Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snapshots #2993

Merged
merged 660 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
660 commits
Select commit Hold shift + click to select a range
de77e9b
[tests] Adapt LXD mount tests to instance_dir
ricab Jun 27, 2023
574b4c8
[image vault] rename parameter
sharder996 Aug 31, 2023
e169089
[vm factory] move common code to base class
sharder996 Aug 31, 2023
f49786b
[vm] remove extra constructor
sharder996 Aug 31, 2023
cb83f6a
[vm image vault] only create vm directory when required
sharder996 Aug 31, 2023
2217517
[vm] make instance_dir protected
sharder996 Aug 31, 2023
a30eb62
[vm factory] use mp::Path for clarity on return parameter usage
sharder996 Aug 31, 2023
0041084
[vm factory] make constructor explicit
sharder996 Aug 31, 2023
c40f50d
[vm factory] use virtual{,-impl} architecture to remove duplicate fun…
sharder996 Sep 13, 2023
073f39e
[qemu] Fix circular dependency in initialization
ricab Sep 14, 2023
d92eaad
[qemu] Remove unnecessary `explicit`
ricab Sep 14, 2023
3e60a3a
[qemu] Make QemuPlatform::get_directory_name const
ricab Sep 14, 2023
3157510
[tests] update tests to properly reference an instance's directory an…
sharder996 Sep 14, 2023
832099e
[vm factory] make instance variable private
sharder996 Sep 14, 2023
ae42fcd
[lxd vm image vault] label unused parameter
sharder996 Sep 14, 2023
fc4cc50
linting changes
sharder996 Sep 14, 2023
f50673f
[vms] Remove artificial constructors for tests
ricab Sep 18, 2023
f14bf7b
[tests] Use a temporary dir in remaining stub VMs
ricab Sep 18, 2023
55bfab1
rename param to be more descriptive
sharder996 Sep 19, 2023
18c4069
[lxd] edit log string to be more descriptive
sharder996 Sep 19, 2023
b50e5ed
remove unnecessary comment
sharder996 Sep 19, 2023
6a2fa2f
[vm factory] rename function
sharder996 Sep 19, 2023
63e606a
[vm factory] extract instance directory derivation into util function
sharder996 Sep 20, 2023
3ca785b
[vm image vault] correct instance directory creation location
sharder996 Sep 20, 2023
2e3d9de
[utils] avoid hardcoded directory separators
sharder996 Sep 20, 2023
d65652a
[cli] add snapshots option to list command
sharder996 Aug 9, 2023
252c68a
[rpc] add option of list of instances or list of snapshots in list reply
sharder996 Aug 9, 2023
cc9840b
[table formatter] print out snapshot list
sharder996 Aug 9, 2023
b286685
[daemon] populate snapshot list item
sharder996 Aug 10, 2023
c4cad4a
[tests] add list snapshots tests for table formatter
sharder996 Aug 10, 2023
6326404
[csv] add snapshot list output to csv formatter
sharder996 Aug 21, 2023
ae3dde3
[yaml] add snapshot list output to yaml formatter
sharder996 Aug 21, 2023
02a9f05
[json] add snapshot list output to json formatter
sharder996 Aug 21, 2023
a1fab16
tear out `snapshot-overview` internals
sharder996 Aug 22, 2023
bfd7464
[proto] rename message fields
sharder996 Sep 26, 2023
87ea3cd
[formatters] add const references to avoid copying
sharder996 Sep 26, 2023
55280c0
[cli] add logic to reject ipv4 and snapshots options together
sharder996 Sep 26, 2023
36045b7
[format utils] remove duplicate code
sharder996 Sep 27, 2023
e6696cc
Merge pull request #3230 from canonical/resize-with-snapshots
sharder996 Sep 22, 2023
0a7ea5b
Merge pull request #3130 from canonical/resolve-instance-dir
ricab Sep 22, 2023
f1ab5b2
[format] Adapt to latest clang-format config
ricab Oct 16, 2023
c856058
Merge pull request #3203 from canonical/move-snapshot-overview-to-list
ricab Sep 29, 2023
6449a56
[cli] hide --all option and allow empty args
sharder996 Sep 29, 2023
ac9ec26
[bash] remove --all from bash completions
sharder996 Sep 29, 2023
0bc84b6
[tests] align tests with deprecated flag
sharder996 Sep 29, 2023
f0d462f
[cli] Signal deprecation of `info --all`
ricab Oct 17, 2023
4e694a7
[cli] Update messages in launch for consistency
ricab Oct 17, 2023
6fa606b
[daemon] Register (null) handler for snapshot mod
ricab Sep 12, 2023
b1ec315
[tests] Fix tests to suit message updates
ricab Oct 17, 2023
5aa192a
[settings] Add bare-bones SnapshotSettingsHandler
ricab Sep 12, 2023
b45d48f
[daemon] Register SnapshotSettingsHandler
ricab Sep 12, 2023
8117455
[settings] Rename field for consistency
ricab Sep 12, 2023
bc70cf7
[settings] Implement snapshot settings keys
ricab Sep 12, 2023
3d44f15
[settings] Use shorthand for multipass namespace
ricab Sep 12, 2023
6caef76
[settings] Avoid repeated `QString::arg` call
ricab Sep 12, 2023
4ddee4a
[settings] Implement SnapshotSettingsHandler::get
ricab Sep 12, 2023
a62b6d9
[settings] Add a SnapshotSettingsException
ricab Sep 12, 2023
f9a266a
[settings] Implement snapshot finding
ricab Sep 12, 2023
6478339
[settings] Forbid snapshot settings on preparing
ricab Sep 12, 2023
0faddbc
[settings] Throw when a snapshot isn't found
ricab Sep 12, 2023
2259e61
[settings] A couple of cosmetic fixes
ricab Sep 12, 2023
a061b99
[settings] Fix return types for helpers
ricab Sep 12, 2023
2804f99
[settings] Implement instance finding
ricab Sep 12, 2023
e933ca9
[settings] Implement snapshot-settings key parsing
ricab Sep 13, 2023
67a5564
[settings] Implement setting snapshot properties
ricab Sep 29, 2023
1b5963a
[settings] Factor out string conversions
ricab Sep 29, 2023
9d84aea
[settings] Forbid bad snapshot names
ricab Sep 29, 2023
eda5582
[settings] Homogenize akin method names
ricab Sep 29, 2023
a1a564a
[settings] Implement finding VMs for modification
ricab Sep 29, 2023
4ef8261
[vm] Implement snapshot renaming
ricab Sep 29, 2023
72661d1
[settings] Shortcut naming snapshot with same name
ricab Sep 29, 2023
a320d49
[vm] Implement "best-effort transactional" rename
ricab Sep 29, 2023
12cf1be
[settings] Simplify helper return
ricab Oct 2, 2023
4d0b236
[settings] Implement finding a snapshot for mod
ricab Oct 2, 2023
7c3338e
[vm] Improve renaming rollback
ricab Oct 2, 2023
56d935e
[vm] Extract reinsert guard from snapshot renaming
ricab Oct 2, 2023
80dad4c
[snapshot] Require VM param to construct snapshots
ricab Oct 3, 2023
b77966b
[vm] Add snapshot-count getter
ricab Oct 3, 2023
5046a7c
[snapshot] Add an index field to snapshots
ricab Oct 3, 2023
2e1746b
[vm] Add instance directory accessor
ricab Oct 3, 2023
7c5fb52
[snapshot] Add a directory field to snapshots
ricab Oct 3, 2023
383af1e
[snapshot] Add assert for constructor precondition
ricab Oct 3, 2023
d00687d
[snapshot] Add a persist method
ricab Oct 3, 2023
a46df75
[snapshot] Implement `Snapshot::persist`
ricab Oct 3, 2023
ff94fb6
[snapshot] Tag new fields as const
ricab Oct 3, 2023
bb21668
[snapshot] Fix param name
ricab Oct 3, 2023
d985ea8
[snapshot] Reorder fields and ctor params
ricab Oct 3, 2023
72512f0
[snapshot] Adapt JSON format to updated fields
ricab Oct 3, 2023
777dc6e
[utils] Use QSaveFile to write json
ricab Oct 4, 2023
5816c50
[utils] Actually handle errors when writing JSON
ricab Oct 4, 2023
7189054
[aliases] Rely on transactional json writing
ricab Oct 4, 2023
27629e5
[tests] Remove obsolete alias test
ricab Oct 4, 2023
904a815
[tests] Replace obsolete alias tests with new one
ricab Oct 4, 2023
835c965
[tests] Fix a couple of hanging daemon tests
ricab Oct 4, 2023
e2d866f
[utils] Move json utils to mockable singleton
ricab Oct 4, 2023
81383e7
[tests] Add a MockJsonUtils
ricab Oct 4, 2023
ef8a74f
[tests] Mock JsonUtils in ImageVault tests
ricab Oct 4, 2023
4e6ba33
[utils] Create parent dirs to write json
ricab Oct 5, 2023
47ed2bd
[tests] Fix two remaining ImageVault test problems
ricab Oct 5, 2023
0cf0f03
[tests] Fix new issue in a couple of daemon tests
ricab Oct 5, 2023
8f710c6
[tests] Fix repeated include guard ids
ricab Oct 9, 2023
586024b
[utils/tests] Fix small include and doc issues.
ricab Oct 9, 2023
0435abe
[tests] Fix last failing test after `write_json`
ricab Oct 9, 2023
7ccf273
[snapshot] Remove outdated TODO
ricab Oct 9, 2023
a53120a
[vm] Adapt rollbacks to self-persisting snapshots
ricab Oct 10, 2023
571de62
[vm] Refactor common file rolling back
ricab Oct 10, 2023
29805f6
[vm] Improve comment
ricab Oct 10, 2023
006c71c
[snapshot] Persist snapshot deletion in snapshots
ricab Oct 10, 2023
42447e0
[snapshot] Refactor derivation of filename
ricab Oct 10, 2023
6ee24cc
[snapshot] Use FileOps to rename files
ricab Oct 10, 2023
08f555f
[snapshot] Persist snapshot when modifying parent
ricab Oct 10, 2023
1d346dd
[vm] Prune obsolete code
ricab Oct 10, 2023
e47108e
[snapshot] Persist renaming in snapshots
ricab Oct 10, 2023
c44e6da
[snapshot] Change format of ID to use in backend
ricab Oct 10, 2023
8abe01a
[snapshot] Add index and parent-index getters
ricab Oct 10, 2023
3565587
[snapshot] Delete obsolete TODO
ricab Oct 10, 2023
f442778
[vm] Move inline method implementation
ricab Oct 10, 2023
2445d60
[vm] Allow fetching snapshots by index
ricab Oct 10, 2023
fa6abb5
[snapshot] Persist and load parents by index
ricab Oct 10, 2023
337bd41
[vm] Tag loaded JSON as const
ricab Oct 11, 2023
83880b4
[vm] Save head snapshot index rather than name
ricab Oct 11, 2023
fcb2ed6
[vm] Allow boundary space in snapshot files
ricab Oct 11, 2023
79503cf
[vm] Add a newline at the end of snapshot files
ricab Oct 11, 2023
fc7a8d4
[snapshot] Reduce visibility of `serialize` method
ricab Oct 11, 2023
ea29a86
[snapshot] Construct snapshots from filename
ricab Oct 13, 2023
6173a21
[snapshot] Remove snapshot name from file name
ricab Oct 11, 2023
13689d3
[snapshot] Remove obsolete renamed-file rollback
ricab Oct 11, 2023
3ebc7f6
[snapshot] Re-inline simplified `set_name` method
ricab Oct 11, 2023
52e80fb
[snapshot] Persist the snapshot when capturing
ricab Oct 11, 2023
b6c031e
[snapshot] Remove persist method from interface
ricab Oct 11, 2023
7631711
[snapshot] Persist a snapshot when setting comment
ricab Oct 11, 2023
22fc602
[snapshot] Slight reorder of snapshot fields
ricab Oct 11, 2023
bc0be83
[snapshot] Remove obsolete TODOs
ricab Oct 11, 2023
d495273
[snapshot] Require a single capture per snapshot
ricab Oct 12, 2023
02beae7
[snapshot] Add further preconditions
ricab Oct 12, 2023
58b4caa
[snapshot] Move check for max index into Snapshot
ricab Oct 12, 2023
4edc8fe
[snapshot] Fix max index with four digits
ricab Oct 12, 2023
dc7dec2
[snapshot] Receive const VM in one of constructors
ricab Oct 13, 2023
07b821c
[snapshot] Fix success on invalid snapshot
ricab Oct 13, 2023
6943415
[lint] Fix various lint issues
ricab Oct 13, 2023
93538bb
[format] Adapt to latest clang-format config
ricab Oct 16, 2023
ed2cee1
[snapshot] Fix rollbacks
ricab Oct 18, 2023
736bac1
[vm] Normalize snapshot param name across VMs
ricab Oct 19, 2023
7cd1027
[tests] Comment out unused param names in stub
ricab Oct 19, 2023
081a1c6
[tests] Fix state setting in stub vm constructor
ricab Oct 19, 2023
f32a115
[vm] Add a TODO to remove rename_snapshot from VM
ricab Oct 19, 2023
b6f8229
[snapshot] Fix specific version in fmt calls
ricab Oct 19, 2023
3d2292e
[vm] Improve parameter naming
ricab Oct 19, 2023
a935fc5
[cli] Add a `--snapshots` flag to `info`
ricab Oct 17, 2023
031f1d8
[cli] Use consistent form in `info` options
ricab Oct 17, 2023
5368010
[rpc] Add and set a snapshots flag in InfoRequest
ricab Oct 17, 2023
ab6b659
[daemon] Fill details on `info --snapshots`
ricab Oct 17, 2023
183ad61
[daemon] Streamline populating info response
ricab Oct 17, 2023
d09c916
[daemon] Fix repeated snapshot info
ricab Oct 19, 2023
caeec0a
[bash] Add `info --snapshots` to bash completion
ricab Oct 17, 2023
be06d01
[daemon] Extract processing of snapshot info
ricab Oct 19, 2023
6863937
[daemon] Replace lambda param with capture
ricab Oct 19, 2023
effe4e1
[rpc] Add `snapshots` flag to `InfoReply`
ricab Oct 18, 2023
c0ad644
[daemon] Get rid of superfluous structured binding
ricab Oct 19, 2023
f0d8cbf
[daemon] Set `InfoReply::snapshots`
ricab Oct 18, 2023
8dbc0ca
[cli] Adapt output of `info` when nothing found
ricab Oct 18, 2023
2205dbb
[tests] Adapt test for empty info output
ricab Oct 18, 2023
41f2289
Merge pull request #3241 from canonical/deprecate-info-all
ricab Oct 17, 2023
34e96d5
[tests] Test no-snapshots info reply.
ricab Oct 18, 2023
685570d
[qemu] Tolerate missing snapshot on `delete`
ricab Oct 18, 2023
bccb34b
[daemon] Fix interpreting of empty snapshot args
ricab Oct 19, 2023
f12e6ea
[bash] add snapshot and restore bash completions
sharder996 May 26, 2023
bfd4a4c
[qemu] Log missing QEMU snapshots on delete
ricab Oct 18, 2023
ef6e353
[bash] two part bash completion with restorable instances and then th…
sharder996 Jul 6, 2023
60667cd
[bash] remove auto-period at end of instances
sharder996 Sep 29, 2023
a1af37a
[bash] flatten and expand item lists
sharder996 Oct 4, 2023
885c126
[bash] format fetched snapshots as <instance>.<snapshot>
sharder996 Oct 4, 2023
2e31ad2
[bash] add snapshot flags as nonrepeating args
sharder996 Oct 16, 2023
159be73
[bash] fix typo
sharder996 Oct 17, 2023
04e5857
[bash] adapt command for multipass list
sharder996 Oct 17, 2023
1198a3b
[bash] return all restorable snapshots on multipass restore tab compl…
sharder996 Oct 17, 2023
fd6782a
[bash] reorder piping
sharder996 Oct 18, 2023
b6802c7
[bash] remove deprecated `--all` from info call
sharder996 Oct 20, 2023
d5c30de
Merge pull request #3224 from canonical/snapshot-settings
sharder996 Oct 19, 2023
f0b5a58
[bash] suggest all snapshots and instances for info and delete
sharder996 Oct 20, 2023
b6c8b9a
Merge pull request #3259 from canonical/info--snapshots
sharder996 Oct 19, 2023
4349257
Merge pull request #3260 from canonical/no-instances-snapshots-info-f…
sharder996 Oct 19, 2023
0ddfa65
Merge pull request #3263 from canonical/fix-empty-snapshot-args
sharder996 Oct 20, 2023
2e2cc36
Merge pull request #3261 from canonical/qemu-delete-missing-snapshot
sharder996 Oct 20, 2023
339e8d2
[clang] edit formatting
sharder996 Oct 23, 2023
5a919df
Merge pull request #3100 from canonical/snapshot-restore-bash-completion
ricab Oct 23, 2023
062e4b1
[exception] Adhere to conventional naming suffix
ricab Oct 24, 2023
b6d10dc
[exception] Use uniform snapshot exception msgs
ricab Oct 24, 2023
bc97e4b
Merge pull request #3269 from canonical/clang-format-changes
ricab Oct 24, 2023
e214080
[exception] Use same parameter names
ricab Oct 24, 2023
ae8799d
[cli] Use consistent alias namespace declaration
ricab Oct 24, 2023
47fb4e5
[cli] Add a period at the end of exception message
ricab Oct 24, 2023
314d483
[cli] Refactor repeated yes/no regexes
ricab Oct 24, 2023
5019ce1
[cli] Rename yes/no answer vars
ricab Oct 24, 2023
0a1c8a4
[various] Fix namespace usage inconsistencies
ricab Oct 24, 2023
7af570b
[vm] Remove unnecessary inner scope
ricab Oct 24, 2023
5a0f3c7
[vm] Remove separate variable declaration
ricab Oct 24, 2023
d79aa30
[cli] Fix missing newlines in `delete` description
ricab Oct 24, 2023
2baeea5
[cli] Add tip about quoting snapshot comments
ricab Oct 24, 2023
3ec5593
[daemon] Add newline for readability
ricab Oct 24, 2023
054771e
[daemon] Move initialization of info details
ricab Oct 24, 2023
518da73
[daemon] Remove lambda to populate generic info
ricab Oct 24, 2023
d598f04
[daemon] Use explicit lambda-captures
ricab Oct 24, 2023
cf960c1
[daemon] Remove unneeded scope to take snapshot
ricab Oct 24, 2023
17847be
Merge branch 'snapshots-review-fixes' into snapshots
ricab Oct 24, 2023
a54f2bd
[rpc] Change the name of instance-snapshot pairs
ricab Oct 24, 2023
5db7f44
[todos] Remove or update outdated snapshots TODOs
ricab Oct 20, 2023
d437cee
[tests] Refactor repeated mocking for daemon RPC
ricab Oct 24, 2023
7a03f1d
[snapshot] Mark a couple of accessors as noexcept
ricab Oct 20, 2023
3bb53f1
[vm] Remove noexcept from `view_snapshots`
ricab Oct 20, 2023
f005906
[settings] Add noexcept to handler's constructor
ricab Oct 20, 2023
8d9b599
[mounts] Add noexcept to new MountHandler accessor
ricab Oct 20, 2023
50194c6
[vmspecs] Move header to generic include folder
ricab Oct 20, 2023
476a127
[snapshot] Throw on unsupported state
ricab Oct 20, 2023
b96bcd9
[snapshot] Throw on non-positive snapshot index
ricab Oct 20, 2023
3f94d6f
[snapshot] Fix index overflow exception contents
ricab Oct 20, 2023
781bf47
[vm] Replace TODO with justification
ricab Oct 20, 2023
2cd456f
[mount] Add a couple of constructors to VMMount
ricab Oct 20, 2023
594d708
[mount] Move ctor implementation to cpp
ricab Oct 20, 2023
cdde27e
[mount] Construct mounts from json
ricab Oct 20, 2023
8152618
[daemon] Use new VMMount constructor from JSON
ricab Oct 20, 2023
b36a26e
[snapshot] Use new VMMount constructor from JSON
ricab Oct 20, 2023
0a288ec
[mount] Serialize mounts to JSON
ricab Oct 20, 2023
172e189
[daemon] Use new VMMount serialize method
ricab Oct 20, 2023
4ea69ff
[snapshot] Use new VMMount serialize method
ricab Oct 20, 2023
001d626
[snapshot] Remove incorrect TODO
ricab Oct 20, 2023
41a1590
[cosmetic] Fix extra newline
ricab Oct 25, 2023
60435c9
[cli] DRY in description of `info` command
ricab Sep 21, 2023
b679c8f
Merge pull request #3265 from canonical/snapshots-todos
sharder996 Oct 25, 2023
b6e0732
[cli] Rename positional argument to `info` command
ricab Sep 21, 2023
65965f2
[utils] Fix include form
ricab Oct 20, 2023
b9488a1
[snapshots] Fix attempts to move from const
ricab Oct 23, 2023
4eeac93
[cli] Use "hint" instead of "tip" in help text
ricab Oct 25, 2023
39a4e43
[qemu] Use uniform initialization in QemuSnapshot
ricab Oct 23, 2023
a13934a
[cosmetic] Use conventional alias-namespace prefix
ricab Oct 26, 2023
8b5ba52
[cli] Add using declaration to improve formatting
ricab Oct 26, 2023
0a27d0a
[cli] Fix double space in snapshot spinner msg
ricab Oct 26, 2023
cae393c
[tests] Fix missing include
ricab Oct 26, 2023
275ed82
Merge branch 'snapshots-small-improvements' into snapshots
ricab Oct 26, 2023
acf850a
[snapshot] Avoid deriving the ID string each time
ricab Oct 27, 2023
1bdc9c1
[exceptions] Rename file to match type
ricab Oct 27, 2023
a917147
[vm] Move default implementation to base VM
ricab Oct 27, 2023
e24e524
[utils] Implement remaining string trimmers
ricab Oct 27, 2023
a0f1612
[vm] Use generic trim util on file contents
ricab Oct 27, 2023
bc29248
[utils] Generalize trimmers
ricab Oct 27, 2023
5eb6460
[utils] Avoid repeating isspace lambda
ricab Oct 27, 2023
d40e8e6
[utils] Separate template declaration/definition
ricab Oct 27, 2023
bc394d8
[utils] Bind `std::isspace` safely
ricab Oct 30, 2023
6baa7a4
[utils] Fix ignored custom filter in trim
ricab Oct 30, 2023
2f856e5
[utils] Fix formatting
ricab Oct 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 3rd-party/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function(generate_grpc_cpp SRCS DEST)
"${DEST}/${FIL_WE}.pb.cc"
"${DEST}/${FIL_WE}.pb.h"
COMMAND $<TARGET_FILE:protoc>
ARGS --grpc_out=${DEST} --cpp_out=${DEST} --proto_path=${FIL_DIR} --plugin=protoc-gen-grpc=$<TARGET_FILE:grpc_cpp_plugin> ${ABS_FIL}
ARGS --grpc_out=${DEST} --cpp_out=${DEST} --proto_path=${FIL_DIR} --proto_path=${grpc_SOURCE_DIR}/third_party/protobuf/src --plugin=protoc-gen-grpc=$<TARGET_FILE:grpc_cpp_plugin> ${ABS_FIL}
DEPENDS ${ABS_FIL} protoc grpc_cpp_plugin
COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}"
VERBATIM)
Expand Down
59 changes: 53 additions & 6 deletions completions/bash/multipass
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,43 @@ _multipass_complete()
{
local state=$1

local cmd="multipass list --format=csv --no-ipv4"
[ -n "$state" ] && cmd="$cmd | \tail -n +2 | \awk -F',' '\$2 == \"$state\"'"
local cmd="multipass list --format=csv --no-ipv4 | \tail -n +2"
[ -n "$state" ] && cmd="$cmd | \awk -F',' '\$2 == \"$state\"'"

local instances=$( \eval $cmd | \cut -d',' -f 1 | \tr '\r\n' ' ')

_add_nonrepeating_args "$instances"
}

