Commit Graph

216 Commits

Author SHA1 Message Date
Matthieu MOREL
8a176255c0 fix(general): enable wsl for all go files (#4524)
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-04-26 13:01:20 -07:00
Matthieu MOREL
b0827d128a fix(ci): remove gocritic unnecessaryDefer exclusion (#4525)
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-04-25 14:47:08 -07:00
Matthieu MOREL
675e958877 chore(ci): bump golangci-lint to v2.1.2 (#4500)
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
2025-04-15 22:49:13 -07:00
Rohit-BM18
9b68189d29 feat(cli): compute snapshot diff stats (#4444)
Added functionality to calculate aggregate statistics when
comparing what's changed between snapshots using kopia diff

Statistics collected during snapshot diff computation includes:

- files added/removed/modified
- dirs added/removed/modified
- files/dirs with metadata changes but same underlying content (OID)

Testing approach:

Added a test for verifying stats collected when comparing two directories with the same objectID but metadata changes across snapshots (dir mode, dir mod time, dir owner, etc), expectation is all the appropriate dir stats fields are updated.
Added another test for verifying stats collected when comparing two directories with similar file contents but the metadata for the files have changed between snapshots but content remains unchanged. Expectation is all the relevant file level stats fields are updated.
Existing tests have been updated due to stats now being printed in addition to previous output.
2025-03-07 12:41:14 +00:00
Julio López
2a22281271 fix(server): ensure server uploads "repodiag" blobs (#4358)
The kopia server was not uploading any logs to the repository,
because "repodiag" blob uploads would always fail.

The cause was the following: when the (log) repodiag blob
PUT operation was initiated, the `Context` used for this
operation was already canceled.

The context used for blob uploads is passed to
`repodiag.NewLogManager` when opening the repository.
In the case of the kopia server, the repository is asynchronously
opened in `server.Server.InitReposotoryAsync`. The context
passed to `repo.Open` is canceled after the "open repository"
server task completes.

This issue was introduced in #1691

Change:
Use `context.WithoutCancel()` instead of the context passed
when the repo diagnoser is created.

New tests are included to reproduce this failure and verify
the fix.
- test: ensure server logs are uploaded to the repo
- test: honor cancellation in map storage
- test: repodiag context cancellation

Ref:
- #1691
2025-01-22 20:13:39 -08:00
Jarek Kowalski
b60cac4860 fix(cli): fixed v0.18.0 failures using v0.17.0-generated config (#4255)
This was caused by the client using key derivation algorithm
from a config file (which did not have it when it was generated
using old version of Kopia).

Fixes #4254
2024-11-17 10:15:00 -08:00
Jarek Kowalski
eb1cf64c27 chore(ci): upgraded linter to 1.62.0 (#4250) 2024-11-16 07:16:50 -08:00
Julio López
eb2ea5dddd test(server): speedup cert key generation in server tests (#4166)
Use shorter key size to speed up cert generation in TestServerStartInsecure.

Refactor: add const for default server-control username.
2024-10-10 10:22:34 -07:00
Julio López
5dbc8a478a refactor(general): minor cleanups (#4003)
Followups to #3655

* wrap fs.Reader
* nit: remove unnecessary intermediate variable
* nit: rename local variable
* cleanup: move restore.Progress interface to cli pkg
* move cliRestoreProgress to a separate file
* refactor(general): replace switch with if/else for clarity
  Removes a tautology for `err == nil`, which was guaranteed
  to be true in the second case statement for the switch.
  Replacing the switch statement with and if/else block is clearer.
* initialize restoreProgress in restore command
* fix: use error.Wrapf with format string and args


Simplify SetCounters signature:

Pass arguments in a `restore.Stats` struct.
  `SetCounters(s restore.Stats)`
Simplifies call sites and implementation.
In this case it makes sense to pass all the values
using the restore.Stats struct as it simplifies
the calls.
However, this pattern should be avoided in general
as it essentially makes all the arguments "optional".
This makes it easy to miss setting a value and simply
passing 0 (the default value), thus it becomes error
prone.
In this particular case, the struct is being passed
through verbatim, thus eliminating the risk of
missing a value, at least in the current state of
the code.
2024-08-27 09:42:58 -07:00
Julio López
ae9f1c734b fix(server): ensure repo disconnection on server start exit (#3980)
Ensure repository disconnection at the end of the `server start` CLI command.
This was caught as a result of fixing the test below.

Fix `TestServerStartInsecure`:
Remove `--password=xxx` parameter, which causes a server start failure
due to incorrect repo password, and not for the case being checked,
which is the lack of the `--insecure` parameter.

Update test comments accordingly.
2024-07-11 18:51:12 -07:00
Eugene Sumin
2b92388286 refactor(general): Increase restore progress granularity (#3655)
When restoring huge file(s), the progress reporting is done in a bit
weird way:

```
kopia_test % kopia snapshot restore ka2084d263182164b6cf3456668e6b6da /Users/eugen.sumin/kopia_test/2
Restoring to local filesystem (/Users/eugen.sumin/kopia_test/2) with parallelism=8...
Processed 6 (5.4 GB) of 5 (5.4 GB) 1.6 MB/s (100.0%) remaining 0s.
Processed 6 (5.4 GB) of 5 (5.4 GB) 1.6 MB/s (100.0%) remaining 0s.
Processed 6 (5.4 GB) of 5 (5.4 GB) 1.6 MB/s (100.0%) remaining 0s.
Processed 6 (5.4 GB) of 5 (5.4 GB) 1.5 MB/s (100.0%) remaining 0s.
Processed 6 (5.4 GB) of 5 (5.4 GB) 1.5 MB/s (100.0%) remaining 0s.
Processed 6 (5.4 GB) of 5 (5.4 GB) 1.5 MB/s (100.0%) remaining 0s.
Restored 5 files, 1 directories and 0 symbolic links (5.4 GB).
```
In fact, the amount of restored data is dumped when particular file
completely restored.

This PR contains the least invasive change, which allows us to see
progress update while file is downloaded from object storage.
```
Restoring to local filesystem (/Users/eugen.sumin/kopia_test/55) with parallelism=8...
Processed 2 (3.1 MB) of 5 (1.8 GB).
Processed 4 (459.6 MB) of 5 (1.8 GB) 270.3 MB/s (25.2%) remaining 4s.
Processed 4 (468.7 MB) of 5 (1.8 GB) 269 MB/s (25.7%) remaining 4s.
Processed 4 (741.6 MB) of 5 (1.8 GB) 269 MB/s (40.6%) remaining 3s.
Processed 4 (1.1 GB) of 5 (1.8 GB) 280 MB/s (57.6%) remaining 2s.
Processed 5 (1.4 GB) of 5 (1.8 GB) 291.1 MB/s (75.2%) remaining 1s.
Processed 5 (1.4 GB) of 5 (1.8 GB) 289.8 MB/s (75.6%) remaining 1s.
Processed 5 (1.6 GB) of 5 (1.8 GB) 270.2 MB/s (85.3%) remaining 0s.
Processed 5 (1.7 GB) of 5 (1.8 GB) 256.3 MB/s (95.0%) remaining 0s.
Processed 6 (1.8 GB) of 5 (1.8 GB) 251 MB/s (100.0%) remaining 0s.
Processed 6 (1.8 GB) of 5 (1.8 GB) 251 MB/s (100.0%) remaining 0s.
Restored 5 files, 1 directories and 0 symbolic links (1.8 GB).
```

---------

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>
2024-05-10 09:47:13 -07:00
Julio López
ca1962f6e4 refactor(general): user password hashing and key derivation helpers (#3821)
Code movement and simplification, no functional changes.

Objectives:
- Allow callers specifying the needed key (or hash) size, instead of
hard-coding it in the registered PBK derivers. Conceptually, the caller
needs to specify the key size, since that is a requirement of the
(encryption) algorithm being used in the caller. Now, the code changes
here do not result in any functional changes since the key size is
always 32 bytes.
- Remove a global definition for the default PB key deriver to use.
Instead, each of the 3 use case sets the default value.

Changes:
- `crypto.DeriveKeyFromPassword` now takes a key size.
- Adds new constants for the key sizes at the callers.
- Removes the global `crypto.MasterKeySize` const.
- Removes the global `crypto.DefaultKeyDerivationAlgorithm` const.
- Adds const for the default derivation algorithms for each use case.
- Adds a const for the salt length in the `internal/user` package, to ensure
  the same salt length is used in both hash versions.
- Unexports various functions, variables and constants in the `internal/crypto`
  & `internal/user` packages.
- Renames various constants for consistency.
- Removes unused functions and symbols.
- Renames files to be consistent and better reflect the structure of the code.
- Adds a couple of tests to ensure the const values are in sync and supported.
- Fixes a couple of typos

Followups to:
- #3725
- #3770
- #3779
- #3799
- #3816

The individual commits show the code transformations to simplify the
review of the changes.
2024-04-26 23:30:56 -07:00
Sirish Bathina
1e98511c2e feat(general): key derivation algorithm for cache encryption (#3799)
Add an option to select the password-based key derivation algorithm
for the local cache encryption key when connecting to a kopia
repository server.
2024-04-25 17:45:12 -07:00
Sirish Bathina
c71f57d83c feat(general): allow setting key derivation algorithm for format blob (#3779)
Adds support to set the algorithm to derive the key used to encrypt
the repository format blob.
2024-04-24 14:07:19 -07:00
Jarek Kowalski
211e28c98c chore(repository): BREAKING CHANGE remove support for HTTP-based repository API (#3745)
Remove support for HTTP-based repository API
2024-04-17 16:23:58 -07:00
Jarek Kowalski
b55d5b474c refactor(repository): refactored internal index read API to reduce memory allocations (#3754)
* refactor(repository): refactored internal index read API to reduce memory allocations

* fixed stress test flake, improved debuggability

* fixed spurious checklocks failures

* post-merge fixes

* pr feedback
2024-04-12 22:59:11 -07:00
Jarek Kowalski
09415e0c7d chore(ci): upgraded to go 1.22 (#3746)
Upgrades go to 1.22 and switches to new-style for loops

---------

Co-authored-by: Julio López <1953782+julio-lopez@users.noreply.github.com>
2024-04-08 09:52:47 -07:00
lvyaoting
67f87a5450 chore(general): fix function names in comment (#3786)
Signed-off-by: lvyaoting <lvyaoting@outlook.com>
2024-04-07 21:33:33 -07:00
NickIAm
3da0473219 fix(cli): restore objects with I prefix fails (#3062)
* Fix restoring objects with I prefix
set default of snapshot-time to 'latest' as noted in the help output

* Change test of restore to check it works without a time given
This is because --snapshot-time defaults to "latest" now.
2024-03-26 21:03:46 -07:00
Nick
8c081add53 chore(server): Disable legacy API by default (#3730) 2024-03-13 11:11:09 -07:00
Jarek Kowalski
a8e4d50600 build(deps): upgraded linter to v1.55.2, fixed warnings (#3611)
* build(deps): upgraded linter to v1.55.2, fixed warnings

* removed unsafe hacks with better equivalents

* test fixes
2024-02-02 23:34:34 -08:00
Jarek Kowalski
7ee30b76bb fix(repository): fixed handling of content.Info (#3356)
* fix(repository): fixed handling of content.Info

Previously content.Info was an interface which was implemented by:

* index.InfoStruct
* index.indexEntryInfoV1
* index.indexEntryInfoV2

The last 2 implementations were relying on memory-mapped files
which in rare cases could be closed while Kopia was still processing
them leading to #2599.

This changes fixes the bug and strictly separates content.Info (which
is now always a struct) from the other two (which were renamed as
index.InfoReader and only used inside repo/content/...).

In addition to being safer, this _should_ reduce memory allocations.

* reduce the size of content.Info with proper alignment.

* pr feedback

* renamed index.InfoStruct to index.Info
2023-10-14 10:34:15 -07:00
Jarek Kowalski
af1550ad81 feat(server): reduce server refreshes of the repository (#3265)
* feat(server): reduce server refreshes of the repository

Previously each source would refresh itself from the repository
very frequently to determine the upcoming snapshot time. This change
refactors source manager so it does not own the repository connection
on its own but instead delegates all policy reads through the server.

Also introduces a new server scheduler that is responsible for
centrally managing the snapshot schedule and triggering snapshots
when they are due.

* Update cli/command_server_start.go

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>

* Update internal/server/server.go

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>

* Update internal/server/server_maintenance.go

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>

* pr feedback

---------

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>
2023-09-15 12:08:35 -07:00
Jarek Kowalski
044db7593b feat(repository): apply retention policies server-side (#3249)
* feat(repository): apply retention policies server-side

This allows append-only snapshots where the client can never delete
arbitrary manifests and policies are maintained on the server.

The client only needs permissions to create snapshots in a given, which
automatically gives them permission to invoke the server-side method
for their own snapshots only.

* Update cli/command_acl_add.go

Co-authored-by: Guillaume <Gui13@users.noreply.github.com>

* Update internal/server/api_manifest.go

Co-authored-by: Guillaume <Gui13@users.noreply.github.com>

* Update internal/server/api_manifest.go

Co-authored-by: Guillaume <Gui13@users.noreply.github.com>

* Update internal/server/grpc_session.go

Co-authored-by: Guillaume <Gui13@users.noreply.github.com>

---------

Co-authored-by: Guillaume <Gui13@users.noreply.github.com>
2023-09-02 18:23:21 -07:00
Julio Lopez
1320f0c8e8 chore(general): remove unnecessary //nolint directives (#3256) 2023-08-29 12:40:40 -07:00
NickIAm
a9c5a993c8 fix(cli): prevent duplicate snapshots when --all and a source path are given (#3067)
Adds a check for snapshot create when --all and a source path are
given simultaneously. Returns an error in this case since it would
otherwise create a  duplicate snapshot for the specified source path.

---

Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>
2023-08-03 17:36:10 +00:00
Jarek Kowalski
83b88d8bbf chore(ci): fixes for ARM64 runner on AWS (#3179)
- fixed directory iteration order
- reduced providervalidation memory usage
- disabled one test case of TestSnapshotSparseRestore
  (filed https://github.com/kopia/kopia/issues/3178 to fix)
2023-07-27 11:30:40 -07:00
Julio Lopez
d97679608e fix(cli): preserve error exit code when '--json' output is specified (#3163)
Changes kopia's behavior to match the exit code that would
have been returned when the `--json` flag was not specified.

`kopia snapshot create my/path --json` terminates with a 0
status code in cases where
`kopia snapshot create my/path` terminates with a
 non-zero exit code.

One such case is when there are permissions errors reading
files or directories to snapshot.

Adds end-to-end tests for snapshot create with '--json' flag
2023-07-20 06:39:40 -07:00
Maxim Schuwalow
851fe6c193 feat(cli): add --override-source parameter to allow overriding source when snapshotting (#3041) 2023-07-11 17:34:30 -07:00
Julio Lopez
8f2499b94b breaking(cli): remove deprecated 'snapshot gc' command (#2862)
* remove deprecated `snapshot gc` command
* run `maintenance` instead of `snapshot gc` in robustness
* use `maintenance` command instead of `gc` alias for clarity
* use `maintenance run` in `TestSnapshotDeleteRestore`
2023-04-10 23:17:32 -04:00
Aaron Alpar
c65613ccba feat(cli): ability to read repository status ... (#2799)
* fix spelling

* permissive index read

* fixup v1 permissive index

* fixups for lint

* trigger rebuild

* Update repo/local_config.go

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>

* rename permissive read flag

* extend "permissive-read" rename

* hide permissive command-line flag

* syntax fixup

* fixup for test

* fixups for tests

* Update .golangci.yml

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>

---------

Co-authored-by: Shikhar Mall <mall.shikhar.in@gmail.com>
2023-03-27 16:08:11 -07:00
Jarek Kowalski
07972b56cf fix(ci): fixed test race condition due to logging (#2852) 2023-03-26 17:05:12 -07:00
Jarek Kowalski
ba919e9f16 chore(ci): fixed test flakes caused by not waiting for server to stop (#2749) 2023-02-09 06:46:56 +00:00
Jarek Kowalski
2801ab1640 feat(repository): added streaming of FindManifests responses (#2733)
This change adds a new streaming response to the FindManifests API. The
server will deliver the response in chunks of N manifests where N is
requested by the client. This allows the client to process the response
in chunks and improves pipelining of responses.

For now client will hold the entire response in memory since this
is what FindManifests() API currently does. This will be fixed in a
follow up change.

Replaces #2713
Fixes #2660
2023-02-07 06:19:09 -08:00
Jarek Kowalski
e6612977b7 feat(server): improved server shutdown and integration tests (#2722)
* feat(server): improved server shutdown and integration tests

Added `--shutdown-grace-period` flag to `kopia server start` command
which can be used to specify how long the server will wait for active
connections to finish before forcibly shutting down.

This allowed removal of final out-of-process execution of
during integration tests and the need for `integration-tests` target
which was running the same tests as `tests` but in out-of-process mode.

We thus now have all the test coverage in-process without having to
build and launch `kopia` binary.

* fixed logging

* increase test timeout

* speed up and/or parallelize longest-running tests
2023-02-01 22:19:32 -08:00
Edward Betts
1e97574391 fix(general): correct spelling mistakes (#2684) 2023-01-21 07:37:15 -08:00
lciti
37d64afc21 fix(snapshots): Partly fix #544 by supporting setuid/setgid/sticky bits when snapshotting, restoring and fuse-mounting. (#2597)
Also modified an end-to-end test to also check that these extra mode flags work when snapshotting+restoring.
Manually tested fuse-mount.

Co-authored-by: Luca Citi <lciti@ieee.org>
2022-12-07 03:26:29 +00:00
Jarek Kowalski
e57020fb70 test(repository): server testability refactoring (#2612)
- removed repo.OpenAPIServer() which was only needed for testability
- introduced servertesting package to replace it
2022-12-01 06:27:52 +00:00
Ricardo Pescuma Domenecci
31495392a1 feat(cli): Allow restore from snapshoted path (#2335)
* feat(cli): Allow restore from snapshoted path

* Find files in multiple snapshots

* Added --snapshot-time to restore

* Added restore by path test

* More timespec formats

* Test for snapshot list with a file in multiple snapshots

* Handle restore without target path

* Fix for tests

* Made changes requested in PR and rebased
2022-09-06 04:42:07 +00:00
Ricardo Pescuma Domenecci
47aaa2dc40 feat(cli): Added ECC related options to repository create cli command (#2308)
* Encryptor pipeline

* Added ECC related options to repository create cli command

* Fix for lint errors

* Fixing comments from the PR

* Fixed lint errors

* Changes requested in PR

* Created e2e test
2022-08-13 08:49:22 -07:00
Jarek Kowalski
51dcaa985d chore(ci): upgraded linter to 1.48.0 (#2294)
Mechanically fixed all issues, added `lint-fix` make target.
2022-08-09 06:07:54 +00:00
Jarek Kowalski
6160ee5668 refactor(repository): moved format blob management to separate package (#2245)
* refactor(repository): moved format blob management to separate package

This is completely mechanical, no behavior changes, only:

- moved types and functions to a new package
- adjusted visibility where needed
- added missing godoc
- renamed some identifiers to align with current usage
- mechanically converted some top-level functions into member functions
- fixed some mis-named variables

* refactor(repository): moved content.FormatingOptions to format.ContentFormat
2022-07-30 14:13:52 -07:00
Shikhar Mall
26e6f59b2b feat(cli): New Upgrade CLI / Switch to Format Version 3 (upgrade coordination) (#1818)
* kopia format upgrade lock

* Update cli/command_repository_set_parameters_test.go

Co-authored-by: Ali Dowair <adowair@umich.edu>

* Update cli/command_repository_upgrade.go

Co-authored-by: Ali Dowair <adowair@umich.edu>

* Update cli/command_repository_upgrade.go

Co-authored-by: Ali Dowair <adowair@umich.edu>

* pr feedback

* pr feedback

* add a min drain time check

* env var for io-drain-timeout

* fix: add more doctext around upgrade phases

* build: wrap with EnvName

* add experimental warning

* protect upgrade cli behind env varible

* fix conflicts after relocating the upgrade lock

* generalize the command args

* drop certain features as per feedback

* sub-divide the upgrade command into begin and rollback

* Update cli/command_repository_upgrade.go

Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>

* Update cli/command_repository_upgrade.go

Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>

* missing return

* rename force flag to allow-unsafe-upgrade

Co-authored-by: Shikhar Mall <shikhar@kasten.io>
Co-authored-by: Ali Dowair <adowair@umich.edu>
Co-authored-by: Shikhar Mall <small@kopia.io>
Co-authored-by: Julio Lopez <1953782+julio-lopez@users.noreply.github.com>
2022-07-27 16:23:45 -07:00
Jarek Kowalski
191b3e5461 feat(cli): BREAKING CHANGE ensure --checkpoint-interval is <=45min (#2196)
Also hide the flag, since it's not recommended to be tweaked anyway.

The value of <=45m is very important for safety of the garbage collection algorithms - too long an interval between checkpoints could mean that GC treats contents in the middle of being uploaded as unused, because they are not reachable from any snapshots or checkpoints.

Fixes #2193
2022-07-16 04:15:32 +00:00
Jarek Kowalski
8515d050e5 test(infra): improved support for in-process testing (#2169)
* feat(infra): improved support for in-process testing

* support for killing of a running server using simulated Ctrl-C
* support for overriding os.Stdin
* migrated many tests from the exe runner to in-process runner

* added required indirection when defining Envar() so we can later override it in tests

* refactored CLI runners by moving environment overrides to CLITestEnv
2022-07-09 18:22:50 -07:00
Jarek Kowalski
9941a05ab1 chore(ui): upgraded UI (#2157)
* https://github.com/kopia/htmlui/pull/88
* https://github.com/kopia/htmlui/pull/90
* https://github.com/kopia/htmlui/pull/89
* https://github.com/kopia/htmlui/pull/84
* https://github.com/kopia/htmlui/pull/85
2022-07-07 03:54:11 +00:00
Ali Dowair
98e10d52f1 Rename --sparse to --write-sparse-files (#2095)
This commit renames the sparse restore flag (`kopia snapshot restore`
and `kopia restore`) to conform more with the naming precedents in
the Kopia code. This is a breaking change.

The original motivation can be found here:
https://github.com/kopia/htmlui/pull/61#discussion_r899155054
2022-07-01 19:01:53 -07:00
Ali Dowair
eddde91f2d chore(snapshots): unify sparse and normal FS output paths (#1981)
* Unify sparse and normal IO output

This commit refactors the code paths that excercise normal and sparse
writing of restored content. The goal is to expose sparsefile.Copy()
and iocopy.Copy() to be interchangeable, thereby allowing us to wrap
or transform their behavior more easily in the future.

* Introduce getStreamCopier()

* Pull ioCopy() into getStreamCopier()

* Fix small nit in E2E test

We should be getting the block size of the destination file, not
the source file.

* Call stat.GetBlockSize() once per FilesystemOutput

A tiny refactor to pull this call out of the generated stream copier,
as the block size should not change from one file to the next within
a restore entry.

NOTE: as a side effect, if block size could not be found (an error
is returned), we will return the default stream copier instead of
letting the sparse copier fail. A warning will be logged, but this
error will not cause the restore to fail; it will proceed silently.
2022-06-14 18:09:45 +00:00
basldfalksjdf
a78dacc0d1 feat(snapshots): add option to ignore empty snapshots being saved (#2036)
* Add policy to ignore empty snapshots being saved

* Update command_snapshot_create.go

* Update source_manager.go

* Update command_snapshot_create.go

* Update source_manager.go

* fixes

* Update source_manager.go

* Update command_snapshot_create.go

* fix

* fix

Co-authored-by: Mehak  Satija <mehaksatija@Mehaks-MacBook-Pro.local>
Co-authored-by: Mehak  Satija <mehaksatija@Mehaks-MBP.hitronhub.home>
2022-06-13 03:41:08 +00:00
Julio Lopez
99fb50118f fix(cli): add retention to JSON output (#1992)
refactor(cli): snapshot list JSON functionality.
Defines SnapshotManifest struct for the snapshot list JSON output.

test(cli): `snapshot list --json`
2022-05-31 13:43:42 -07:00