_multipass_snapshots()
{
local instance=$1
local cmd="multipass list --snapshots --format=csv 2>/dev/null | \tail -n +2"
[ -n "$instance" ] && cmd="$cmd | \awk -F',' '\$1 == \"$instance\"'"
local snapshots=$( \eval $cmd | \cut -d',' -f 1,2 | \tr ',' '.' | \tr '\r\n' ' ' )

_add_nonrepeating_args "$snapshots"
}

_multipass_instances_and_snapshots()
{
_multipass_snapshots
_multipass_instances
}

_multipass_restorable_snapshots()
{
local instances=$( multipass info --no-runtime-information --format=csv \
| \tail -n +2 \
| \awk -F',|\r?\n' '$2 == "Stopped" && $16 > 0' \
| \cut -d',' -f 1 \
| \tr '\r\n' ' ')

for instance in ${instances}; do
_multipass_snapshots "${instance}"
done
}

# Set $opts to the list of available networks.
_multipass_networks()
{
Expand Down Expand Up @@ -186,7 +215,7 @@ _multipass_complete()
cmd="${COMP_WORDS[1]}"
prev_opts=false
multipass_cmds="authenticate transfer delete exec find help info launch list mount networks \
purge recover shell start stop suspend restart umount version get set \
purge recover restart restore shell snapshot start stop suspend umount version get set \
alias aliases unalias"

if [[ "${multipass_cmds}" =~ " ${cmd} " || "${multipass_cmds}" =~ ^${cmd} || "${multipass_cmds}" =~ \ ${cmd}$ ]];
Expand All @@ -200,9 +229,12 @@ _multipass_complete()
opts="${opts} --working-directory --no-map-working-directory"
;;
"info")
_add_nonrepeating_args "--all --format"
_add_nonrepeating_args "--format --snapshots"
;;
"list"|"ls"|"networks"|"aliases")
"list"|"ls")
_add_nonrepeating_args "--format --snapshots"
;;
"networks"|"aliases")
_add_nonrepeating_args "--format"
;;
"delete")
Expand Down Expand Up @@ -231,6 +263,12 @@ _multipass_complete()
"transfer"|"copy-files")
_add_nonrepeating_args "--parents --recursive"
;;
"snapshot")
_add_nonrepeating_args "--name --comment"
;;
"restore")
_add_nonrepeating_args "--destructive"
;;
esac

if [[ ${prev} == -* ]]; then
Expand Down Expand Up @@ -302,12 +340,21 @@ _multipass_complete()
_multipass_instances "Stopped"
_multipass_instances "Suspended"
;;
"delete"|"info"|"umount"|"unmount")
"umount"|"unmount")
_multipass_instances
;;
"delete"|"info")
_multipass_instances_and_snapshots
;;
"recover")
_multipass_instances "Deleted"
;;
"snapshot")
_multipass_instances "Stopped"
;;
"restore")
_multipass_restorable_snapshots
;;
"mount")
local source_set=0
local prev
Expand Down
70 changes: 52 additions & 18 deletions include/multipass/cli/format_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <multipass/settings/settings.h>

#include <fmt/format.h>
#include <google/protobuf/util/time_util.h>

#include <algorithm>
#include <string>
Expand All @@ -33,44 +34,77 @@ class Formatter;

namespace format
{
static constexpr int col_buffer = 3;

std::string status_string_for(const InstanceStatus& status);
std::string image_string_for(const multipass::FindReply_AliasInfo& alias);
Formatter* formatter_for(const std::string& format);

template <typename Instances>
Instances sorted(const Instances& instances);
template <typename Container>
Container sorted(const Container& items);

void filter_aliases(google::protobuf::RepeatedPtrField<multipass::FindReply_AliasInfo>& aliases);

// Computes the column width needed to display all the elements of a range [begin, end). get_width is a function
// which takes as input the element in the range and returns its width in columns.
static constexpr auto column_width = [](const auto begin, const auto end, const auto get_width, int minimum_width,
int space = 2) {
if (0 == std::distance(begin, end))
return minimum_width;

auto max_width =
std::max_element(begin, end, [&get_width](auto& lhs, auto& rhs) { return get_width(lhs) < get_width(rhs); });
return std::max(get_width(*max_width) + space, minimum_width);
};
static constexpr auto column_width =
[](const auto begin, const auto end, const auto get_width, int header_width, int minimum_width = 0) {
if (0 == std::distance(begin, end))
return std::max({header_width + col_buffer, minimum_width});

auto max_width = std::max_element(begin, end, [&get_width](auto& lhs, auto& rhs) {
return get_width(lhs) < get_width(rhs);
});
return std::max({get_width(*max_width) + col_buffer, header_width + col_buffer, minimum_width});
};
} // namespace format
} // namespace multipass

template <typename Instances>
Instances multipass::format::sorted(const Instances& instances)
template <typename Container>
Container multipass::format::sorted(const Container& items)
{
if (instances.empty())
return instances;
if (items.empty())
return items;

auto ret = instances;
auto ret = items;
const auto petenv_name = MP_SETTINGS.get(petenv_key).toStdString();
std::sort(std::begin(ret), std::end(ret), [&petenv_name](const auto& a, const auto& b) {
if (a.name() == petenv_name)
using T = std::decay_t<decltype(a)>;
using google::protobuf::util::TimeUtil;
townsend2010 marked this conversation as resolved.
Show resolved Hide resolved

// Put instances first when sorting info reply
if constexpr (std::is_same_v<T, multipass::DetailedInfoItem>)
{
if (a.has_instance_info() && b.has_snapshot_info())
return true;
else if (a.has_snapshot_info() && b.has_instance_info())
return false;
}

// Put petenv related entries first
if (a.name() == petenv_name && b.name() != petenv_name)
return true;
else if (b.name() == petenv_name)
else if (b.name() == petenv_name && a.name() != petenv_name)
return false;
else
{
// Sort by timestamp when names are the same for snapshots
if constexpr (std::is_same_v<T, multipass::DetailedInfoItem>)
{
if (a.has_snapshot_info() && a.name() == b.name())
return TimeUtil::TimestampToNanoseconds(a.snapshot_info().fundamentals().creation_timestamp()) <
TimeUtil::TimestampToNanoseconds(b.snapshot_info().fundamentals().creation_timestamp());
townsend2010 marked this conversation as resolved.
Show resolved Hide resolved
}
else if constexpr (std::is_same_v<T, multipass::ListVMSnapshot>)
{
if (a.name() == b.name())
return TimeUtil::TimestampToNanoseconds(a.fundamentals().creation_timestamp()) <
TimeUtil::TimestampToNanoseconds(b.fundamentals().creation_timestamp());
townsend2010 marked this conversation as resolved.
Show resolved Hide resolved
}

// Lastly, sort by name
return a.name() < b.name();
}
});

return ret;
Expand Down
37 changes: 37 additions & 0 deletions include/multipass/exceptions/file_open_failed_exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) Canonical, Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#ifndef MULTIPASS_FILE_OPEN_FAILED_EXCEPTION_H
#define MULTIPASS_FILE_OPEN_FAILED_EXCEPTION_H

#include <cerrno>
#include <cstring>
#include <stdexcept>

namespace multipass
{
class FileOpenFailedException : public std::runtime_error
{
public:
explicit FileOpenFailedException(const std::string& name)
: std::runtime_error(fmt::format("failed to open file '{}': {}({})", name, strerror(errno), errno))
{
}
};
} // namespace multipass

#endif // MULTIPASS_FILE_OPEN_FAILED_EXCEPTION_H
47 changes: 47 additions & 0 deletions include/multipass/exceptions/snapshot_exceptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) Canonical, Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

#ifndef MULTIPASS_SNAPSHOT_EXCEPTIONS_H
#define MULTIPASS_SNAPSHOT_EXCEPTIONS_H

#include <stdexcept>
#include <string>

#include <multipass/format.h>

namespace multipass
{
class SnapshotNameTakenException : public std::runtime_error
{
public:
SnapshotNameTakenException(const std::string& vm_name, const std::string& snapshot_name)
: std::runtime_error{fmt::format("Snapshot already exists: {}.{}", vm_name, snapshot_name)}

Check warning on line 32 in include/multipass/exceptions/snapshot_exceptions.h

View check run for this annotation

Codecov / codecov/patch

include/multipass/exceptions/snapshot_exceptions.h#L31-L32

Added lines #L31 - L32 were not covered by tests
{
}
};

class NoSuchSnapshotException : public std::runtime_error
{
public:
NoSuchSnapshotException(const std::string& vm_name, const std::string& snapshot_name)
: std::runtime_error{fmt::format("No such snapshot: {}.{}", vm_name, snapshot_name)}

Check warning on line 41 in include/multipass/exceptions/snapshot_exceptions.h

View check run for this annotation

Codecov / codecov/patch

include/multipass/exceptions/snapshot_exceptions.h#L40-L41

Added lines #L40 - L41 were not covered by tests
{
}
};
} // namespace multipass

#endif // MULTIPASS_SNAPSHOT_EXCEPTIONS_H
5 changes: 5 additions & 0 deletions include/multipass/file_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <QByteArray>
#include <QDir>
#include <QFileDevice>
#include <QFileInfoList>
#include <QSaveFile>
#include <QString>
#include <QTextStream>
Expand All @@ -45,6 +46,10 @@ class FileOps : public Singleton<FileOps>
// QDir operations
virtual bool exists(const QDir& dir) const;
virtual bool isReadable(const QDir& dir) const;
virtual QFileInfoList entryInfoList(const QDir& dir,
const QStringList& nameFilters,
QDir::Filters filters = QDir::NoFilter,
QDir::SortFlags sort = QDir::NoSort) const;
virtual bool mkpath(const QDir& dir, const QString& dirName) const;
virtual bool rmdir(QDir& dir, const QString& dirName) const;

Expand Down
20 changes: 14 additions & 6 deletions include/multipass/json_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,29 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Alberto Aguirre <[email protected]>
*
*/

#ifndef MULTIPASS_JSON_UTILS_H
#define MULTIPASS_JSON_UTILS_H

#include <string>
#include "singleton.h"

#include <QJsonObject>
#include <QString>

#include <string>

#define MP_JSONUTILS multipass::JsonUtils::instance()

namespace multipass
{
void write_json(const QJsonObject& root, QString file_name);
std::string json_to_string(const QJsonObject& root);
}
class JsonUtils : public Singleton<JsonUtils>
{
public:
explicit JsonUtils(const Singleton<JsonUtils>::PrivatePass&) noexcept;

virtual void write_json(const QJsonObject& root, QString file_name) const; // transactional; creates parent dirs
virtual std::string json_to_string(const QJsonObject& root) const;
};
} // namespace multipass
#endif // MULTIPASS_JSON_UTILS_H
2 changes: 1 addition & 1 deletion include/multipass/memory_size.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MemorySize
friend bool operator<=(const MemorySize& a, const MemorySize& b);
friend bool operator>=(const MemorySize& a, const MemorySize& b);

MemorySize();
MemorySize() noexcept;
townsend2010 marked this conversation as resolved.
Show resolved Hide resolved
explicit MemorySize(const std::string& val);
long long in_bytes() const noexcept;
long long in_kilobytes() const noexcept;
Expand Down
Loading
Loading