Compare commits

..

939 Commits

Author SHA1 Message Date
5a2e6ccf77 api: tape restore: avoid throwing away ns mapping, use target_store instead
avoid assembling a hash mapping of namespaces only to not use it,
i.e., throw it away then anyway

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 16:59:57 +02:00
f31e32a006 api: tape restore: some code cleanups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 16:55:13 +02:00
2ad96e1635 api: tape restore: split/rework datastore/namespace map implementation
The split out helpers will (partially) be used in later patches for
call sites where we only need parts of the info assembled here.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 16:47:27 +02:00
7bc2e240b1 api: tape restore: use HumanByte for friendlier total/throughput reporting
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 10:45:13 +02:00
20a04cf07c api: tape restore: refactor some code parts shorter
not wanting to play code golf here, but bloat in code makes it often
also harder to read, so try to reduce some of that without making it
to terse.

No semantic change intended.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 10:42:47 +02:00
a40ffb92ac code formatting fixups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 10:38:33 +02:00
e2aeff40eb tape: use inline variable in formats for code reduction
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 10:38:33 +02:00
d20137e5a9 tree wide: typo fixes through codespell
Most, not all, found and fixes using `codespell -wci3 -L crate`

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-05 10:34:10 +02:00
6a35698796 bump version to 2.2.3-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 16:30:20 +02:00
2981cdd4c0 api: datastore status: use cheaper any_privs_below over can_access_any_namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:34:42 +02:00
8c9c6c0755 api: list datastore: avoid iterating over NS for priv check, use AclTree
Make the assumption that if a user has any privilege that would make
an NS and (parts) of its content visible they also should be able to
know about the datastore and very basic errors on lookup (path
existence and maintenance mode) even if that NS doesn't even exists
(yet), as they could, e.g., make or view a backup and find out
anyway.

This avoids iterating over parts of the whole datastore folder tree
on disk, doing a priv check on each, swapping IO to virtual in memory
checks on info we got available already anyway, is always a good idea
after all

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:34:42 +02:00
2c69b69108 config: cached user info: expose new any_privs_below
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:29:45 +02:00
0bed1f2956 config: any_priv_below: plural name & switch to slice of &str for path
s/any_priv_below/any_privs_below/ for consistency and switch from a
single &str for the path param to the slice-ref string variant, as
that allows to use it more often without allocation.

Also allow passing the whole path as single &str element in the slice
by splitting each component on '/' like we do in other parts
nowadays. Note though that we need to omit the leading slash then.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:29:45 +02:00
4ef6b7d1f0 config: s/propagating/only_propagated/ and style nits
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:29:45 +02:00
87d8aa4278 pbs-config: acl-tree: add any_priv_below
`any_priv_below()` checks if a given AuthId has any given privileges
on a sub-tree of the AclTree. to do so, it first takes into account
propagating privileges on the path itself and then uses a depth-first
search to check if any of the provided privileges are set on any
node of the sub-tree pointed to by the path.

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:29:45 +02:00
51d900d187 datastore: swap ConfigVersionCache with digest for change detection
We got the digest available anyway, and it's only 16 bytes more to
save (compared to last_generation and the recently removed last_time,
both being 64 bit = 8 bytes each)

Side benefit, we detect config changes made manually (e.g., `vim
datacenter.cfg`) immediately.

Note that we could restructure the maintenance mode checking to only
be done after checking if there's a cached datastore, in which case
using the generation could make sense to decide if we need to re-load
it again before blindly loading the config anyway. As that's not only
some (not exactly hard but not really trivial like a typo fix either)
restructuring work but also means we'd lose the "detect manual
changes" again I'd rather keep using the digest.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-04 15:26:50 +02:00
519ca9d010 datastore: make unsafe fn public again, useful for example/test
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 17:10:17 +02:00
615a50c108 datastore: make unsafe functions only visible in their own crate
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 13:42:42 +02:00
f418f4e48b api: list datastores: avoid unsafe datastore open
to avoid the problematic open fresh datastore with fresh chunkstore
with, and that's the actual problematic part, fresh process locker.
As the latter uses posix record locks which are pretty dangreous as
they operate on a path level (not FD level) and thus closing any file
opened (even if it wasn't opened for locking at all) drops all active
locks on the same file on completely unrelated file descriptors -.-

Also, no operation wasn't exactly correct for this thing in the first
place, but we cannot use Operation::Lookup either, as we're currently
indeed using a rather stupid-simple way and *are* reading.

So until we optimize this to allow querying the AclTree if there's
any priv XYZ below a path, use the Operation::Read.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 13:31:29 +02:00
c66fa32c08 datastore: add safety doc comment for unsafe opens
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 10:58:33 +02:00
2515ff35c2 datastore: reduce chunk store open visibility and comment pitfalls
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 10:15:41 +02:00
33a1ef7aae datastore: rename non-telling map to datastore_cache
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 10:11:09 +02:00
9c12e82006 datastore: drop bogus last_update stale-cache mechanism
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 10:04:16 +02:00
9f19057036 config: version cache: fix ordering of datastore generation increase
Fixes: 118deb4d (pbs-datastore: use ConfigVersionCache for datastore)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-03 09:18:09 +02:00
c7f7236b88 datastore: more concise comment
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 17:48:08 +02:00
fdefe192ac bump version to 2.2.2-3
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 17:38:52 +02:00
1ed8698b7e docs: faq: more specific eol date
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 17:38:52 +02:00
0bd9c87010 datastore: lookup: reuse ChunkStore on stale datastore re-open
When re-opening a datastore due to the cached entry being stale
(config change) but also if the last re-open was >60s ago). On
datastore open the chunk store was also re-opened, which in turn
creates a new ProcessLocker, loosing any existing shared lock which
can cause conflicts between long running (24h+) backups  and GC.

To fix this, reuse the existing ChunkStore, and thus  its
ProcessLocker, when creating a up-to-date datastore instance on
lookup, since only the datastore config should be reloaded. This is
fine as the ChunkStore path is not updatable over our API.

This was always a potential issue but got exposed in practice by
commit 118deb4db8 which introduced the
unconditional "re-open after 60s" mechanism.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [ T: reword commit message a bit and reference commit that made the
   issue much more likely ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 17:00:49 +02:00
fbfb64a6b2 tree wide: clippy lint fixes
most (not all) where done automatically

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 15:59:55 +02:00
c39852abdc client: clippy lints
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 15:57:33 +02:00
1ec167ee8c api types: clippy lints
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-02 15:57:07 +02:00
11ca834317 update to nix 0.24 / rustyline 9 / proxmox-sys 0.3
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-06-02 14:33:33 +02:00
68a6e970d4 bump tokio-util to 0.7
along with the rest of tokio/futures/hyper/openssl being updated - this
is the only one we explicitly depend on that had a non-compatible
version number.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-06-02 09:41:38 +02:00
4e851c26a2 bump version to 2.2.2-2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 17:00:02 +02:00
ceb815d295 server: remove jobstate: ignore removal error due to file not found
we want to remove lock and state file anyway, so not found is all
right

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 16:40:09 +02:00
14433718fb bump version to 2.2.2-1
same story as last time

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 15:09:43 +02:00
3dc8783af7 manager cli: output more info when transforming prune jobs
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 15:09:20 +02:00
6d89534929 bump version to 2.2.2-1
re-bump for small fixes discovered before any upload

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 14:34:03 +02:00
aa19d5b917 manager cli: output more info when skipping prune tranforms
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 14:31:53 +02:00
a8d3f1943b api types: prune keep options: also check weekly in keeps_something
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 14:30:24 +02:00
3cf12ffac9 bump version to 2.2.2-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-06-01 13:04:37 +02:00
2017a47eec Cargo.toml: add missing patch sections
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-06-01 11:01:23 +02:00
21185350fb ui: add prune job worker task description and renderer
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-31 13:11:23 +02:00
17b079918e ui: prune & gc: relay activate/deactivate events to sub panels
which allows us also to drop the initial manual load in the init,
which would also trigger if the tab isn't visible.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-31 10:02:12 +02:00
fbfc439372 ui: system config: improve bottom margins and scroll behavior
setting scrollable on the parent tab panel makes not much sense and
will always add a scroll bar that can scroll a few pixels, even if
there's enough space.
Rather set it to true (= auto) in the actual panels that hold the
content.

Also set a bottom margin so that users can see the "end" of the panel
at the bottom, otherwise it looked like it had a start and sides, but
no bottom.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-31 07:03:31 +02:00
27d3a232d0 ui: prune jobs: avoid duplicate params through nested input panels
input panel collect all form fields below them, so nesting two
input panels needs a bit of special care to avoid that each of the
panels adds the data of the deeper nested ones, resulting in
duplicate parameters that the backend then chokes one.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-30 15:15:42 +02:00
1fa6083bc8 ui: prune & gc: disallow collapse and add bottom margin
the intra-panel margin is still the same (10 + 0 == 7 + 3) but one
can now see the bottom border.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-30 15:02:08 +02:00
aa32a46171 api: disable setting prune options in datastore.cfg
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 14:48:15 +02:00
6283d7d13a stop executing datastore prune job
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 14:47:57 +02:00
d4dd7ac842 api: don't use PRUNE perms for prune jobs
just stick to MODIFY so we don't need to give the prune jobs
an owner for now

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 14:33:06 +02:00
451da4923b drop unused import
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 14:01:22 +02:00
f15e094408 d/postinst: transform prune tasks from datastore cfg to new prune job
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-30 13:58:45 +02:00
134779664e manager: hidden command to move datastore prune opts into jobs
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
9ce2f903fb ui: rework prune job view/edit
Fix missing load on initial view, re-use the prune input panel for
editing and avoid using a tab panel for a single tab, rework also
some columns widths and various other small parts-

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-30 13:58:43 +02:00
6802a68356 ui: re-integrate prune into prune & GC panel
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-30 13:58:43 +02:00
c69884a459 ui: add ui for prune jobs
similar to verification/sync jobs, the prune settings on the
datastore are deprecated

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
93205cbe92 tests: switch to PruneJobOptions
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
434dd3cc84 client: switch to PruneJobsOptions
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
dba37e212b add prune jobs api
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
db4b8683cf add prune job config
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
5557af0efb api-types: add PruneJobConfig
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
8721b42e2f api: add some missing sorted macro calls
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-30 13:58:43 +02:00
5408e30ab1 d/postinst: fix upper version for applying sync.cfg remove-vanished default
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-30 13:40:24 +02:00
70493f1823 ui: datastore content: better cope with restricted privs on parent namespaces
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 16:09:48 +02:00
069720f510 ui: datastore content: only mask the treeview, not the top bar
so that an user can try to reload again easily for non-persistent
errors

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 16:06:21 +02:00
a93c96823c ui: datastore content: avoid duplicate masking on load error
we already handle that manually in the onLoad and want to further
extend that, so drop the more generic monStoreError

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 16:02:44 +02:00
2393943fbb api: namespace list: fix restrictive priv checking
This endpoint only lists all accessible namespace, and one doesn't
necessarily needs to have permissions on the parent itself just to
have OK ACLs on deeper down NS.

So, drop the upfront check on parent but explicitly avoid leaking if
a NS exists or not, i.e., only do so if they got access on the parent
NS.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 11:14:01 +02:00
49d604aec1 ui: datastore options: avoid breakage if rrd store cannot be queried
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 10:59:42 +02:00
246275e203 ui: datastore options: avoid breakage if active-ops cannot be queried
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 10:59:25 +02:00
c9fb0f3887 ui: datastore summary: cope with optional gc-stats
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 10:58:38 +02:00
84de101272 api: status: include empty entry for stores with ns-only privs
I.e., for those that only got permissions on a sub namespace and
those that onlöy got BACKUP_READ, as both they could just list and
count themselves too after all, so not exactly secret info.

The UI needs some adaptions to cope with gc-stats and usage being
optional, will be done in a next commit.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-27 10:55:48 +02:00
de77a20d3d api: move can_access_any_namespace helper to hierarchy
to prepare for reuse

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 13:35:33 +02:00
997c96d6a3 datastore status: impl empty-status constructor for item type
we can now use it for the error case and will further use it for the
can access namespace but not datastore case in a future patch

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 13:34:00 +02:00
513da8ed10 docs: fix yet another typo
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 13:26:56 +02:00
e87e4499fd docs: fix some typos
The s/Namesapce/Namespace/ one was reported in the forum [0] and so I
figured I do a quick scan for others too using codespell.

[0]: https://forum.proxmox.com/threads/109724/post-472744

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 13:08:52 +02:00
a19b8c2e24 pbs-config: clippy fixes
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 11:42:13 +02:00
b8858d5186 datastore: avoid unsafe transmute, use to_ne_bytes
which is stable since rustc 1.32 but wasn't available in out
toolchain when this was originally written in commit 7bc1d7277

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 11:42:13 +02:00
bc001e12e2 datastore: clippy fixes
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-26 11:42:13 +02:00
abd8248520 tree-wide: remove DatastoreWithNamespace
instead move the acl_path helper to BackupNamespace, and introduce a new
helper for printing a store+ns when logging/generating error messages.

Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-26 11:42:10 +02:00
974a3e521a api: datastore: cleanup store/ns handling
this should just avoid some clones, no semantic changes intended.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
ea2e91e52f move and unify namespace priv helpers
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
77bd14f68a sync/pull: cleanup priv checks and logging
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
d1fba4de1d include privilege names in check_privs error
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
3e4994a54f api: tape: use check_privs instead of manual lookup
these all contain the path in the error message already, so no (new)
potential for leakage..

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
75b377219d api: backup env: use check_privs
it includes the path, which might be helpful when users are switching to
using namespaces. datastore and namespace lookup happens after, so this
doesn't leak anything.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
c8dc51e41f api: namespace: check privs directly
instead of doing a manual lookup and check - this changes the returned
error slightly since check_privs will include the checked ACL path, but
that is okay here, checks are before we even lookup the namespace/store,
so no chance to leak anything.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
7d0dbaa013 priv checks: use priv_to_priv_names and include path
where appropriate. these should never leak anything sensitive, as we
check privs before checking existence or existence is already known at
that point via other privileges.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
efa62d44d4 api: add new priv to priv name helper
for usage in permission check error messages, to allow easily indicating
which privs are missing.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
210ded9803 priv handling: use DatastoreWithNamespace
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
99e1399729 api: tape: restore: improve permission checks
no redundant store+namespace mapping, and synchronize namespace creation
check with that of manual creation and creation as part of sync.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
0aa5815fb6 verify_job: fix priv check
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
bb5c77fffa api2: reader env: fix priv checks
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
ebfcf75e14 acl: fix handling of sub-components containing '/'
previously with an ACL for the path "/foo/bar" without propagation and a
check for `&["foo", "bar/baz"] this code would return the ACL (roles)
for "/foo/bar" for the path "/foo/bar/baz".

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
83e3000349 sync job: don't require privs on datastore
syncing to a namespace only requires privileges on the namespace (and
potentially its children during execution).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
4a4dd66c26 api: list snapshots: fix log param order
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
b9b2d635fe sync job: fix worker ID parsing
the namespace is optional, but should be captured to allow ACL checks
for unprivileged non-job-owners.

also add FIXME for other job types and workers that (might) need
updating.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-25 17:18:56 +02:00
9f8aa8c5e2 debug: recover: allow overriding output-path
including to STDOUT.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Tested-by: Hannes Laimer <h.laimer@proxmox.com>
2022-05-24 11:46:04 +02:00
b11693b2f7 debug: move outfile_or_stdout to module for reuse
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Tested-by: Hannes Laimer <h.laimer@proxmox.com>
2022-05-24 11:45:59 +02:00
53435bc4d5 debug: recover: allow ignoring missing/corrupt chunks
replacing them with chunks of zero bytes.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Tested-by: Hannes Laimer <h.laimer@proxmox.com>
2022-05-24 11:45:54 +02:00
8bec3ff691 tape/pool_writer: give proper types to 'contains_snapshot'
instead of a string. The underlying catalog implementation has to
care about how this is formatted, not the external caller

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-23 16:20:13 +02:00
789e22d905 proxmox-tape: use correct api call for 'load-media-from-slot'
it's a 'post' api call, not 'put'

reported here:
https://forum.proxmox.com/threads/lto8.109946/
and here:
https://forum.proxmox.com/threads/cant-clear-tape.86454/

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-23 16:14:41 +02:00
a1c30e0194 cargo fmt
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-23 16:12:22 +02:00
d4c6e68bf0 fix typo
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-23 15:05:38 +02:00
e642344f98 ui: datastore content: enable recursive/depth selector for prune all
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 13:35:01 +02:00
d4574bb138 ui: prune input: support opt-in recursive/max-depth field
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 13:34:17 +02:00
26b40687b3 prune datastore: add depth info to tak log
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 13:32:45 +02:00
e3c26aea31 prune datastore: support max-depth and improve priv checks
use the relatively new variant of ListAccessibleBackupGroups to also
allow pruning the groups that one doesn't own but has the respective
privileges on their namespace level.

This was previously handled by the API endpoint itself, which was ok
as long as only one level was looked at.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 13:31:09 +02:00
65aba79a9b prune datastore: rework tak log
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 13:23:24 +02:00
4b6a653a0f verify filter: improve comment
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 12:36:51 +02:00
3c41d86010 verify all: adhere to NS privs for non-owned groups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 12:36:06 +02:00
93821e87e6 accessible group iter: rename "new" to "new_owned"
to clarify that it's only returning owned backups that way.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 12:34:06 +02:00
f12f408e91 api: datastore status: adhere to NS privs for non-owner
Not only check all owned backup groups, but also all that an auth_id
has DATASTORE_AUDIT or DATASTORE_READ on the whole namespace.

best viewed with whitespace change ignore (-w)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 12:32:35 +02:00
71cad8cac0 accessible group iter: add owner override and owner + extra priv handling
The "owner override" privs will skip the owner check completely if
the authid has a permission for any of the bitwise OR'd privs
requested on the namespace level.

The "owner and privs" are for the case where being the owner is not
enough, e.g., pruning, if set they need to match all, not just any,
on the namespace, otherwise we don't even look at the groups from the
current NS level.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 12:27:58 +02:00
49bea6b5d9 accessible group iter: allow NS descending with DATASTORE_READ
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-19 12:26:48 +02:00
f7247e2b84 ui: datastore content: add icons to top bar prune/verify buttons
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 18:37:20 +02:00
5664b41c30 ui: acl view: make path column flex, but enforce minWidth
with namespaces the paths can get pretty complex, so make the path
column take some flex space too, but not too much to avoid making it
look odd for the short paths we have otherwise

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 18:22:17 +02:00
33612525e1 ui: datastore permissions: allow ACL path edit & query namespaces
Without namespaces this had not much use, but now that we can have
permissions below we should allow so.

For convenience also query the namsepaces here and add them to the
list of available ACL paths, the read-dir shouldn't be that expensive
(albeit, we could cache them in the frontend)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 18:14:37 +02:00
a502bc5617 ui: small style cleanups/refactoring
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 18:04:16 +02:00
8772ca727c api types: verify job: fix doc comment typo
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 15:45:55 +02:00
7f3b4a94e6 api types: verify job: allow outdated-afer == 0 for backward compat
We can have those in existing verify jobs configs, and that'd break
stuff. So, even while the "bad" commit got released only recently
with `2.1.6-1` (14 April 2022), we still need to cope with those that
used it, and using some serde parser magic to transform on read only
is hard here due to section config (json-value and verify currently
happen before we can do anything about it)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 15:39:59 +02:00
327d14b3d1 Revert "verify: allow '0' days for reverification"
This reverts commit 7a1a5d206d.

We could already cause the behavior by simply setting ignore-verified
to false, aas that flag is basically an on/off switch for even
considering outdated-after or not.

So avoid the extra logic and just make the gui use the previously
existing way.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 12:53:08 +02:00
0f8fd71093 cargo: update commented-out path patched dependencies
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 09:00:41 +02:00
8d3b84e719 d/changelog: fixup last entry
as this obviously is released...

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-18 08:45:53 +02:00
d1d328d582 bump version to 2.2.1-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 14:03:30 +02:00
72e344a1b4 ui: namespace & maintenance mode: refer to onlineHelp
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 14:03:00 +02:00
f71a4ce6d6 docs: client usage: add some hints for namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:55:21 +02:00
a3b1026753 docs: some textwidth cleanups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:55:04 +02:00
5e1b17018b ui: namespace selector: show picker empty text if no namespace
by filtering out the empty namespace from the api, and putting
manually a div with the grid-empty xclass around the gettext

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [ T: reword commit message ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:40:27 +02:00
9615d9a6b6 ui: tape restore: reword comment w.r.t. mapping value
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:35:55 +02:00
3ae4dab4b9 ui: tape restore: fix form validation for datastore mapping
'defaultStore' can be '' or null, so check for truthyness also, we
want the mapping to be a formField so that the validation triggers
and the restore button gets en/disabled accordingly. We still have to
call 'getValue' manually, because the onGetValues will get it as
string instead of an array

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:35:21 +02:00
d74172bfc1 node info: fix typo in product name
s/Bacckup/Backup

Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
2022-05-17 13:30:36 +02:00
2e9a9f94a4 update online help reference info
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:30:11 +02:00
ed9797d67e storage: add some initial namespace docs
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:29:02 +02:00
56f0ce27ac docs: storage: refer to options
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:28:50 +02:00
67d4131158 docs: basic maintenance mode section
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:28:24 +02:00
acbb19498a docs: also mention Sync in heading of Managing Remotes
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:28:05 +02:00
187ec50488 docs: refer more to screenshots all over the place
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:27:37 +02:00
b3116e5680 docs: update and add screenshots
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 13:27:09 +02:00
77baca66eb ui: datastore list: drop duplicate errorBox reference, neither is used
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 11:07:46 +02:00
e7ddae292a ui: datastore selector: move maintenance mode inline with icon
else it's a lot of wasted space for the ordinary case, that hasn't
permanent maintenance modes activated, and even if, their admins
should be used to it, so not the best space/usability ROI there
either.

Just use the icon as visual clue and add a tooltip for the
maintenance mode info.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 10:49:31 +02:00
c15b058db7 ui: form/DataStoreSelector: show maintenance mode in selector
to not having to query the activeTasks everywhere, change the renderer
to omit the check/spinner when no activeTasks are given

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-17 10:40:56 +02:00
8af1fa5477 ui: use base 10 (SI) for all storage related displays
matches what we do for (most) of such things in PVE since 7.0 there
and also what the disk management gui shows, further disks are sold
with SI units for their advertised capacity, so its more fitting
there too.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 10:21:26 +02:00
f61d822efa ui: utils: add depreacation comment to render_size_usage
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 10:21:26 +02:00
d0e3f5dd5c ui: server status: fix missing space in title
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 10:21:26 +02:00
16e605583f ui: server status: use power of two base for memory and swap
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 10:21:26 +02:00
62e5cf1e8c pbs-client: fix symbolic mode display for 'other' mode
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-17 10:20:57 +02:00
76bc66b9bd ui: sync/verify jobs: use pmxDisplayEditField to fix editing
commit bd21a63b only fixed sync, not verify, and we can do better by
using a display-edit field.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 09:48:03 +02:00
bd21a63bd2 ui: sync job: don't send 'id' on edit
we cannot change the id, and even if we send the same, the backend
does not allow 'duplicate' parameters (the id is in the url already)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 09:47:56 +02:00
d14512c82d ui: datastore/Summary: correctly show the io-delay chart
by checking if *any* record has data, not only the first
this would prevent the chart from being shown for e.g. newly added
datastores, or for datastores after the server was offline for some time

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 09:47:56 +02:00
e5cf0e3eda ui: update online help reference
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 09:47:56 +02:00
14f140d1c5 docs: storage: show gui disk management screenshot
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 09:47:56 +02:00
1d592668ac docs: update/add some screenshots
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-17 09:47:56 +02:00
2c0fae66b3 docs: certs: fix odd image referencing and drop duplicate usage
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 19:27:06 +02:00
cbd7db1d7f docs: certificates
manually adapt to differences between PMG and PBS

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-16 19:27:06 +02:00
6189b956b6 docs: add certificate-management.rst
the file certificate-managment.rst is generated from the pmg-docs repo

by running:
```
asciidoc -b $(pwd)/asciidoc/pmg-docbook \
-f asciidoc/asciidoc-pmg.conf -o - pmg-ssl-certificate.adoc | \
pandoc -f docbook -t rst --shift-heading-level-by=1 \
-o certificate-mangement-auto.rst

sed -ri 's/__/_/' certificate-mangement-auto.rst
sed -ri 's/\{pmg\}/`Proxmox Backup`_/g' certificate-mangement-auto.rst
sed -ri 's/\{PMG\}/`Proxmox Backup`_/g' certificate-mangement-auto.rst
sed -ri 's/Proxmox Mail Gateway/`Proxmox Backup`_/g' \
certificate-mangement-auto.rst
sed -ri 's/pmg-([a-zA-Z0-9_-]*).png/pbs-\1.png/g' \
certificate-mangement-auto.rst
sed -ri 's/pmgproxy/proxmox-backup-proxy/g' \
certificate-mangement-auto.rst
sed -ri 's/pmgconfig/proxmox-backup-manager/g' \
certificate-mangement-auto.rst
sed -ri 's/pmg-daily/proxmox-backup-daily-update/g' \
certificate-mangement-auto.rst
sed -ri 's/\/etc\/pmg\/node.conf/\/etc\/proxmox-backup\/node.cfg/g' \
certificate-mangement-auto.rst
sed -ri 's/\/etc\/pmg\/acme/\/etc\/proxmox-backup\/acme/g' \
certificate-mangement-auto.rst
sed -ri \
's/\/etc\/pmg\/pmg-api.pem/\/etc\/proxmox-backup\/proxy.pem/g' \
certificate-mangement-auto.rst
sed -ri 's/screenshot/screenshots/g' certificate-mangement-auto.rst

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-16 19:27:06 +02:00
c2add820a4 docs: add certificate related screenshots
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 19:27:06 +02:00
e1dc2d2210 docs: use case-matching keys for glossary
this silences warnings a la:
```
WARNING: term container not found in case sensitive match.made a
reference to Container instead
```
the issue is purely cosmetic during build, and should vanish in a newer
version of sphinx-doc [0].

[0] https://github.com/sphinx-doc/sphinx/issues/7636

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-16 19:27:06 +02:00
bffc923420 docs: cleanup and readd command-line-tools
the collection of descriptions of our cli tools was dropped in
04e24b14f0

I'll readd it to the sysadmin.rst, since the (related) service daemons
also got moved here.

additionally add the newly added cli-tools to both
command-line-tools.rst and command-syntax.rst, and put both in the same
order

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-16 19:27:06 +02:00
c760a67278 docs: silence duplicate label warnings.
by reindroducing the trailing ',' after local-zfs.rst
and adding the missing 'traffic-control.rst' to the list
of files/patterns to be excluded.

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-16 19:27:06 +02:00
0181b0f1f7 bump version to 2.2.0-2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 19:01:19 +02:00
d22363ad08 BackupDir/BackupGroup: add ns to Debug impl
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
7784698948 BackupGroup: stop implementing Display
this shouldn't be printed/logged - use DatastoreWithNamespace /
pbs_api_types::BackupGroup instead.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
3697161800 prune: fix workerid issues
properly encode the namespace as separate field both for manual prunes
and the job. fix the access checks as well now that the job doesn't use
the jobid as workerid anymore.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
e13303fca6 tree-wide: prefer api-type BackupGroup for logging
together with DatastoreWithNamespace where needed, to not forget
namespace information.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
eefa297aa0 BackupDir: stop implementing Display
the api type implements it already, all call sites should rather use
DatastoreWithName and pbs_api_types::BackupDir for logging/..

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
5ae393af15 tape/verify: use print_ns_and_snapshot
in those few places where we actually want to use/print the full,
NS-included path.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
f2fe00f1e2 BackupDir: fix manifest_lock_path
this definitely shouldn't rely on BackupDir's Display implementation..

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
1afce610c7 tree-wide: prefer api-type BackupDir for logging
in combination with DatastoreWithNamespace to not lose the namespace
information.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
f15601f1c9 BackupDir: add group/dir accessors
for getting the respective api type references for convenient
printing/logging.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:49:19 +02:00
90915ab629 ui: verify/sync: allow to optionally override ID again
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 18:48:44 +02:00
ebab1e5ed9 api: namespace create: lookup datastore with corret operation
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 18:26:55 +02:00
6da6bafeac ui: add maintenance mask to DataStoreListSummary
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-05-16 18:10:35 +02:00
067c77329b docs: acl path: add a namespace related example
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 18:10:13 +02:00
8c4131708a docs: add namespace section to sync documentation
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 18:09:15 +02:00
a7646fe42a Revert "fix #4001: datastore/catalog: add number of files to directory entry"
causes trouble with UI and is inconsistent as its still missing in
file restore (daemon)

We probably want to use a separate property to safe this to avoid
confusion with size.

This reverts commit 66ad63bac2.
2022-05-16 17:51:35 +02:00
dadaa9e2f0 ui: verify outdated: disallow blank and drop wrong empty text
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 16:46:06 +02:00
6a7b673872 ui: switch summary repo status to widget toolkit one
Not only can we remove a few lines of duplicated code, we also get
the "link to repo management" for free.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 15:56:33 +02:00
0606432e9b d/control: use regular versioned build-dependency
although the full variant is provided by the current librust-log-dev
package, it won't be once it gets bumped to the next upstream version.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 15:52:39 +02:00
7ebd97e8ea ui: fix setting protection in namespace
The ns parameter would not be included previously.

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
2022-05-16 15:29:55 +02:00
44df558d66 docs: terminology: add namespaces and slightly restructure
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 15:28:00 +02:00
9c75e2f3e1 build: bump required log version
else logging using "{var}" in format strings doesn't work properly.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 15:02:07 +02:00
4adb574d74 client: add completion callbacks for ns parameters
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-16 11:59:14 +02:00
fb840eda4d pbs-client: namespace completion helper
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-16 11:58:13 +02:00
007388f053 bump version to 2.2.0-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 11:06:18 +02:00
1d9ba1cc8b docs: add "Objects and Paths" section and fix perm scrot
we show the add-user one twice in this chapter, one should actually
be add-permission

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 10:56:19 +02:00
63e98028cc api types: namespace: fix typo in error message
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 09:50:17 +02:00
e3ea577011 pull: use API BackupDir for log messages
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-16 09:43:28 +02:00
6bfc94ea19 api types: BackupNamespace: fix depth check on pushing subdir to ns
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 09:37:38 +02:00
1f2126fd7c api types: BackupNamespace: remove unused, commented out code
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 09:37:38 +02:00
456456483e datastore: ns iter: clamp depth to MAX_NAMESPACE_DEPTH from datastore root
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 09:37:38 +02:00
3eb15257b9 ui: permission path selector: add some more path suggestions
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 08:44:49 +02:00
597398cb48 docs: rework access control, list available privileges
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-16 08:00:40 +02:00
3d2baf4170 ui: datastore: use safe destroy as base for dialog
only ask the name of the current NS, not the full NS path to avoid
too long input requirements on deep levels.

needs a few smaller hacks, ideally we would pull out the basic stuff
from Edit window in some EditBase window and let both, SafeDestroy
and Edit window derive from that, for better common, in sync
features.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:47:44 +02:00
3aafa61362 namespace deletion: propagate delete-groups=false but ENOTEMPTY as error
after all we couldn't delete all that got requested, ideally this
should become a task where we can log what got deleted and what
not...

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:32:49 +02:00
60b9676fa2 ui: datastore: allow deleting currently shown namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:04:50 +02:00
e5824cd61f ui: content: reload tree on succesful datastore add
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:03:16 +02:00
508d644e87 ui: tree NS entries: remove commented out qtip
we won't use that, it's to invasive

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:02:38 +02:00
b0166d4e8d api: cargo fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:01:57 +02:00
ca3f8757ba datastore: clippy fixes
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 16:01:09 +02:00
118e984996 datastore: move backup dir/group/namespace iter to own module
no changes in interface for users of the crate as we re-export
anyway, so more for avoiding to crowd the datastore module to much

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 15:59:43 +02:00
45ba884d0d ui: content: fix tooltip for forgetting snapshot
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 14:09:25 +02:00
d1f9cceada namespace deletion: make destroying groups separate choice
And make that opt-in in the API endpoint, to avoid bad surprises by
default.

If not set we'll only prune empty namespaces.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 14:09:25 +02:00
4ac8ec11fb fix #4001: ui: add prefix to files downloaded through the pxar browser
Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 14:09:25 +02:00
66ad63bac2 fix #4001: datastore/catalog: add number of files to directory entry
When listing the content of a catalog, add the number of files
contained in the directory as its size. Also removes redundant code,
the `mtime` and the `size` of a file is already set when creating the
archive entry, but we naturally need to override the size now for
directories.

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-15 14:08:51 +02:00
9ec82aefb4 ui: prune all: add namespace info in title
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 18:57:05 +02:00
e3cda36ba5 ui: move prune input panel into own file
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 18:51:54 +02:00
5d05f334f1 ui: prune group: add NS info to title
restructure it a bit for better UX

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 18:47:13 +02:00
a3d61f3fba ui: remote target ns selector: add clear trigger
like we have for the local NS selector

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 18:40:52 +02:00
ed289736cf ui: improve render_optional_namespace slighly
it maybe should still simple get dropped and replaced with
(empty)Text 'Root' or 'Root Namespace'

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 18:39:56 +02:00
dc193e8197 ui: remote target ns selector: fix clearing value on edit
never makes sense to clear the value due to remote or remoteStore
change as we weren't enabled then in the first place.

This fixes clearing the currently set namespace on editing an
existing job, which always made it seem like the Root namespace was
selected, even if the originalValue was correct (thus the dirty-form
reset/ok behaviour still worked, making it even more confusing)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 18:29:12 +02:00
1f71e44172 client: make change-owner and prune namespace aware
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 17:16:25 +02:00
7da520ae46 hierachy: ListAccessibleBackupGroups make store also a lifetime'd ref
avoid some extra Arc::clone, even if they're not really expensive
(just some atomics)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 14:56:34 +02:00
cbde538c0c ui: maintenance mode: opinionated code cleanup
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 14:51:57 +02:00
cf1b029b3f ui: ACL edit: set default focus on a non-combobox element
to avoid making it "jump" in the users face by immediately opening
the picker on window open.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 14:50:40 +02:00
4f897c8cf9 ui: namespace selector: set queryMode to local
to avoid that the comobox triggers automatic API request with the
queryParam default `query` GET param on manual typing (e.g., for
filtering) from the user, we have all data already loaded and locally
available.

https://docs.sencha.com/extjs/7.0.0/classic/Ext.form.field.ComboBox.html#cfg-queryMode

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 14:48:36 +02:00
2e63a46414 ui: trigger datastore update after maintenance mode edit
This provides immediate feedback for adding the respective icon in
the navigation tree entry most of the time, and we can then increase
the query period of the datastore list store to the original 15
again, as it was lowered to 5 seconds for just this reason in commit
fbd6f54f39

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 14:39:02 +02:00
9f4d9abbf6 ui: fix storeId casing to register store correctly
we query that store to add the datastore specific ACL paths to
improve UX there, this failed a while due the StoreManager lookup
always failing as the store wasn't registered in the StoreManager due
to using storeid vs. correct storeId

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-14 12:28:03 +02:00
8122eaadaa cargo fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 16:59:32 +02:00
22cfad134f api: datastore status: make counts recurse over all accesible namespaces
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 16:49:42 +02:00
de27ebc6b6 hierachy: add lifetime to ListAccessibleBackupGroups so that owner can be ref
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 16:48:56 +02:00
74391d1c32 docs: tape: add information about namespaces
which are backed up, how to use the new parameters and how to map
them during restore

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 15:45:17 +02:00
fca84a4b94 docs: tape/restore: mention single snapshot restore
what it is, how to use it and the caveats

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 15:45:17 +02:00
602319f9fc docs: tape: remove note about global content namespace
that is actually not true, we save the datastore in the chunk archives
as well as the snapshot archives, otherwise we could not backup
multiple datastores to a single media-set.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 15:45:17 +02:00
8d2a9b2904 cli: proxmox-tape: fix ns/depth parameter
was forgotten after recent rebase

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 15:45:17 +02:00
c8e93b31ff bump version to 2.1.10-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 14:26:38 +02:00
cf99333b83 ui: adapt to s/backup-ns/ns/ api param change
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 14:21:52 +02:00
b70a12e723 ui: tape/Restore: allow simple namespace mapping
add a default namespace selector (of the current default store)
and a namespace selector per target datastore (for media-sets with
multiple datastores).

to achieve that we have to change the way we handle the mapping field a bit:
* don't use it as field directly (otherwise the value gets stringified),
  but use the 'getValue' method in 'onGetValues'.
* set the defaultStore there, not only that we have one
  (with this we can now easily show it as emptytext for each store)
* add a reference to the widgets to the record so that we can access
  them in the respective change handler (also clean those references up,
  else we have a cyclic reference between record <-> widget)

in onGetValues, if we have multiple datastores, the mapping grid does
all the work for us, otherwise, we have to create the ns mapping
ourselves there.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:09:53 +02:00
f6b09e83cb ui: tape/BackupJobEdit: add onlineHelp
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:09:53 +02:00
6f836d3ffa ui: tape/Backup: add namespace + max-depth to backup job edit window
like we do for sync

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:09:53 +02:00
80df7caded ui: tape/Backup: add namespace and recursion field for manual backup
and change the layout to two columns, because the window was getting
too tall.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:09:53 +02:00
12d334615b api: tape/backup: fix namespace/max-depth parameters
by adding the 'default' serde hint and renaming 'recursion_depth' to
'max_depth' (to be in line with sync job config)

also add the logic to actually add/update the tape backup job config

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:09:53 +02:00
1e37156a6b ui: tape/BackupOverview: show namespaces as their own level above groups
since the namespaces are in the snapshot path we get here, we must parse
them out, else we confuse the first namespace with the group.

for now, show all namespaces on the same level (so not nested), and
do not allow for preselecting a namespace for restoring

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:08:32 +02:00
e49bd1e98f tape: media catalog: use match for magic check
like in other parts of the code

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 14:08:32 +02:00
707c48ad46 tape: bump catalog/snapshot archive magic
the snapshot string format is not backwards compatible since it now has
an in-line namespace prefix. it's possible to select which magic to use
at the start of the backup, since a tape backup job knows whether it
operates on non-root namespaces up-front.

the MediaCatalog itself also has a similar incompatible change, but
there
- updating existing catalogs in-place
- not knowing what the catalog will contain in the future when initially
  creating/opening it
makes bumping the magic there harder. since the tape contents are
sufficiently guarded by the other two bumps, ignoring the
backwards-incomaptible change of the on-disk catalogs seems like an okay
tradeoff.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 14:08:32 +02:00
07ffb86451 api: tape/restore: add namespace mapping
by adding a new parameter 'namespaces', which contains a mapping
for a namespace like this:

store=datastore,source=foo,target=bar,max-depth=2

if source or target are omitted the root namespace is used for its value

this mapping can be given several times (on the cli) or as an array (via
api) to have mappings for multiple datastores

if a specific snapshot list is given simultaneously, the given snapshots
will be restored according to this mapping, or to the source namespace
if no mapping was found.

to do this, we reutilize the restore_list_worker, but change it so that
it does not hold a lock for the duration of the restore, but fails
if the snapshot does exist at the end. also the snapshot will now
be temporarily restored into the target datastore into the
'.tmp/<media-set-uuid>' folder.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:08:32 +02:00
fc99c2791b api: tape/restore: check and create target namespace
checks the privilegs for the target namespace. If that does not exist,
try to recursively create them while checking the privileges.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:08:32 +02:00
6b61d319c5 api: tape/restore: add optional namespace map to DataStoreMap
and change the interface from 'get_datastore' to 'get_targets'

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:08:32 +02:00
be97e0a55b tape: add namespaces mapping type
and the relevant parser for it

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:08:32 +02:00
999293bbca tape: add namespaces/recursion depth to tape backup jobs
and manual api via TapeBackupJobSetup

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 14:08:31 +02:00
9c65e6ab4a tape: fix snapshot path in catalog and snapshot_archive
both used the 'Display' trait of pbs_datastore::BackupDir, which is not
intended to be serialized anywhere. Instead, manually format the path
using the print_ns_and_snapshot helper, and conversely, parse with
'parse_ns_and_snapshot'. to be a bit safer, change the register_snapshot
signature to take a BackupNamespace and BackupDir instead of a string.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 13:52:50 +02:00
1e4e1514d3 pbs-api-types: add parse and print ns_and_snapshot
these are helpers for the few cases where we want to print and parse
from a format that has the namespace and snapshot combined, like for
the on-tape catalog and snapshot archive.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 13:52:50 +02:00
05b7175a56 tape: notify when arriving at end of media
when continuing a media set, we first move to the end of the tape and
start with the next (chunk) archive. If that takes long, the task logs
last line is 'moving to end of media' even if we already startet
writing. To make this less confusing, log that we arrived at the
end of the media.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-13 13:52:50 +02:00
bc21ade293 tree-wide: rename 'backup-ns' API parameters to 'ns'
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-13 13:46:13 +02:00
f07e660153 ui: move max NS prefix length logic to reduced max-depth selector
for better re-usability in the future and it felt a bit odd to have
such specific logic in the sync job edit directly

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 13:15:02 +02:00
addcb7803e datastore: inline some format variables
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 12:42:41 +02:00
1ddfae5499 api types: set NS_MAX_DEPTH schema default to MAX_NAMESPACE_DEPTH
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 12:32:25 +02:00
54d315c951 ui: group filter: make also local filter NS aware
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-13 12:32:25 +02:00
9dde8cd625 ui: sync: add reduced max-depth selector
that allows setting the limit based on sync namespace prefix lengths.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 12:20:29 +02:00
87be232d1c pull/sync: clamp (local) max-depth if unset
to handle the unlikely case of `ns` being deeper than `remote-ns`,
`max-depth` being set to `None` and a too-deep sub-ns of `ns` existing.
such a sub-ns cannot have been created by a previous run of this sync
job, so avoid unexpectedly removing it.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 12:07:22 +02:00
e40c7fb906 api: split max-depth schema/types
into the regular one (with default == MAX) and the one used for
pull/sync, where the default is 'None' which actually means the remote
end reduces the scope of sync automatically (or, if needed,
backwards-compat mode without any remote namespaces at all).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 12:07:22 +02:00
66abc4cb7d namespaces: move max-depth check to api type
and use it when creating a sync job, and simplify the check on updating
(only check the final, resulting config instead of each intermediate
version).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 12:07:22 +02:00
11567dfbad pull/sync: correctly query with remote-ns as parent
else (grand)-parents and siblings/cousins of remote-ns are also
included, and mapping the remote-ns prefix fails.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-13 12:07:22 +02:00
7a3e777ded pull/sync: detect remote lack of namespace support
and fall back to only syncing the root namespace, if possible. the sync
job will still be marked as failed to prompt the admin to resolve the
situation:
- explicitly mark the job as syncing *only* the root namespace
- or upgrade remote end to support namespaces

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-12 17:00:38 +02:00
b9310489cf pull/sync: treat unset max-depth as full recursion
to be consistent with tape backup and verification jobs.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-12 17:00:38 +02:00
d9aad37f2f pull: pass params as non-ref in pull_store
so that it's possible to modify them in-place without cloning.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-12 16:26:26 +02:00
2a088b9975 datastore: drop bogus chunk size check, can cause trouble
other sizes can happen in legitimate and illegitimate ways:
 - illegitimate: encryped chunks and bad actor client
 - legitimate: same chunk but newer zstd version (or compression
   level) can compress it better (or worse) so the

Ideally we could take the actual smaller chunk so that improved zstd
tech gets leveraged, but we could only allow to do that for
un-encrypted ones.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 15:41:20 +02:00
78e1ee5230 bump version to 2.1.9-2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 14:28:16 +02:00
c7d42dac97 ui: navigation tree: fix losing datastore selection on store load
instead of using 'replaceChild', simply set the appropriate
properties. When using the 'nodeUpdate' (protected function of extjs,
intended to be overwritten) instead of the private 'updateNode', it
will be called when the properties change

This way, the treenode stays the same and it can keep the selection

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-12 14:28:16 +02:00
8ca7cccf5f file-restore: add namespace support to qemu part
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-12 13:35:34 +02:00
e30a2e9058 ui: content: fix various tree-checks from action handlers
they all still used some odd side effects of the tree structure to
decided what record type they operated on, just move them over to the
new `ty` record.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 13:28:20 +02:00
08982a3746 rest: example: fix comment width
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 11:57:51 +02:00
42fb291c7c cargo fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 11:54:21 +02:00
e9b9f33aee rest server: daemon: update PID file before sending MAINPID notification
There is a race upon reload, where it can happen that:
1. systemd forks off /bin/kill -HUP $MAINPID
2. Current instance forks off new one and notifies systemd with the
   new MAINPID.
3. systemd sets new MAINPID.
4. systemd receives SIGCHLD for the kill process (which is the current
   control process for the service) and reads the PID of the old
   instance from the PID file, resetting MAINPID to the PID of the old
   instance.
5. Old instance exits.
6. systemd receives SIGCHLD for the old instance, reads the PID of the
   old instance from the PID file once more. systemd sees that the
   MAINPID matches the child PID and considers the service exited.
7. systemd receivese notification from the new PID and is confused.
   The service won't get active, because the notification wasn't
   handled.

To fix it, update the PID file before sending the MAINPID
notification, similar to what a comment in systemd's
src/core/service.c suggests:
> /* Forking services may occasionally move to a new PID.
>  * As long as they update the PID file before exiting the old
>  * PID, they're fine. */
but for our Type=notify "before sending the notification" rather than
"before exiting", because otherwise, the mix-up in 4. could still
happen (although it might not actually be problematic without the
mix-up in 6., it still seems better to avoid).

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
2022-05-12 11:53:54 +02:00
f4d246072d ui: avoid ascending to upper NS on double click of current
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 11:48:27 +02:00
15808a9023 ui: add namespace: preselect current NS as parent for new one
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 11:47:14 +02:00
e22ad28302 GC scheduling: avoid triggering operation tracking error for upfront checks
without that one gets a "failed to lookup datastore X" in the log for
every datastore that is in read-only or offline maintenance mode,
even if they aren't scheduled for GC anyway.

Avoid that by first opening the datastore through a Lookup operation,
and only re-open it as Write op once we know that GC needs to get
scheduled for it.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 11:36:56 +02:00
0408f60b58 datastore: add new Lookup for operations tracking
We sometimes need to do some in-memory only stuff, e.g., to check if
GC is already running for a datastore, which is a try_lock on a mutex
that is in-memory.

Actually the whole thing would be nicer if we could guarantee to hold
the correct contract statically, e.g., like
https://docs.rust-embedded.org/book/static-guarantees/design-contracts.html

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 11:36:56 +02:00
d4d730e589 proxy: rrd: skip update disk stats for offline datastores
RDD update did not use lookup_datastore() and therefore bypassed
the maintenance mode checks. This adds the needed check directly.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-05-12 11:36:56 +02:00
5b460ef525 client: add --ns parameters to snapshot commands
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-12 11:02:06 +02:00
03d4f43d5a client: rename --backup-ns to --ns in backup command
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-05-12 10:43:56 +02:00
5225817de6 docs: zfs: update documentation about ZED
This closely follows commit aa425868069818167ff0a3cca5c64a2acc88173e
in pve-docs.

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-12 10:08:30 +02:00
0ae5f76277 docs: local-zfs: minor cleanup and adaptation
fixes a few small glitches in the markup.

rephrases a few PVEisms (PBS will not swap when starting a backup to
an external storage)

add zstd to available compression algorithms

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-12 10:08:30 +02:00
09d903034f docs: system-booting: (re)add screenshots
add the grub+systemdboot screen from a PBS system (taken via
spice-viewer).

The alingment of left/right looked better to me than keeping both on the
right).

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-12 10:08:30 +02:00
9eb804006c docs: add system-booting from pve-docs
and transform to reST.

semantic changes to the content are:
* s/{pve}/`Proxmox Backup`_/g
* changing footnotes to parenthesized notes (did not see footnote use in
  the current docs)
* removed the comment about systems setup before the introduction of
  p-b-t (which was introduced before pbs)

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-12 10:08:30 +02:00
6e3391c85b docs: sysadmin: adapt kernel-specifics for PBS
while all statements here are technically true - adding all
virtualization improvements is not relevant for proxmox backup in most
cases.
The intel nic driver seems like a left-over from a time (pre PVE 5.1)
where the pve-kernel included the out-of-tree drivers.

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2022-05-12 10:08:30 +02:00
71139be203 bump version to 2.1.9-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:48:51 +02:00
fbca018229 ui: content: code cleanups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
7e8b24bd8c ui: content: show namespaces also inline and rework node type detection
this not only makes the action disable/hide checks simpler, but also
prepares the view a bit for the idea of adding a new API endpoint
that returns the whole datastore content tree as structured JSON so
that it can be directly loaded into a tree store.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
fe79687c59 pull group: add error context for cleanup_unreferenced_files
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
9ccf933be5 datastore: move update_manifest into BackupDir impl
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
87cdc327b9 sync: pull snapshot: use template variables for bloat reduction
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
5566099849 datastore: move cleanup_unreferenced_files to BackupDir impl and fix NS awareness
sync failed on cleanup due to always trying to do so in the root NS

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
92b9cc1554 ui: remote target selectors: code cleanups
just a small start...

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
0e3de42aa7 ui: sync job: use namespace selector for localNS
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
8c29bca57c ui: move remote target datastore/ns selectors to own file
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
d895b26bb9 ui: add namespace fields to sync
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:40:43 +02:00
c06c1b4bd7 sync/pull: make namespace aware
Allow pulling all groups from a certain source namespace, and
possibly sub namespaces until max-depth, into a target namespace.

If any sub-namespaces get pulled, they will be mapped relatively from
the source parent namespace to the target parent namespace.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
31aa38b684 ui: verify job: fix add-job on datastore-agnostic level
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
9d8090626c ui: namespace selector: allow to set datastore dynamically
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
6b4d057370 api-types: rework BackupNamespace::map_prefix
to use slice::strip_prefix() from std

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
53d073ec1a datastore: minor cleanup
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
30ccc3003e datastore: relative path fixup
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
bc4af01559 ui: datastore content: make verify-all more flexible
allow to specify the namespace, max_depth and also the re-verify/skip
behavior.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
d83ce0d0c7 ui: fix group backup comment NS awareness
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
ad7741a294 ui: verify job: make namespace and max-depth aware
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
a327f918af ui: add verifyOutdatedAfter component
mainly as separate component for the trigger

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
0b1edf297b verify job: support max-depth config
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
59229bd7f1 api: verify: support namespaces
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
8e82cc807c add ns-recursive and acl/authid aware backup group iter
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
d4037525a8 remote scan/completion: add namespace support
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
40d495de6d api: add DatastoreWithNamespace helper struct
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
d3a570eb79 ui: fix wrong call to htmlEncode
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
9f8fb928f1 ui: add namespace renderer
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
226a4e68da client: add basic namespace commands
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
473063e9ec api: ns management: fix permission checks
we do not have normal GET variables available in the checks provided
by the rest server from the api macro, so do it manually.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
93b0659ff2 ui: datastore: more NS awareness
verify is actually not yet ready in the backend

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
e8112eb37b ui: datastore content: show root node for better UX with NS
that way it's easier to see on which NS one currently operates and
allows better distinguishing of root NS and some sub ns named "Root"

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
6f5753cfa3 api-types: allow empty namespace
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
3c09413a0a client: don't pass empty backup-ns
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
028346e42c ui: content view: improve empty text
reference NS so that users get a hint where they are currently
hierarchy-wise, and clarify that we found no *accessible* snapshots,
on this level, i.e., there can be some that we just cannot see due to
only having access on lover level NS or being different owners.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
bc06c7b4e9 api: namespace: return popped component
helpful for places where namespaces need to be (re)created

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
7a404dc53d api: datastore: further unify check helpers
this is the most common sequence of checks we have in this file, so
let's have a single place where we implement it.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
c939698414 api: datastore: load datastore & check owner helper
these happen together very often.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
1909ece229 api: datastore: lookup after checking privs
else this could leak existence of datastore.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
2bc2435a96 api: datastore: refactor priv checks
the helper now takes both high-privilege and lesser-privilege privs, so
the resulting bool can be used to quickly check whether additional
checks like group ownership are needed or not.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
a724f5fd47 api: datastore: unify access checks
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
133d718fe4 split the namespace out of BackupGroup/Dir api types
We decided to go this route because it'll most likely be
safer in the API as we need to explicitly add namespaces
support to the various API endpoints this way.

For example, 'pull' should have 2 namespaces: local and
remote, and the GroupFilter (which would otherwise contain
exactly *one* namespace parameter) needs to be applied for
both sides (to decide what to pull from the remote, and what
to *remove* locally as cleanup).

The *datastore* types still contain the namespace and have a
`.backup_ns()` getter.

Note that the datastore's `Display` implementations are no
longer safe to use as a deserializable string.

Additionally, some datastore based methods now have been
exposed via the BackupGroup/BackupDir types to avoid a
"round trip" in code.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
1baf9030ad ui: datastore prune: support passing namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
2f5417f845 prune: allow passing namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
a7f5e64154 ui: datastore content: allow to create new namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
55ffd4a946 ui: utils: also provided me.SAFE_ID_RE
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
94135ccca2 ui: datastore content: allow to select namespace to show
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
968270ae3d ui: add namespace selector combobox
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
d45506d4a4 api: backup create: enforce that namespace exists
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
cabda57f0a api: backup create: make permission check namespace aware
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
7d6fc15b20 api: datastore: make permission checks namespace aware
We probably can combine the base permission + owner check, but for
now add explicit ones to upfront so that the change is simpler as
only one thing is done.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
18934ae56b api: namespace management endpoints
allow to list any namespace with privileges on it and allow to create
and delete namespaces if the user has modify permissions on the parent
namespace.

Creation is only allowed if the parent NS already exists.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
15a9272495 datastore: add max-depth to recursive namespace iter
on depth == 0 we only yield the anchor ns, this simplifies usage in
the API as for, e.g. list-snapthos the depth == 0 means only the
snapshots from the passed namespace, nothing below.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
08aa5fe7aa api: add NS_MAX_DEPTH_SCHEMA
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
 [ T: renamed from NAMESPACE_RECURSION_DEPTH_SCHEMA & moved to from
   jobs to datastore ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
e687d1b8ee api: add prefix-mapping helper to BackupNamespace
given a namespace, a source prefix and a target prefix this helper
strips the source prefix and replaces it with the target one (erroring
out if the prefix doesn't match).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
c12a075b83 api: derive UpdaterType for BackupNamespace
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
c5648f1920 config: acl tree: allow path components to be paths too
will be used for namespaces

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
dc3d716bdb datastore: add create_namespace
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
6dd8a2ced0 BackupNamespace: fix deserialize of root NS
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
be5b3ebfdd api-types: fixup backup-ns being optional
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
c18d481fd7 pbs-client: don't include empty backup-ns in requests
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
68857aecb3 client: add --ns parameter to snapshot list
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
352e13db9d api types: BackupNamespace add pop & parent helpers
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
220b66077c api-types: more regex fixups
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
2772159692 api-types: add missing slash in optional ns path regex
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
89ae3c3255 client: more backup namespace support
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
13d6de3787 datastore: include namespace in full_path
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
33f2c2a1bf api: add remaining missing backup-ns parameters
these are the ones for non-#[api] methods, also fill in the
namespace in prune operations

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
4c7cc5b39e datastore: add helpers to destroy whole namespaces
The behavior on "any snapshot was protected" isn't yet ideal, as we
then do not cleanup any (sub) namespace, even if some of them where
cleaned from groups & snapshots completely. But that isn't easy to do
with our current depth-first pre-order iterator behavior, and it's
also not completely wrong either, the user can re-do the removal on
the sub-namespaces, so leave that for later.

Should get moved to a datastore::BackupNamespace type once/if we get
one

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
90e3869690 datastore: add single-level and recursive namespace iterators
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
02ec2ae9b8 api types: namespace: add from_parent_ns helper
will be used in the (recursive) namespace iterator

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
c2425132c4 api types: namespace: include problematic component in error
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
11ffd737e3 datastore: add backup_ns accessor
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
8c74349b08 api-types: add namespace to BackupGroup
Make it easier by adding an helper accepting either group or
directory

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
42103c467d ns: max depth: set constant to upper inclusive boundary
makes usage a bit simpler, e.g., the api maximum can use that 1:1
then.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
b68bd900c1 api-types: add BackupNamespace type
The idea is to have namespaces in a datastore to allow grouping and
namespacing backups from different (but similar trusted) sources,
e.g., different PVE clusters, geo sites, use-cases or company
service-branches, without separating the underlying
deduplication domain and thus blowing up data and (GC/verify)
resource usage.

To avoid namespace ID clashes with anything existing or future
usecases use a intermediate `ns` level on *each* depth.

The current implementation treats that as internal and thus hides
that fact from the API, iow., the namespace path the users passes
along or gets returned won't include the `ns` level, they do not
matter there at all.

The max-depth of 8 is chosen with the following in mind:
- assume that end-users already are in a deeper level of a hierarchy,
  most often they'll start at level one or two, as the higher ones
  are used by the seller/admin to namespace different users/groups,
  so lower than four would be very limiting for a lot of target use
  cases

- all the more, a PBS could be used as huge second level archive in a
  big company, so one could imagine a namespace structure like:
  /<state>/<intra-state-location>/<datacenter>/<company-branch>/<workload-type>/<service-type>/
  e.g.: /us/east-coast/dc12345/financial/report-storage/cassandra/
  that's six levels that one can imagine for a reasonable use-case,
  leave some room for the ones harder to imagine ;-)

- on the other hand, we do not want to allow unlimited levels as we
  have request parameter limits and deep nesting can create other
  issues as well (e.g., stack exhaustion), so doubling the minimum
  level of 4 (1st point) we got room to breath even for the
  more odd (or huge) use cases (2nd point)

- a per-level length of 32 (-1 due to separator) is enough to use
  telling names, making lives of users and admin simpler, but not
  blowing up parameter total length with the max depth of 8

- 8 * 32 = 256 which is nice buffer size

Much thanks for Wolfgang for all the great work on the type
implementation and assisting greatly with the design.

Co-authored-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Co-authored-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
77337b3b4c api types: BackupType: add iter for enum
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-12 09:33:50 +02:00
b6c8717cc2 completion: fix 'group-filter' parameter name
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-10 12:06:34 +02:00
dfea916ca7 proxmox-backup-manager: add limit to pull
seems to have been forgotten initially.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-10 11:54:50 +02:00
d49025064c datastore: chunk store: leverage new format str variable reference
makes it often compact enough for rustfmt to move it into a single
line

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-10 09:46:51 +02:00
dd612daab0 chunk_store: insert_chunk: write chunk again if it is empty on disk
and issue a warning. We can do this, because we know an empty chunk
cannot be valid, and we (assumedly) have a valid chunk in memory.

Having empty chunks on disk is currently possible when PBS crashes,
but the rename of the chunk was flushed to disk, when the actual data
was not.

If it's not empty but there is a size mismatch, return an error.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-10 08:47:40 +02:00
8915c1e74a api: tape/restore: skip snapshot if owner check failed
instead of aborting the whole restore

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-09 13:56:16 +02:00
c94d2867c1 api: tape/restore: fix wrong datastore locking
used_datastores returned the 'target', but in the full_restore_worker,
we interpreted it as the source and searched for a mapping
(which we then locked)

since we cannot return a HashSet of Arc<T> (missing Hash trait on DataStore),
we have now a map of source -> target

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-05-09 13:37:03 +02:00
0b232f2edc drop mut on some http client usages
thanks to commit 70142e607dda43fc778f39d52dc7bb3bba088cd3 from
proxmox repos's proxmox-http crate

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-05 10:50:51 +02:00
2c64201e64 update proxmox-http b-d to 0.6.1
so that we can drop some mut on http client usages

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-05 10:50:49 +02:00
41c1a17999 router change made one level of rpcenv mut superfluous
Created via `cargo fix`.  see commit
47acc8dc8f68ed2c5db69b1678b479e05b0a3194 from proxmox-rs

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-05 10:00:29 +02:00
aefbaa4dc6 update proxmox-router b-d to 1.2.2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-05 09:54:18 +02:00
60ed7aeae6 bump version to 2.1.8-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-02 17:36:22 +02:00
29c56859b0 pull: add some comments
and remove already fixed fixmes.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
 [ T: squash in cargo fmt fixup for some trailing ws ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-02 14:10:26 +02:00
aa07391764 pull: remove unnecessary pub visibility
pull_store is the entrypoint used by other code, the rest does not need
to be visible at all.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-02 14:09:56 +02:00
df768ebea9 pull: filter local removal candidates by owner
else this might remove groups which are not part of the pull scope. note
that setting/using remove_vanished already checks the required privs
earlier.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-05-02 14:09:56 +02:00
20814a3986 proxmox-backup-proxy: stop accept() loop on daemon shutdown
On reload the old process hands over to the new process but needs to
keep running until all its worker tasks are finished to avoid
breaking a in-progress action like a xterm.js web shell or a backup
creation/restore.

During that wait time the receiving channel was already closed, but
the TCP sockt accept listener was still left active by mistake.

That paired with the `SO_REUSEPORT` being set on the underlying
socket, made the kernel choose either the old or new process for new
incoming connections, both still listened for them after all and
reuse-port + multiple processes is often used as load-balancer
mechanism.

As the old proxy accepted connections but didn't process them anymore
one could observer sporadic connection failures on any API call, well
any new connection to the proxy, depending on which process got the
it assigned.

The fix is to stop accepting new connections one we shutdown, so poll
the shutdown_future too during accept and just exit the accept-loop
on shutdown.

Note: This part of the code, nor other parts that could influence it,
wasn't changed at all in recent times, so it's still unresolved for
why it pops up only now.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Co-authored-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
 [ T: add more (root cause) info and reword a bit ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-02 10:31:33 +02:00
8550de7403 api: status: return gc-status again
Returning the GC status was dropped by mistake in commit 762f7d15
("datastore status: factor out api type DataStoreStatusListItem")

As this is considered a breaking change which we also felt, due to
the gc-status being used in the web interface for the datastore
overview list (not the dashboard), re add it.

Fixes: 762f7d15
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [ T: add reference to breaking commit, reword message ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-05-02 10:11:01 +02:00
0f198b82f5 cargo fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-28 10:26:00 +02:00
a0781d7b9e bump version to 2.1.7-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-27 19:54:28 +02:00
f732942089 ui: add tooltip to datastore in maintenance mode
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-27 19:21:19 +02:00
1b7479c968 ui: utils: add function for parsing maintenance mode
...since the same code is used is more than one place

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-27 19:21:19 +02:00
fbd6f54f39 ui: update datastore list more often
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-27 19:21:19 +02:00
adf5dcba8d ui: update icon in datastore list when in maintenance mode
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-27 19:21:19 +02:00
e022d13cf3 api2: DataStoreListItem add maintenance info
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-27 19:21:19 +02:00
dd09432a90 ui: add summary mask when in maintenance mode
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-27 19:21:19 +02:00
6ddd69c5ce file-restore: add 'timeout' and 'json-error' parameter
timeout limits the code with the given timeout in seconds, and
'json-error' return json to stdout when the call returns an error like
this:

{
    "msg": "error message",
    "error": true,
    "code": <HTTP_STATUS_CODE>, // if it was an http error
}

with both options set, a client can more easily determine if the call
ran into a timeout (since it will return a 503 error), and can poll
it again

both is done behind new parameters, so that we can stay backwards-compatible

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-27 19:19:57 +02:00
25be1fa0d7 file-restore: factor out 'list_files'
we'll want to reuse that in a later patch

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-27 19:19:57 +02:00
8eaa46ffea restore-daemon: avoid auto-mounting zpools
the duration of mounting zpools not only correspond to the number of disks,
but also to the content (many subvols for example) which we cannot know
beforehand. so avoid mounting them at the start, and mount it only when
the user requests a listing/extraction with the zpool in path

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-27 19:19:57 +02:00
4d76ab91e4 restore-daemon: put blocking code into 'block_in_place'
DISK_STATE.lock() and '.resolve()' can both block since they access
the disks. Putting them into a 'block_in_place' makes tokio move it
out in its own thread to avoid that the executor isn't able to
progress any other futures in the mean time.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-27 19:18:44 +02:00
436a48d611 restore-daemon: start disk initialization in parallel to the api
this way, the vm can start up faster, and the actual disk init happens
in parallel. this avoids unnecessary timeouts when starting the vm

if the call panics, we still abort the vm with an error

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-27 19:18:44 +02:00
274ac755a1 api types: datastore status: reword doc comment of estimated_full_date
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-25 11:48:25 +02:00
579362f743 ui: update generated OnlineHelpInfo map
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-25 10:17:21 +02:00
f3b02a9b86 fix #3067: ui: add a separate notes view for longer markdown notes
since markdown notes might be rather long, this commit adds a tab
similar to pve's datacenter or node notes. requires a bump of the
widget toolkit in order to use the `pmxNotesView`.

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
2022-04-25 08:39:39 +02:00
684a402931 fix #3067: docs: add markdown primer from pve to pbs
this copies the markdown primer from the pve docs to allow access to
it via the help buttons in the gui

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
2022-04-25 08:39:39 +02:00
1eef52c206 datastore: move blob loading into BackupDir impl and adapt call sites
data blobs can only appear in a BackupDir (snapshot) in the backup
hierachy, so makes more sense that it lives in there.

As it wasn't widely used anyway it's easy to move the single
non-package call site over to the new one directly and drop the
implementation from Datastore completely.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 20:16:58 +02:00
f03649b8f3 datastore: move destroying group or dir into respective impl
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 20:14:39 +02:00
5c9c23b6b2 datastore: move manifest locking into BackupDir impl
the manifest is owned by the backup dir (snapshot) so it should also
handle locking, makes no sense to have the implementation somewhere
higher up.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 20:10:43 +02:00
b298e9f16e datastore: s/fail_if_not_exist/assert_exists/
avoid putting whole sentences in parameter names

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 20:10:34 +02:00
cc295e2c7a datastore: improve backup group/snapshot iters
move the check for directory before doing the OSString -> String
conversion, which should be a bit more efficient.

Also let the match return the entry in the non-skip/return case to
reduce indentation level for the inner "yield element" part, making
it slightly easier to follow.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 20:02:58 +02:00
4b77d300a2 datastore: replace manual path assembly by group/dir full_path
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 19:57:20 +02:00
df5c6a11cd datastore: list snapshots iter: report group dir in error
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-24 19:57:10 +02:00
07a683d266 pbs-client: extract: add top-level dir in tar.zst
when download a folder, include that folder as first entry (except '/')

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-04-22 11:35:55 +02:00
7098f5d885 pbs-client: extract: rewrite create_zip with sequential decoder
instead of an async recursive function. Not only is it less code,
recursive futures are not really nice and it should be faster too.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-04-22 11:35:53 +02:00
f37d8540e1 server pull: fix comment w.r.t. initial downloaded chunk capacity
> The hash set will be able to hold at least capacity elements
> without reallocating. If capacity is 0, the hash set will not
> allocate.
-- rustdoc, HashSet::with_capacity

So, the number we pass is the amount of chunk "IDs" we safe, which is
then 64Ki, not 16Ki and thus the size we can reference too is also
256 GiB, not 64 GiB.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-21 15:55:03 +02:00
eb1cd24e21 pbs-tape: sgutils2: check sense data when status is 'CHECK_CONDITION'
Some raid controllers return a 'transport error' when we expected a
'sense error'. it seems the correct way to check the sense data is when
either the result category is 'SENSE' or when the status is 'CHECK_CONDITION',
so do that. (similar to how 'sg_raw' returns the errors)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-04-21 09:35:52 +02:00
6da20161f0 reference the datastore in BackupGroup/Dir
And drop the base_path parameter on a first bunch of
functions (more reordering will follow).

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 15:31:04 +02:00
bb628c295a api-types: DataStoreConfig::new for testing
so our examples can more easily access a datastore without
going over a configuration & cache

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 15:31:04 +02:00
2c88dc97fd api2: read_remote: also return RemoteWithoutPassword
like for the index, instead of manually stripping it.

this (and the previous change) is backwards-compatible since `Remote`
already skipped serializing empty strings, so the returned JSON is
identical.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-04-20 13:58:41 +02:00
6b0c6492f7 datastore: cleanup and document backup group/dir openers
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 13:24:57 +02:00
10a0059602 datastore: drop Hash from BackupGroup
same as for Eq/Ord/...

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 13:08:44 +02:00
5203cfcff9 datastore: drop PartialEq and PartialOrd from BackupGroup
Same as previous commits: this will be linked to a
particular DataStore and Eq/Ord is now only part of the
api types, for now.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 12:23:14 +02:00
cf320b6ba1 datastore: drop Eq and PartialEq from BackupDir
Same as previous commit: this is supposed to be connected to
a datastore and Eq/PartialEq only make sense for the
api-type part.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 12:22:57 +02:00
5116453b6d datastore: drop Ord from BackupGroup
This one is supposed to be linked to a datastore instance,
so it won't be Ord for now.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 12:20:30 +02:00
db87d93efc make datastore BackupGroup/Dir ctors private
And use the api-types for their contents.

These are supposed to be instances for a datastore, the pure
specifications are the ones in pbs_api_types which should be
preferred in crates like clients which do not need to deal
with the datastore directly.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 11:56:23 +02:00
38aa71fcc8 api-types: use BackupType for GroupFilter::BackupType
instead of a string

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 11:49:01 +02:00
1f6a45c938 rename BackupDir's group_path to relative_group_path
datastore's group_path will be moved to BackupDir soon and
this is required to be able to properly distinguish them

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 10:04:02 +02:00
b444eb68af api-types: datastore type improvements
let BackupGroup implement Hash

let BackupGroup and BackupDir be AsRef<BackupGroup>
let BackupDir be AsRef<BackupDir>

the pbs-datastore types will implement these AsRefs as well

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 10:03:39 +02:00
2d5c20c8f5 datastore: remove unused list_files function
it also doesn't belong into this type

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 10:00:33 +02:00
c4b2d26cdb datastore: move last_backup from BackupInfo to BackupGroup
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-20 10:00:25 +02:00
fe94c9962e AuthId: derive Ord and PartialOrd
So the we can sort...

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-04-20 09:58:52 +02:00
24cb5c7a81 RemoteWithoutPassword: new API type
To make it explicit that we do not return the password.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-04-20 09:42:46 +02:00
988d575dbb api-types: introduce BackupType enum and Group/Dir api types
The type is a real enum.

All are API types and implement Display and FromStr. The
ordering is the same as it is in pbs-datastore.

Also, they are now flattened into a few structs instead of
being copied manually.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 13:12:46 +02:00
33eb23d57e datastore: add snapshot iterator and provide example
will be more used in the future, when the upend-datastore master plan
comes in effect.

also a preparatory work for namespaces

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
249dde8b63 backup: switch over to streaming Iterator improving memory usage
Avoid collecting the whole group list in memory only to iterate and
filter over it again.

Note that the change could result in a indentation change, so best
viewed with `-w` flag.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
7b125de3e1 datastore: add helper to get a iterator for backup groups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
de015ce7e1 datastore: implement Iterator for backup group listing
While currently it's still only used in a collected() way, most call
sites can be switched over to use the iterator directly, as often
they already convert the not-so-cheap, in-memory vector back in
.into_iter() anyway.

somewhat also preparatory (yak shaving) work for namespaces

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
72f8154571 api datastore: some code cleanups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
693f3285eb datastore: backup info: drop deprecated list_backup_groups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
7d9cb8c458 replace deprecated list_backup_group from BackupInfo with Datastore one
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
c90dbb5c7b datastore: move list_backup_groups into Datastore impl
Having that as static method in BackupInfo makes zero sense and just
complicates call sites, which need to extract the base_path from the
store manually upfront.

Mark old fn as deprecated so that we can do the move in a separate
step.

It's also planned to add an Iterator impl for this to allow more
efficient usage in the future.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-15 12:38:16 +02:00
bdfa637058 client: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 14:25:05 +02:00
f9a5beaa15 backup client: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 14:06:15 +02:00
00ae34dfda tools: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 14:05:17 +02:00
9531d2c570 rust fmt for pbs src
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 14:03:46 +02:00
ee0ea73500 server: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 14:01:25 +02:00
dc7a5b3491 api: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 13:33:01 +02:00
35f151e010 config: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 13:32:04 +02:00
42c2b5bec9 datastore: rustfmt whole package
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 13:27:53 +02:00
fb3c007f8a d/changelog: fixup released
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-14 09:48:00 +02:00
ff7568f1d9 bump version to 2.1.6-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-13 17:31:21 +02:00
1fd46218ea cli: tape key-restore: print more info for better ux
as getting the marker error if we passed valid json (but not valid
key) is confusing

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-13 16:59:47 +02:00
ede9dc0d1a api: tape key restore: fix optional param handling and code refactoring
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-13 16:59:47 +02:00
ae60eed310 proxmox-tape: api: restore_key-code moved to tape-encryption-keys
The restore_key api-endpoint is tape/drive/{drive}/restore-key.
Since I cannot set the url parameter for the drivename to null or
undefined, when restoring by exported-key, I moved the
added restore_key-api-code to
"create_key aka POST api2/json/config/tape-encryption-keys" and
added an ApiHandler call in the cli's "restore_key" to call
"create_key" in the api.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
2022-04-13 16:31:17 +02:00
e3746a329e pbs-client: pxar: avoid some more clones
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:30:40 +02:00
7546e9c997 pbs-client: pxar: avoid some vec extensions
The `Components` `Iterator` has an `as_path()` method to get
the remainder as a borrowed path. This is more efficient
iterating and joining the components into a new `PathBuf`.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:28:01 +02:00
0bb4036f25 pbs-client: pxar: drop link_to_pathbuf
pxar's Hardlink and Symlink structs implement `AsRef<OsStr>`
and have an `.as_os_str()` method.

Simply use `Path::new(link)`.

Also, the function was not very well written, and we don't
always need an owned copy.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:18:31 +02:00
84d3af3a0e pbs-client: pxar: fmt
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:17:20 +02:00
055eab54ff ui: datastore/Content: enable tar download in ui
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:08:34 +02:00
984ddb2ff2 api: admin/datastore: add tar support for pxar_file_download
by using the newly added 'create_tar' and the 'ZstdEncoder'

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:08:26 +02:00
23af572d3f pbs-client: add 'create_tar' helper function
similar to create_zip, uses an accessor to write a tar into an output
that implements AsyncWrite, but we use a Decoder to iterate instead
of having a recursive function. This is done so that we get the
entries in the correct order, and it should be faster as well.

Includes files, directories, symlinks, hardlink, block/char devs, fifos
into the tar. If the hardlink points to outside the current dir to
archive, promote the first instance to a 'real' file, and use a
hardlink for the rest.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 10:05:08 +02:00
99f09fd3c1 bump proxmox-compression dependency to 0.1.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 09:37:20 +02:00
da7a71115c bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 08:21:18 +02:00
ebb85c1ca3 bump proxmox-schema dependency to 1.3.1 for streaming attribute
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 08:20:27 +02:00
fb6e48f402 bump proxmox-router dependency to 1.2
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 08:17:08 +02:00
b7c3eaa981 api: admin/datastore: enable streaming for some api calls
namely /admin/datastore/{store}/snapshots
and /nodes/{node}/tasks

since those are api calls where the result can get quite large
with this change, the serialization is now streaming instead of making
a `Value` in memory.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 08:13:42 +02:00
32e2b5abe6 adapt to the new ApiHandler variants
namely 'StreamingSync' and 'StreamingAsync'
in rest-server by using the new formatter function,
and in the debug binary by using 'to_value'

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 08:13:40 +02:00
2ef2c0fe0c proxmox-rest-server: OutputFormatter: add new format_data_streaming method
that takes the data in form of a `Box<dyn SerializableReturn + Send>`
instead of a Value.

Implement it in json and extjs formatter, by starting a thread and
stream the serialized data via a `BufWriter<SenderWriter>` and use
the Receiver side as a stream for the response body.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-13 08:13:36 +02:00
9c3b29bd8f ui: datastore options: maintenance mode related refactorings
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-12 16:54:56 +02:00
3c8f240712 ui: datastore options: fix active-ops-tracking store leak
without this the store stayed active in the background and kept
updating every 3s for every datastore the ui was opened.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-12 16:21:41 +02:00
6353e22c00 ui: datastore options: factor out update stop/start to controller
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-12 16:18:43 +02:00
38774184a9 tree-wide: replace serde_json::from_value(a_value.clone())
`&Value` itself implements `Deserializer` and can therefore
be passed directly to `T::deserialize` without requiring an
intermediate `clone()`. (This also enables optionally
borrowing strings if the result has a short enough lifetime)

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-12 16:12:15 +02:00
845baef61b ui: maintenance mode: also render message
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-12 16:12:15 +02:00
73ce2ae1c7 ui: maintenance mode: refactor renderer
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-12 16:12:12 +02:00
556eda0537 ui: add option to change the maintenance type
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-12 15:29:14 +02:00
5fd823c3f2 api: add get_active_operations endpoint
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-12 15:29:14 +02:00
758c6ed588 api: make maintenance_type updatable
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-12 15:29:14 +02:00
4bc84a6549 pbs-datastore: add active operations tracking
Saves the currently active read/write operation counts in a file. The
file is updated whenever a reference returned by lookup_datastore is
dropped and whenever a reference is returned by lookup_datastore. The
files are locked before every access, there is one file per datastore.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-12 15:29:14 +02:00
e9d2fc9362 datastore: add check for maintenance in lookup
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-12 15:29:14 +02:00
2a05c75ff1 api-types: add maintenance type
+ bump proxmox-schema dep to 1.2.1 (for quoted property string)

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-04-12 15:29:14 +02:00
66b88dadba ui: node config: avoid split listeners
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-12 15:29:03 +02:00
9ee2ef2e55 client: drop unnecessary clone
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-12 12:34:52 +02:00
12558e0dde tree wide: some stylistic clippy fixes
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-11 08:14:28 +02:00
b22d785c18 api types: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-10 18:00:18 +02:00
4ad118c613 cli: backup manager: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-10 17:50:35 +02:00
6082d75966 tests: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-10 17:49:26 +02:00
4de1c42c20 tape: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-10 17:49:03 +02:00
429bc9d0a2 restore daemon: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-10 17:47:20 +02:00
a22d338831 examples: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-10 17:44:34 +02:00
1e724828b4 rest server: log rotation: refactor and comment improvements
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-07 14:04:18 +02:00
40853461d1 rest server: log rotation: fix off-by-one for max_days
The entries in a file go from oldest end-time in the first time to
newest end-time in the last line. So, just because the first line is
older than the cut-off time, the remaining one doesn't necessarily
have to be old enough too. What we can know for sure that older than
the current checked rotations of the task archive are definitively up
for deletion.

Another possibility would be to check the last line, but as scanning
backwards is more expensive/complex to do while only being an actual
improvement in a very specific edge case (it's more likely to have a
mixed time-cutoff vs. task-log-file boundary than that those are
aligned)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-07 12:58:32 +02:00
416194d799 rest-server: add option to rotate task logs by 'max_days' instead of 'max_files'
and use it with the configurable: 'task_log_max_days' of the node config

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-04-06 17:12:49 +02:00
eb419c5267 config/node: add 'task_log_max_days' config
to be able to configure the maximum days to keep task logs

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-04-06 17:10:02 +02:00
baefc29544 rest-server: cleanup_old_tasks: improve error handling
by not bubbling up most errors, and continuing on. this avoids that we
stop cleaning up because e.g. one directory was missing.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-04-06 17:10:02 +02:00
b23adfd4ee pbs tape: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 17:00:29 +02:00
a527b54f84 pbs fuse loop: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:59:54 +02:00
b2df21bb02 docs: client: file exclusion: add note about leading slash
It's not documented yet and not intuitive:
https://forum.proxmox.com/threads/98810
https://forum.proxmox.com/threads/107143

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
2022-04-06 16:59:00 +02:00
2b323a359d pxar: create: add entry: fix anchored path pattern matching
Similar to 874bd545 ("pxar: fix anchored exclusion at archive root"),
but this time for inclusion. Because of the inconsistency, it could
happen that a file included in generate_directory_file_list() got
excluded in add_entry(), e.g. with a .pxarexclude file like
> *
> !/supposed-to-be-included

Reported-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
2022-04-06 16:58:08 +02:00
48fcee6a50 pxar bin: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:58:04 +02:00
c650378a39 pbs build config: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:57:36 +02:00
40ea990c05 file restore: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:57:07 +02:00
aaaa10894d rrd: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:56:33 +02:00
41583796b1 rest server: rust fmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:55:39 +02:00
b300e6fbc2 use BufReader/Writer for Files passed to serde_json::from_reader/writer
As serde_json will otherwise read files 1 byte at a time.
Writing is a bit better, but syntacitcal elements (quotes, braces,
commas) still often show up as single write syscalls, so use BufWriter
there as well.

Note that while we do store the file in the resulting objects, we do not
need to keep the buffered read/writers as we always `seek` to the
beginning on further file operations.

Reported-by: Mark Schouten <mark@tuxis.nl>
Link: https://lists.proxmox.com/pipermail/pbs-devel/2022-April/004909.html
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-04-06 16:40:35 +02:00
085ae87380 api: tape: rust format
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:31:49 +02:00
938a1f137c cli: tape: rust format
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:27:32 +02:00
5525ec246f tape: key recovery: refcator and split string/file case for cli params
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-04-06 16:25:34 +02:00
b676dbce78 fix #3854 paperkey import to proxmox-tape
added a parameter to the cli for importing tape key via a json-parameter or
via reading a exported paperkey-file or json-file.
For this i also added a backupkey parameter to the api, but here it only
accepts json.

The cli interprets the parameter first as json-string, then json-file
and last as paperkey-file.

functionality:
proxmox-tape key paperkey [fingerprint of existing key] > paperkey.backup
proxmox-tape key restore --backupkey paperkey.backup # key from line above
proxmox-tape key restore --backupkey paperkey.json # only the json
proxmox-tape key restore --backupkey '{"kdf": {"Scrypt": ...' # json as string

for importing the key as paperkey-file it is irrelevant, if the paperkey got exported as html
or txt.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
2022-04-06 13:39:56 +02:00
7c22932c64 pbs-client: print error when we couldn't download previous fidx/didx
When we have a previous manifest, we try to download the fidx/didx files
to get the known chunks list. We continue if that fails (which is ok),
but we did not print any error, leading to a confusing backup output,
since the users would expect that chunks will be reused.

Printing the error should at least make it apparent that something did
not work correctly.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-04-06 10:12:29 +02:00
2b422b82fb fix #3067: api: add support for multi-line comments in node.cfg
add support for multi-line comments to node.cfg and the api, similar to
how pve handles multi-line comments

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
Acked-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-23 10:43:43 +01:00
9e2b423e27 tools: improve PhantomData usage
The ticket doesn't contain a `T`, it's stringified. We only
produce a new T when verifying.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-22 12:41:14 +01:00
39ffb75d91 api: datastore_status: restore api/gui compatibility
the latest changes to this api call changed/removed some things that
were actually necessary for the gui. Readd those and document them this
time.

The change from u64 to i64 limits us to 8EiB of Datastore sizes (instead if
16EiB) but if we reach that, we must adapt most other parts to use 128bit
sizes anyway

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-03-22 10:31:25 +01:00
762f7d15dc datastore status: factor out api type DataStoreStatusListItem
And use the rust type instead of json::Value.
2022-03-20 09:38:50 +01:00
80ab05e40c fix #3934 tape owner-selector to Authid
changed pmxUserSelector to pbsAuthidSelector, because it is currently
not possible to restore with a api token via gui.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
2022-03-17 10:13:18 +01:00
e099bd0717 ui: fix panel height in the dashboard
this fixes an issue where the layout looks misaligned in three column
layouts

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
2022-03-11 12:52:50 +01:00
171a00ca97 tape, docs, api: fix miscellaneous typos
Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-03-11 12:52:06 +01:00
c8322f8a33 config: don't manually track padding size
make ConfigVersionCacheData a #[repr(C)] union to fix its
size and let it transparently `Deref{,Mut}` to its actual
contents

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-10 10:32:46 +01:00
eb080f361a docs: tape: minor wording tweaks
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-03-09 10:44:37 +01:00
bd0300917e docs: improve tape-backup examples
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-03-09 10:44:37 +01:00
787c6550d4 proxmox-backup-debug api: fewer cloning
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-09 10:10:54 +01:00
c6140c62ab proxmox-backup-debug api: rustfmt fixes
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-09 10:10:54 +01:00
9735f5de84 proxmox-backup-debug api: parse parameters before sending to api
when we use http to make the api call, we have to parse the parameters
before, else we might send the string "true" instead of the boolean true
and the api rejects it with a 'Parameter verification error'.

We already have all api call schemas here, so parsing is possible.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-09 10:10:54 +01:00
a07ace0d1e regex: bump to 1.5.5
to ensure CVE fix for DoS on untrusted RE is picked up where it matters

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-03-09 09:55:36 +01:00
904ce33d9f tools: parse_objset_stat: drop the unecessary 'objset-' from the log
'objset_id' already contains that, so the error was
"could not parse 'objset-objset-0xFFFF' stat file"

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-08 09:13:05 +01:00
6dd5944772 tools: zfs_dataset_stats: remove dataset <-> obset file mapping on error
this can only real fail for two reasons:
* the format is wrong:
    this should not happen unless the format changed, then it will
    happen every time
* the file can't be read:
    this can happen if a user deletes and recreates a dataset manually,
    since the mapped file does not exist anymore but the dataset does

for the second case, delete the mapping from the hashmap, so that the
next call will refresh the mapping with the correct file

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-08 09:12:52 +01:00
dcd1518e10 api/config: use http_bail for 'not found' errors
the api should return a 404 error for entries that do not exist

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-08 09:09:25 +01:00
8d6425aa24 api/config: use param_bail for parameter errors
when using the 'extjs' formatter, it marks them in a way, so that
the gui can mark the form fields with the error

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-08 09:09:22 +01:00
4042eedf18 Username schema: set min_length to 1
Just to get a better error message (the regex already requires min_length 1)

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-03-07 13:47:06 +01:00
1c8efc0062 cleanup: move BasicRealmInfo to pbs-api-types
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-03-07 08:06:55 +01:00
a9a15a9ab4 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-04 09:53:41 +01:00
bd4562e4b1 bump proxmox-schema dep to 1.3
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-03-04 09:50:21 +01:00
e1f9553f2d pbs-config: improve semi-useful comment
commenting that version_cache.increase_datastore_generation increases
the, well, version is rather superfluous. Also avoid the use of "we",
which is always ambiguous in code comments.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-03-01 09:54:39 +01:00
118deb4db8 pbs-datastore: use ConfigVersionCache for datastore
instead of relying on the content of some configs

previously, we always read and parsed the config file, and only
generated a new config object when the path or the 'verify-new' option
changed.

now, we increase the datastore generation on config save, and if that
changed (or the last load is 1 minute in the past), we always
generate a new object

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-03-01 08:16:27 +01:00
9c96e5368a docs: add tape schedule examples
just a few examples how one could configure tape pools and jobs.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-03-01 08:10:53 +01:00
83b5076dce docs: explain retention time for event allocation policy in more detail
'when the calendar event' triggers was too vague, it could mean for
the current media-set or the next time. Apart from that, it was not
technically correct all the time, since we take the start time of
the next media set if that exists first.

The idea here is that we begin the retention when the media set is
finished.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-03-01 08:08:18 +01:00
fef61684b4 datastore: add tuning option for chunk order
currently, we sort chunks by inode when verifying or backing up to tape.
we get the inode# by stat'ing each chunk, which may be more expensive
than the gains of reading the chunks in order

Since that is highly dependent on the underlying storage of the datastore,
introduce a tuning option  so that the admin can tune that behaviour
for each datastore.

The default stays the same (sorting by inode)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-02-23 09:06:03 +01:00
118f8589a9 client cli: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-22 11:50:46 +01:00
c2f84841b6 bin: daily-update: use syslog/log crates instead of printing to stderr
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-22 10:58:44 +01:00
b0728103b6 bin: daily-update: make single checks/updates fail gracefully
avoid that the acme renewal is skipped due to bailing out earlier
from a subscription or apt update error.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-22 10:27:00 +01:00
00d41438b9 bin: daily-update: use from_millis instead of big nanosecond value
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-22 10:25:40 +01:00
50654b22df bin: daily-update: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-21 15:52:28 +01:00
d96c7da31f bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-21 14:25:54 +01:00
9c890d72b9 bump proxmox-async dep to 0.4
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-21 14:25:37 +01:00
229c1788c1 bump proxmox-lang dep to 1.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-21 14:24:24 +01:00
f26d7ca5c5 use io_format_err, io_bail, io_err_other from proxmox-lang
and move the comment from the local io_bail in pbs-client/src/pxar/fuse.rs
to the only use

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-21 14:24:13 +01:00
b066586a47 depend on new 'proxmox-compression' crate
the compression utilities live there now

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-21 14:23:43 +01:00
0d7873cf09 cargo: bump schema dependency
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-18 15:04:22 +01:00
667476f19d cli client: backup: better use of our api macro capabilities
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-18 15:04:22 +01:00
a1b800c232 cli client: backup: refactor/cleanup of (dry-run) logs
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-18 15:04:22 +01:00
4b8395ee0e fix #3323: cli client: add dry-run option for backup command
adds a dry-run parameter for "proxmox-backup-client backup".
With this parameter on it simply prints out what would be uploaded,
instead of uploading it.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-18 15:04:22 +01:00
dcd9c17fff tape/pool_writer: skip already backed up chunks in iterator
currently, the iterator goes over *all* chunks of the index, even
those already backed up by a previous snapshots in the same tape
backup. this is bad since for each iterator, we stat each chunk to
sort by inode number. so to avoid stat'ing the same chunks over
and over for consecutive snapshots, add a 'skip_fn' to the iterator
and in the pool writer and check the catalog_set if we can skip it

this means we can drop the later check for the catalog_set
(since we don't modify that here)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-02-18 10:40:41 +01:00
f30757df50 rrd: extract data: avoid always calculating start-time fallback
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-15 07:59:55 +01:00
ac20cb1f65 rrd: avoid intermediate index, directly loop over data
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-15 07:59:55 +01:00
c19af51ecb rrd cache: code style, avoid useless intermediate mutable
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-15 07:59:12 +01:00
d6644e29fe move src/shared_rate_limiter.rs to src/tools/shared_rate_limiter.rs
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-02-14 14:57:56 +01:00
260147bd73 ParallelHandler: avoid re-export (cleanup)
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-02-14 14:12:39 +01:00
e705b3057f rename cached_traffic_control.rs to traffic_control_cache.rs, improve dev docs
Keep things inside crate::traffic_control_cache (do not pollute root namespace).

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-02-14 13:45:44 +01:00
192ece47fb rrd_cache: add developer docs
and make RRD_CACHE private (please use get_rrd_cache instead).

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-02-14 12:07:10 +01:00
7739004815 ui: fixup title case
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-14 11:37:49 +01:00
11363a6a69 ui: node options: add support for selecting default language
Allows setting the default language in Configuration/Other/General

Signed-off-by: Matthias Heiserer <m.heiserer@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-14 11:37:26 +01:00
41adda1c64 fix #3853: tape cli: add force flag to key change-passphrase
Adds the '--force' flag to the proxmox-tape command allowing users
with root privileges to overwrite the passphrase of a given key.

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
2022-02-14 09:52:20 +01:00
77d6d7a22c fix #3853: api: add force option to tape key change-passphrase
When force is used, the current passphrase is not required. Instead
it will be read from the file pointed to by TAPE_KEYS_FILENAME and
the old key configuration will be overwritten using the new
passphrase. Requires super user privileges.

Signed-off-by: Stefan Sterz <s.sterz@proxmox.com>
2022-02-14 09:52:20 +01:00
5b93835744 rest-server: bump schema to 1.2 and use convenience methods
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-11 14:09:45 +01:00
fd7f760304 proxmox-rest-server: add missing 'derive' feature
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-11 13:57:48 +01:00
af6fdb9d0d tools: disk: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-10 18:39:56 +01:00
a1c906cb02 api: node/disk: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-10 13:12:15 +01:00
dcf5a0f62d misc clippy fixes
the trivial ones ;)

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-02-08 14:57:16 +01:00
bb9e503964 report: add tape, traffic control and disk infos
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
2022-02-07 15:37:06 +01:00
b2fc573a62 report: move subscription info further up
This is something that is checked all the time. Having it further up
saves on scrolling and brings it into better alignment with PVE & PMG
regarding where in the report the info is located.

Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
2022-02-07 15:37:06 +01:00
415da09826 node config: add english to translation enum for default-lang
Signed-off-by: Matthias Heiserer <m.heiserer@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-07 15:24:38 +01:00
5ffa68d2c4 api: node config: add default-lang integration
Signed-off-by: Matthias Heiserer <m.heiserer@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-07 15:24:38 +01:00
e7668a3eea ui: webauthn: decrease upgrade frequency from 1s to 2.5s
this is nothing to important and nothing that'll get changed *that*
often, so 2.5s is more than enough.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-07 15:20:22 +01:00
21898bb831 ui: webauthn: fix stopping store upgrades on destroy
`deactivate` is only triggered if we switch to a different tab on
the same navigation level, but if we switch to a completely different
component (e.g., fom `Options -> Others` to `Datastore foo`) we can
only work with the destroy event, use the before one as else we
cannot access the view controllers method anymore.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-07 15:19:47 +01:00
7b944ff11a re-use PROXMOX_DEBUG env variable to control log level filter
So that we can make 'log::debug' messages actually appear in the
syslog.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-04 11:21:47 +01:00
fce49eab30 fix #3856 hint parameter is not optional
For the API the parameter --hint is not optional. This patch fixes
the man page and cli command doesn't send an API call, if the
parameter does not exist.

Signed-off-by: Markus Frank <m.frank@proxmox.com>
2022-02-03 14:49:25 +01:00
af35bc8b9c proxy: refactor gui-language logic
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-03 13:12:02 +01:00
e5e48b01ad rest: add cookie_from_header helper
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-03 13:12:02 +01:00
5d74f79643 proxy: rustfmt
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-03 13:12:02 +01:00
b0427dda76 docs: fix typo in tape backup
Signed-off-by: Matthias Heiserer <m.heiserer@proxmox.com>
2022-02-03 13:12:02 +01:00
70ba718ce9 node config: avoid "allow" annotation
We rename those anyway for serialization so we do not need to bother
with spelling them in an non-idiomatic way just because i18n has it
like that.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-02-03 13:12:02 +01:00
68811af9f9 fix #3103. node config: allow to configure default UI language
This language is only used if none is set in the cookies.

Signed-off-by: Matthias Heiserer <m.heiserer@proxmox.com>
2022-02-03 13:12:02 +01:00
163629e62e bump proxmox-acme-rs dependency to 0.4
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-02-02 13:18:47 +01:00
1993d98695 traffic-control: use SocketAddr from 'accept()'
instead of getting the 'peer_addr()' from the socket.
The advantage is that we must get this and thus can drop the mapping
from result -> option, and can drop the testing for None and a test case

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-01-31 09:58:14 +01:00
127c5ac3a9 ui: datastore/Content: improve verification actions
verifying a single snapshot is now never skipped because of recent verify
verifying a group will now reverify after 29 days to be consistent
with the 'All OK (old)' display

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-01-27 15:31:55 +01:00
7a1a5d206d verify: allow '0' days for reverification
and let it mean that we will always reverify

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-01-27 15:31:55 +01:00
7a524f1048 bump version to 2.1.5-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-26 16:24:11 +01:00
1d3b253721 README: update for bullseye
and start with a higher level for "h1" headlines

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-26 16:19:21 +01:00
1f8b29f578 file restore: scale per-round delay up dynamically
Avoids latency for restore-VMs that are finished fast but not ready
yet the first round while not checking to often for slower ones, iow,
we assume that the start up distribution is looking like a chi-square
Χ² with k=3.

With 25*round we get at max 45 rounds totalling to 25.875 s delay and
1.125 max between-round delay, which still provides an ok reaction
time.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-26 16:12:58 +01:00
48ce3d00a4 file restore: always wait up to 25s
the timeout for connecting may be much shorter if we get a response
(which doesn't needs to be Ok, e.g., "Connection refused"), so
instead of trying a fixed amount of 60 times lets try for 25s
independent of how often that will be then.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-26 16:04:43 +01:00
d91a0f9fc9 Set MMAP_THRESHOLD to a fixed value (128K)
glibc's malloc has a misguided heuristic to detect transient allocations that
will just result in allocation sizes below 32 MiB never using mmap.

That it turn means that those relatively big allocations are on the heap where
cleanup and returning memory to the OS is harder to do and easier to be blocked
by long living, small allocations at the top (end) of the heap.

Observing the malloc size distribution in a file-level backup run:

@size:
[0]                   14 |                                                    |
[1]                25214 |@@@@@                                               |
[2, 4)              9090 |@                                                   |
[4, 8)             12987 |@@                                                  |
[8, 16)            93453 |@@@@@@@@@@@@@@@@@@@@                                |
[16, 32)           30255 |@@@@@@                                              |
[32, 64)          237445 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[64, 128)          32692 |@@@@@@@                                             |
[128, 256)         22296 |@@@@                                                |
[256, 512)         16177 |@@@                                                 |
[512, 1K)           5139 |@                                                   |
[1K, 2K)            3352 |                                                    |
[2K, 4K)             214 |                                                    |
[4K, 8K)            1568 |                                                    |
[8K, 16K)             95 |                                                    |
[16K, 32K)          3457 |                                                    |
[32K, 64K)          3175 |                                                    |
[64K, 128K)          161 |                                                    |
[128K, 256K)         453 |                                                    |
[256K, 512K)          93 |                                                    |
[512K, 1M)            74 |                                                    |
[1M, 2M)             774 |                                                    |
[2M, 4M)             319 |                                                    |
[4M, 8M)             700 |                                                    |
[8M, 16M)             93 |                                                    |
[16M, 32M)            18 |                                                    |

We see that all allocations will be on the heap, and that while most
allocations are small, the relatively few big ones will still make up most of
the RSS and if blocked from being released back to the OS result in much higher
peak and average usage for the program than actually required.

Avoiding the "dynamic" mmap-threshold increasement algorithm and fixing it at
the original default of 128 KiB reduces RSS size by factor 10-20 when running
backups. As with memory mappings other mappings or the heap can never block
freeing the memory fully back to the OS.

But, the drawback of using mmap is more wasted space for unaligned or small
allocation sizes, and the fact that the kernel allegedly zeros out the data
before giving it to user space. The former doesn't really matter for us when
using it only for allocations bigger than 128 KiB, and the latter is a
trade-off, using 10 to 20 times less memory brings its own performance
improvement possibilities for the whole system after all ;-)

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
 [ Thomas: added to comment & commit message + extra-empty-line fixes ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-26 14:10:54 +01:00
3af17d8919 bump version to 2.1.4-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-21 10:48:42 +01:00
98983a9dab pbs-tools: LruCache: implement Drop
this fixes the leaked memory for the cache, as we had only pointers
in the map/list which were freed, not the underlying chunks

moves the 'clear' implementation out of the trait bounds so that
Drop can reuse it

this is used e.g. for file download from a pxar

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-01-20 11:24:34 +01:00
e92df23806 docs: make external hyperlinks clickable
rustdoc lints detected that two external hyperlinks were not
clickable.

The short cut used is only available for internal links, otherwise
one needs to use the Markdown syntax, so either [Text](URL) or <URL>.

Signed-off-by: Matthias Heiserer <m.heiserer@proxmox.com>
[ T: commit message text width, mention markdown ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-18 15:54:33 +01:00
5ee8dd784f ciphers: improve option naming
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-01-14 11:02:07 +01:00
f37167aeff api2: make tls ciphers updatable
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-14 11:02:07 +01:00
2eba3967b2 proxy: use ciphers from config if set
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-14 11:02:07 +01:00
1d552d2dd5 ciphers: simplify API schema
these need to be checked (and are) via libssl anyway before persisting,
and newer versions might contain new ciphers/variants/... (and things
like @STRENGTH or @SECLEVEL=n were missing).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-01-14 11:02:07 +01:00
1ec7f7e6f2 config: add tls ciphers to NodeConfig
for TLS 1.3 and for TLS <= 1.2

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-14 11:02:07 +01:00
8ad9eb779e bump version to 2.1.3-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-12 16:49:33 +01:00
18ba1b2249 api-types: relax NODENAME_SCHEMA
there isn't really a concept of 'nodes' in PBS (yet) anyway - and if
there ever is, it needs to be handled by the rest-server / specific API
endpoints (like in PVE), and not by the schema.

this allows dropping proxmox-sys from pbs-api-types (and thus nix and
some other transitive deps as well).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-01-12 15:42:58 +01:00
e2e587e3c7 api-types: move RsaPubKeyInfo to pbs-client
it's the only thing requiring openssl in pbs-api-types, and it's only
used by the client to pretty-print the 'master' key, which is
client-specific.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2022-01-12 15:42:58 +01:00
c10a6755f0 docs: fix some typos
the `congestion` typo has been mentioned in the forum:
https://forum.proxmox.com/threads/proxmox-backup-server-2-1-released.100240/#post-443370

fixed a few surrounding ones and ones that `codespell` found in
addition to that.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-12 15:19:59 +01:00
d43aca148f ui: sys config: add icons to tabs
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-12 12:41:28 +01:00
5dfe3b66ab ui: sys config: code cleanup/refactoring
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-12 12:41:28 +01:00
50c0840146 ui: sys config: merge webauthn and general options into one tab
To much wasted space else.
Also rename "Options" to "Others", while it's not _that_ much better
it's slightly more intuitive than config -> options (which has some
redundancy)...

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-12 12:41:25 +01:00
2e02a859cf fix #3058: ui: improve remote edit UX by clarifying ID vs host
also fixup missing emptyText for fingerprint (adapted from PVE's PBS
storage addition) and code-style in surrounding areas a bit

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2022-01-12 09:38:59 +01:00
64c075b6c2 ui: hide rrd chart for io delay if no io_ticks are returned
it makes no sense to show a completely empty graph

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-01-11 11:43:10 +01:00
f27b6086b1 api/admin/datastore: rrd: do not include io_ticks for zfs datastores
since it is not possible to collect them, do not return them here either

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-01-11 11:42:09 +01:00
7c069e82d1 fix #3743: extract zfs dataset io stats from /proc/spl/kstat/zfs/POOL/objset-*
Recently, ZFS removed the pool global io stats from
/proc/spl/kstat/zfs/POOL/io with no replacement.

To gather stats about the datastores, access now the objset specific
entries there. To be able to make that efficient, cache a map of
dataset <-> obset ids, so that we do not have to parse all files each time.

We update the cache each time we try to get the info for a dataset
where we do not have a mapping.

We cannot update it on datastore add/remove since that happens in the
proxmox-backup daemon, while we need the info here in proxmox-backup-proxy.

Sadly with this we lose the io wait metric, but it seems that this is no
longer tracked in zfs at all, so nothing we can do for that.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2022-01-11 08:45:55 +01:00
b44483a853 datastore status: do not count empty groups
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2022-01-07 08:40:22 +01:00
ba857cbe68 tools::config: error on newlines in string values
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2022-01-05 10:04:04 +01:00
c772a4a683 ui: add new options tab under configuration
... and add from-email + move http-proxy there

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-04 08:24:17 +01:00
e466526137 server: use configured email-from for sending mail
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-04 08:09:27 +01:00
62222ed068 api2: make email-from updatable
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-04 08:09:27 +01:00
f06b5283b0 config: add email-from to NodeConfig
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
2022-01-04 08:05:34 +01:00
645d52308b TimeSpan: parse via FromStr
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
7f6c169b25 use schema verify methods
the old, deprecated ones only forward to these anyway.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
9987872382 rrd: drop redundant field names
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
6f1c26b083 tree-wide: is_ok/is_err()
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
3afecb8409 tree-wide: use is_empty() and similar
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
540fca5c9e tree-wide: cleanup manual map/flatten
found with clippy, best viewed with `-w` ;)

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
8ff886773f view_task_result: remove unnecessary &mut
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
aa174e8e8a tree-wide: drop redundant clones
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 15:02:07 +01:00
0a7f902e2a tape: multi-volume: fix overflow check
the part number cannot go above 255 at the moment, but if it ever gets
bumped to a bigger integer type this boundary wouldn't cause a
compile-error. explicitly checking for overflowing u8 makes this a bit
more future-proof, and shuts up clippy as well ;)

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 13:55:33 +01:00
9a37bd6c84 tree-wide: fix needless borrows
found and fixed via clippy

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-30 13:55:33 +01:00
a0c69902c8 fix #3763: disable renegotiation
requires openssl crate with fix[0], like our packaged one.

0: https://github.com/sfackler/rust-openssl/pull/1584

Tested-by: Stoiko Ivanov s.ivanov@proxmox.com
Reviewed-by: Stoiko Ivanov s.ivanov@proxmox.com

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-27 09:09:26 +01:00
f30ada6bbe bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-12-16 11:25:02 +01:00
c3b8e74fdf bump regex dep to 1.5
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-12-16 11:25:02 +01:00
9fa3026a08 cleanup schema function calls
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-12-16 11:25:02 +01:00
821aa8eae6 bump proxmox-schema to 1.1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-12-16 11:25:02 +01:00
0b50c18ed0 ui: group filter: add hint that filter are additive
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-16 11:19:49 +01:00
25e41aa802 restore-daemon: fix use of deprecated env_logger::from_env function
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-16 11:12:36 +01:00
ff6b6cd74d drop unused imports of proxmox_sys::identity
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-16 11:09:38 +01:00
48910f9b0a api: zfs: create zpool with relatime=on
some operations (e.g. garbage collection/restore/etc.) are very read
intensive on the chunks, and having atime=on and relatime=off (zfs default)
makes those write intensive operations too. Additionally, 'ext4' defaults to
relatime, so also change the default for api-created zpools.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-12-16 10:56:04 +01:00
dfe5c4c494 ui: fix opening settings window in datastore panel
When a user directly opened the webui with a fragment that is not
the summary, opening of the 'my settings' window fails because the
initial set of the columns field triggers a state change, which in turn
tries to trigger 'updateColumns'. That fails though, since the columns
were not even rendered yet (because we are on a different tab).

To fix this, simply return when the panel is not rendered yet.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-12-15 15:56:59 +01:00
beb1d6f362 buildsys: drop hack that moved testing after dh_install
the motivation for this was that we required to build some stuff with
different feature flags before the big-split when openid (that still
links to the dependency-greedy) got added, to avoid that binaries
that do not use openid at all also got linked to its dependencies.

This is now fixed since a bit and thus we should be able to drop the
test-reorder hack.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-15 14:25:32 +01:00
323ad7ddc0 fix #3794: api types: set backup time lower limit to 1
Some users want to import historical backups but they run into the
original lower backuo-time limit one can pass. That original limit
was derived from the initial PBS development start in 2019, it was
assumed that no older backup can exist with PBS before it existing,
but imports of older backups is a legitimate thing.

I pondered using 683071200 (1991-08-25), aka the first time Linux was
publicly announced by Linus Torvalds as new limit but at the end I
did not wanted to risk that and backup software is IMO to serious for
such easter eggs, so I went for 1, to differ between the bogus 0 some
tools fallback too if there's something off with time.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-15 14:13:49 +01:00
1f53f6128f cargo: update commented-out local path override for convenience
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-15 13:46:50 +01:00
4912d5f0e3 ui: calendar event: add once daily example and clarify workday one
similar to PVE, copying over the remaining commit message:

Using 00:00 with relying on the implied default is sub optimal as its
a bit of a magic example that new users may not understand as easily.
So spell it out explicitly, even if there'd be a shorter version
possible.

We also had some request for the once-daily every day, and its a
sensible example to have in general, could help getting the
difference between an hour list and a single one.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-07 18:54:26 +01:00
d4877712f8 pbs-client: avoid mut self in http_client methods.
It is not necessary, so avoid it. The client can now be used
with multiple threads (without using a Mutex).

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-04 14:44:05 +01:00
7549114c9f adapt compute_next_event to new signature
the 'utc' flag is now contained in the event itself and not given
as a flag to 'compute_next_event' anymore

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-02 10:40:58 +01:00
c72f8784a5 ui: group filter: merge duplicate filters
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-01 14:30:45 +01:00
6a5a60ebfd ui: group filter: cleanup and comment more
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-01 14:30:45 +01:00
f49cd6c135 ui: form/GroupFilter: copy records for the pbsGroupSelectors
store.getData() returns an 'Ext.util.Collection' which is a special
class that does more than being an array of records. Namely, it can
have 'observers' which can react on the change of the collection

Here, the 'onWidgetAttach' callback will be called twice on the first
row add and the widgets (and thus stores) are cached by extjs. When
doing a 'setData' of a Collection, it tries to add the store as an
observer, but due to the above caching and multiple calling this fails
since the store is already an observer.

For this reason, we want to actually copy the records (which neither
the store, nor the Collection has a method for...)

This gives us an additional benefit: The different pbsGroupSelectors can
sort independently now, before it was all linked to the original store's
collection.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-01 14:30:45 +01:00
b3c7567e3c ui: form/GroupFilter: improve group load callback handling
if 'me' is already destroyed here, return
if records is 'null' (which can happen on a not successful load),
load an empty list instead

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-01 14:30:45 +01:00
d0d970f70b ui: form/GroupFilter: correctly resolve the reference cycle
'record[widget]' does not contain anything since the widgets are
in the 'widgets' property so delete that

we also have to remove the 'record' entry of the widget so that
the widget does not have a link to the record anymore

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-12-01 14:30:45 +01:00
f66d814792 fix broken format strings
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-01 12:46:37 +01:00
b25e07b3ce deps: env_logger update to 0.9
and removal from main crate, not needed there anymore.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-12-01 12:46:37 +01:00
0e994eb938 pbs-api-types: remove proxmox-sys dependency for target wasm
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-01 09:49:52 +01:00
1a211f0d96 pbs-api-types: remove openssl dependency for target wasm
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-01 09:28:47 +01:00
f7fde5c81b pbs-api-types: remove libc dependency
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-01 09:10:25 +01:00
af5a55509d pbs-api-types: removbe usused nix dependency
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-01 09:08:25 +01:00
68b6c1202c remove use of deprecated functions from proxmox-time
Depend on proxmox-time 1.1.1

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-12-01 07:23:18 +01:00
ad72fda1d6 ui: SyncJobEdit: add second tab with group filters
adds a second tab and adapts the styling to our usual one (border/padding)

adds a change listener to the remote datastore selector to change the
remote + datastore on the group filters

remaining changes are mostly indentation changes

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-12-01 06:46:56 +01:00
705f4b0d95 ui: tape/BackupJobEdit: add second tab with group filters
adds a second tab and adapts the styling to our usual one (border/padding)

adds a change listener to the datastore selector to change it on the
group filters

remaining changes are mostly indentation changes

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-12-01 06:44:37 +01:00
65bd918ac3 ui: add GroupFilter form field(container)
this contains a grid + button + hidden field which lets the user
add group filters one by one. the first column is the type selector
(type, group, regex) and the second column shows the relevant
input field (groupselector, kvcombobox for type, and textfield for regex)

i had to hack a little to get access to the widgets of the
fieldcontainer, since we cannot simply access the widget of a column
from another column (which we need to show the correct one when changing
the type), also we cannot traverse the widget hirachy in the usual way,
since extjs seems to build it differently for widgetcolumns.

to solve this, i added references of the widgets to the record, and a
reference of the record to the widgets. since this is now a cyclic
reference, i solve that in 'removeFilter' and in 'beforedestroy' of the grid
by removing the references again

also contains a small css style to remove the padding in the rows

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-12-01 06:42:31 +01:00
7d4d8f47c9 ui: add GroupSelector
to select either a group from a datastore

for now it is expected to set the data in the store manually

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-12-01 06:41:21 +01:00
73fba2edea fix a warning in io_return macro
newer compilers warn about the semicolon there, so put
braces around it

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-29 11:26:25 +01:00
e25982f24e remove unused identity macro
this is not required anymore by the sortable macro

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-29 11:24:02 +01:00
368daf13fd bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-29 11:20:52 +01:00
e6e2927e72 update proxmox-tfa to 2.0
and fix still-very-bad updater usage in config api call...

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-29 11:19:50 +01:00
0fee4ff2a4 pbs-tape: do not depend on pbs-tools
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 13:17:58 +01:00
3dcea3ce33 fix typo in comment
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 13:15:35 +01:00
726b9d4469 use proxmox-sys 0.2.1 and proxmox-io 1.0.1
And remove unused code from pbs-tools.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 12:30:03 +01:00
577095e2f7 move pbs-tools/src/percent_encoding.rs to pbs-api-types/src/percent_encoding.rs
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 11:48:52 +01:00
f35e187f16 fix StdChannelWriter usage
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 11:27:20 +01:00
e2b12ce988 StdChannelWriter: avoid using anyhow::Error
Use a generic implementation to allow different error types.
2021-11-25 11:14:56 +01:00
92ef0b56d8 move pbs-tools/src/str.rs to pbs-client/src/pxar/create.rs
Code is only used there.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 10:43:22 +01:00
8a8a1850d0 remove trait BufferedRead from pbs-tools/src/io.rs
We do not need it.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 09:45:47 +01:00
fddb9bcc3e remove pbs-tools/src/sys.rs
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 09:01:29 +01:00
0df179c2b4 remove pbs-tools/src/cli.rs
Code is only used once in src/bin/proxmox_backup_debug/inspect.rs, so
move it into that file.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-25 08:33:10 +01:00
689ed51397 openid_login: improve error message for disabled users. 2021-11-25 07:29:33 +01:00
3c56335d7b update debian/control 2021-11-25 06:49:26 +01:00
9eb58647c1 pbs-datastore: use hex::serde feature
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-24 13:06:14 +01:00
0ff214bedd debian/control: add librust-proxmox-serde 2021-11-24 10:58:01 +01:00
25877d05ac update to proxmox-sys 0.2 crate
- imported pbs-api-types/src/common_regex.rs from old proxmox crate
- use hex crate to generate/parse hex digest
- remove all reference to proxmox crate (use proxmox-sys and
  proxmox-serde instead)

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-24 10:32:27 +01:00
bd00ff10e4 bump version to 2.1.2-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-23 13:56:36 +01:00
149b969d9a docs: remotes: note that protected flags will not be synced
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-11-23 13:53:03 +01:00
56d3b59c71 docs: backup-client: fix wrong ':ref:'
there is no 'backup server' reference we can link to here, and it would
not make sense anyway.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-11-23 13:53:03 +01:00
c1e6efa8e1 sync job: correctly apply rate limit
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-23 09:42:18 +01:00
3b5473a682 bump version to 2.1.1-2
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 16:07:42 +01:00
4954d3130b docs: add/update tc related screenshots & content, document tc for sync-job
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 16:05:22 +01:00
064497756e bump version to 2.1.1-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 12:27:22 +01:00
ce3c7a1bda ui: sync job: allow to configure rate limit
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 12:20:27 +01:00
50a39bbc1f ui: datastore content: rework rendering protection state
avoid that there's the same icon rendered twice, once clickable and
once as status. Also indicate the protection with a literal text and
by highlighting the single shield with green, if protected.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 11:22:29 +01:00
154d01b042 d/control and Cargo.toml bumps
* pin-utils isn't used anymore
* proxmox-sys version should also be tracked in Cargo.toml

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-22 10:56:36 +01:00
1f3352018b ui: traffic-control edit: add spaces between networks for more readabillity
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:45:29 +01:00
b721783c48 d/control: bump versioned build-dependency to librust-proxmox-sys
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:41:56 +01:00
76ee3085a4 ui: traffic-control edit: simple duplicate networks detection
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
5d5a53059f ui: traffic-control edit: move on-load set value logic to own method
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
77d8c593b3 ui: traffic-control edit: simpler unique timeframe logic
still just a heuristic, i.e., it does the same as previously but in
one line..

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
c450a3cafd ui: traffic-control edit: there's no 'network-select' anymore
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
f8f4d7cab4 ui: traffic-control edit: avoid CIDR literals in gettext
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
91abfef049 ui: traffic-control: include ipv6 in 'all' networks
by including '::/0' too

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
963b7ec51b ui: traffic-control: fix sending network value
we forgot to correclty send the network value as we changed from
the radiogroup to a simple text field

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
16aab0c137 ui: indentation fix
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 10:30:17 +01:00
bf8b8be976 ui: fix group-filter property name
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-22 09:13:32 +01:00
e201104d0b docs: update traffic control docs (use HumanBytes)
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-22 09:07:05 +01:00
d63db0863d proxmox-backup-manager traffic: render data human readable
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-22 09:07:05 +01:00
7a36833103 fix sync job regression test (add RateLimitConfig)
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-22 08:29:43 +01:00
ca6e66aa5a Fingerprint: add new signature method
commit c42a54795d introcuded a bug by
using fp.to_string(). Replace this with fp.signature() which correctly
returns the full fingerprint instead of the short version.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-22 08:29:43 +01:00
94a6b33680 set default for 'protected' flag
otherwise we cannot properly parse the api return value from older
versions, since that field does not exist there.

fixes sync from older versions without the protected feature

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-11-22 08:28:37 +01:00
2d5287fbbc use RateLimitConfig for HttpClient and pull
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-22 07:49:41 +01:00
6eb756bcab sync-job: add rate limit
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-22 07:49:41 +01:00
5647219049 pbs-api-types: split out type RateLimitConfig 2021-11-22 07:49:41 +01:00
b810972823 bump version to 2.1.0-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-21 10:32:17 +01:00
3a07cdf574 d/control: bump versioned dependency for proxmox-widget-toolkit
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-21 10:32:17 +01:00
193ec30c2b fix proxmox-backup-manager sync-job list
Property is called 'group-filter' (not 'groups').
2021-11-21 09:46:46 +01:00
c94723062c pbs-api-types: fix HumanByte::auto_scale 2021-11-21 09:13:02 +01:00
0eadfdf670 ui: traffic-control edit: fix name minLength (3 not 4)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:33:32 +01:00
ebf8ce20bc ui: traffic-control view: tune column width, add more flex
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:32:53 +01:00
e7acdde758 ui: traffic-control edit: make window taller for more common ratio
and add timeframe emptyText

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:09:41 +01:00
f2c9da2349 ui: traffic-control edit: send rates as stringified, auto-scaled size-unit
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:08:22 +01:00
ff344655e2 ui: traffic-control edit: make network edit a single text field
here's to note that the radio-group was my idea, Dominik just
executed it, nicely that is.

But, the panel looks a bit glitchy layout wise as with that and the
bandwidth fields (maybe we should render their unit inline) the
vertical alignments were all over the place.

So for now make it a simple text field and throw in a tooltip for
good measurement

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:04:59 +01:00
3490d9460c ui: traffic-control edit: very simple duplicate timeframe detection
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:04:01 +01:00
fdf9373f9e ui: traffic-control edit: handle empty time-frame correctly
delete on update and avoid sending an empty string in any case, the
backend does not likes that much.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 22:02:47 +01:00
ba80611324 ui: traffic-control view: various code cleanups
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 21:54:55 +01:00
07a579c632 ui: traffic-control view: time frames are optional so avoid render exception
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 21:54:22 +01:00
188a37fbed ui: traffic-control view: make rendere more flexible
do not choke on non-numbers but use the (partially new) widget
toolkit helpers to also be able to parse string based sizes with
units and auto-scale them

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 21:52:31 +01:00
f251367c33 ui: navigation: change traffic-control icon to rotated signal
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 21:43:03 +01:00
ac4e399a10 ui: add Traffic Control UI
adds a list of traffic control rules (with their current usage)
and let the user add/edit/remove them

the edit window currently has a grid for timeframes to add/remove
with input fields for start/endtime and checkboxes for the days

there are still some improvements possible, like having a seperate
grid for networks (the input field is maybe too small), or
optimizing consecutive days to a range (e.g. mon..wed instead of mon,tue,wed)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-11-20 19:40:59 +01:00
4fe77c36df api: traffic_control: add missing rename to 'kebab-case'
otherwise the 'delete' properties need underscores
(e.g. 'burst_in' instead of 'burst-in')

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-11-20 19:40:30 +01:00
118515dbd0 use HumanByte for traffic-control config
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 19:35:24 +01:00
42ba4cd399 human byte: make proper proxmox API type
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 19:35:24 +01:00
ab1c07a622 human byte: add from string parser
Adapted from Dietmar's v3 on pbs-devel but some changes:
- reworked with a strip_suffix fn that does matching, way shorter and
  even easier to read IMO
- make b/B byte symbol fully optional, not just for base-10
- also trim trailing whitespace for SizeUnit::Byte
- simplify the FromStr impl
- adapt parser unit tests such that we actually see the failed test's
  definition line, simplifies debugging a bit

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 19:35:24 +01:00
930a71460f human byte: add proper unit type and support base-10
The new SizeUnit type takes over the auto scaling logic and could be
used on its own too.

Switch the internal type of HumanByte from u64 to f64, this results
in a slight reduce of usable sizes we can represent (there's no
unsigned float type after all) but we support pebibyte now with quite
the precision and ebibytes should be also work out ok, and that
really should us have covered for a while..

Partially adapted by Dietmar's version, but split up and change so:
* there's no None type, for a SizeUnit that does not makes much sense
* print the unit for byte too, better consistency and one can still
  use as_u64() or as_f64() if they do not want/need the unit rendered
* left the "From usize/u64" impls intact, just convenient to have and
  avoids all over the tree changes to adapt to loosing that
* move auto-scaling into SizeUnit, good fit there and I could see
  some re-use potential for non-human-byte users in the future
* impl Display for SizeUnit instead of the separate unit_str method,
  better usability as it can be used directly in format (with zero
  alloc/copy) and saw no real reason of not having that this way
* switch the place where we auto-scale in HumanByte's to the new_X
  helpers which allows for slightly reduced code usage and simplify
  implementation where possible
* use rounding for the precision limit algorithm. This is a stupid
  problem as in practices there are cases for requiring every variant:
  - flooring would be good for limits, better less than to much
  - ceiling would be good for file sizes, to less can mean ENOSPACE
    and user getting angry if their working value is messed with
  - rounding can be good for rendering benchmark, closer to reality
    and no real impact
  So going always for rounding is really not the best solution..

Some of those changes where naturally opinionated, if there's a good
practical reason we can switch back (or to something completely
different).

The single thing I kept and am not _that_ happy with is being able to
have fractional bytes (1.1 B or even 0.01 B), which just does not
makes much sense as most of those values cannot exist at all in
reality - I say most as multiple of 1/8 Byte can exists, those are
bits.o

Note, the precission also changed from fixed 2 to max 3 (trailing
zeros stripped), while that can be nice we should see if we get
a better precision limiting algorithm, e.g., directly in the printer.
Rust sadly does not supports "limit to precision of 3 but avoid
trailing zeros" so we'd need to adapt their Grisu based algorithm our
own - way to much complexity for this though..

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 19:35:24 +01:00
a58a5cf795 move HumanByte to pbs-abi-types crate
Originally-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-20 19:35:24 +01:00
92a8f0bc82 depend on proxmox-async 0.2 2021-11-20 17:14:02 +01:00
bf298a16ef proxmox-rest-server: remove pbs-tools dependency 2021-11-19 18:06:54 +01:00
9a1b24b6b1 use new proxmox-async crate
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-19 18:03:22 +01:00
ea67cd70c9 tfa: handle incompatible challenge data
by returning default data, in case the challenge data is not parseable.
this allows a new challenge to be started for the userid in question
without manual cleanup.

currently this can be triggered if an ongoing challenge created with
webauthn-rs 0.2.5 is stored in /run and attempted to be read
post-upgrade.

Reported-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-11-19 14:12:31 +01:00
281a5dd1fc cleanup unused re-exports
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-19 12:49:46 +01:00
df3b3d1798 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-19 12:22:44 +01:00
f5e2b4726d webauthn: correctly set origin when updating
with current proxmox-tfa this became a hard error, since origin and rp
are not both Strings anymore..

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-11-19 11:58:17 +01:00
daaeea8b4b update to base64 0.13
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2021-11-19 11:58:17 +01:00
6f6df501a0 fix debian/control: include librust-proxmox-sys 2021-11-19 11:35:28 +01:00
d5790a9f27 use new proxmox-sys crate
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-19 11:06:35 +01:00
860eaec58f use proxmox::tools::fd::fd_change_cloexec from proxmox 0.15.3
Depend on proxmox 0.15.3

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-18 13:43:41 +01:00
26e949d5fe traffic-control api: return current traffic with config
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-18 12:24:33 +01:00
ac7dbba458 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-18 11:32:56 +01:00
7c2431d42c api: acme: fix typo
Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-18 11:32:22 +01:00
25c1420a12 config: acme: plugin: rustfmt
Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-18 11:32:22 +01:00
c1a1e1ae8f api: config: acme: rustfmt
Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-18 11:32:22 +01:00
a9df9df25d d/control: update openid build dependency verison
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 11:23:50 +01:00
10beed1199 openid: allow to configure scopes, prompt, ACRs and arbitrary username-claim values
- no longer set prompt to 'login' (makes auto-login possible)
- new prompt configuration
- allow arbitrary username-claim values

Depend on proxmox-openid 0.9.0.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-18 11:20:55 +01:00
df32530750 docs: remote sync: adapt to changed filter param and add some examples
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:40:19 +01:00
062edce27f group filter: rename CLI/API/Config "groups" option to "group-filter"
we even use that for basically all the related schema names, "groups"
allone is just rather not so telling, i.e., "groups" what?

While due to the additive nature of `group-filter` is not the best
possible name for passing multiple arguments on the CLI (the web-ui
can present this more UX-friendly anyway) due to possible confusion
about if the filter act like AND vs OR it can be documented and even
if a user is confused they still are safe on more being synced than
less. Also, the original param name wasn't really _that_ better in
that regards

Dietmar also suggested to use singular for the CLI option, while
there can be more they're passed over repeating the option, each with
a single filter.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
efd2713aa8 proxmox-tape: add groups filter to backup command
and add a completion handler to complete the backup groups

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
8a21566c8a ui: tape: show configred group filters
in the grid and in the edit window

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
c8c5c7f571 fix #3533: tape backup: filter groups according to config
this fixes bug #3533, since now a user can backup a single datastore
on multiple tape media pools in parallel, e.g. vms on one pool, ct on
another.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
91357c2034 tape backup jobs: add group filters to config/api
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
097ccfe1d5 proxmox-tape: add missing 'notify-user' option to backup command
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
61ef4ae8cb fix #sync.cfg/pull: don't remove by default
and convert existing (manually created/edited) jobs to the previous
default value of 'true'. the GUI has always set this value and defaults
to 'false'.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
01ae7bfaf2 docs: mention group filter in sync docs
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
1b52122a1f manager: render group filter properly
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
1d9bc184f5 remote: add backup group scanning
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
5f83d3f636 sync: add group filtering
like for manual pulls, but persisted in the sync job config and visible
in the relevant GUI parts.

GUI is read-only for now (and defaults to no filtering on creation), as
this is a rather advanced feature that requires a complex GUI to be
user-friendly (regex-freeform, type-combobox, remote group scanning +
selector with additional freeform input).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
71e534631f pull: allow pulling groups selectively
without requiring workarounds based on ownership and limited
visibility/access.

if a group filter is set, remove_vanished will only consider filtered
groups for removal to prevent concurrent disjunct filters from trashing
eachother's synced groups.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
6e9e6c7a54 pull/sync: extract passed along vars into struct
this is basically the sync job config without ID and some stuff
converted already, and a convenient helper to generate the http client
from it.

Suggested-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
e2e7560d5e pull: use BackupGroup consistently
instead of `GroupListItem`s. we convert it anyway, so might as well do
that at the start.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
0ceb97538a BackupGroup: add filter helper
to have a single implementation of "group is matched by group filter".

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
3e276f6fb6 api: add GroupFilter(List) type
at the API level, this is a simple (wrapped) Vec of Strings with a
verifier function. all users should use the provided helper to get the
actual GroupFilter enum values, which can't be directly used in the API
schema because of restrictions of the api macro.

validation of the schema + parsing into the proper type uses the same fn
intentionally to avoid running out of sync, even if it means compiling
the REs twice.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
2b00c5abca api-types: add schema for backup group
the regex was already there, and we need a simple type/schema for
passing in multiple groups as Vec/Array via the API.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-18 10:36:57 +01:00
15cc41b6cb proxmox-systemd: remove crate, use new proxmox-time 1.1.0 instead
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-17 13:07:51 +01:00
729bd1fd16 remove now unused serde_filter module
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-17 09:50:08 +01:00
9a7431e2e0 www: use TFA widgets from widget toolkit
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-17 09:44:55 +01:00
52fbc86fc9 bump d/control rust dependencies
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-17 09:44:48 +01:00
afe6c79ce3 bump proxmox-widget-toolkit dependency to 3.4-1
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-17 09:43:26 +01:00
9407810fe1 switch tfa api to use proxmox-tfa::api
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-11-17 09:33:04 +01:00
c42a54795d move fingerprint helpers from pbs-tools to pbs-api-types
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-17 07:07:40 +01:00
96ec3801a9 docs: add traffic control section
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-15 13:43:11 +01:00
c4707d0c1d depend on proxmox-shared-memory 0.1.1
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-15 11:35:52 +01:00
24f9af9e0f add missing file from previous commit
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-14 18:49:29 +01:00
a0172d766b traffic-controls: add API/CLI to show current traffic
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-14 17:21:45 +01:00
09f999337a update to proxmox-http 0.5.4
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-14 08:27:45 +01:00
e3eb062c09 cached_traffic_control: fix regression tests
Avoid using shared memory in tests because of permission problems.
2021-11-14 08:05:40 +01:00
de21d4efdc implement rate limiter in shared memory
This kind of rate limiter can be used among several processes (as long
as all set the same rate/burst).
2021-11-13 17:49:38 +01:00
d5f58006d3 cached_traffic_control: use ShareableRateLimit trait object 2021-11-13 17:49:38 +01:00
cb80ffc1de pbs-config: use new SharedMemory helpers from proxmox-shared-memory crate
depend on proxmox-shared-memory crate.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-13 17:49:38 +01:00
1859a0eb8b rest: make successful-ticket auth log a debug one to avoid syslog
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-11-12 11:10:12 +01:00
9e7132c0b3 bump version to 2.0.14-1 2021-11-12 08:12:18 +01:00
bf013be1c4 create /var/lib/proxmox-bnackup at server startup
This was missing in previous patch...

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-12 08:12:18 +01:00
b935209584 fix directory permission problems
By carefully setting options on all create_path() calls,
and by creating "/var/lib/proxmox-backup" at api server startup.
2021-11-12 07:29:18 +01:00
efd4ddc17b debian/control: depend on librust-cidr-dev 2021-11-10 12:23:16 +01:00
e511e0e553 proxmox-backup-proxy: implement traffic control
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
610150a4b4 implement a traffic control cache for fast rate control limiter lockups
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
485b2438ac traffic_control: use Memcom to track. config versions
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
bfd12e871f Add traffic control configuration config with API
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
0c136bfab1 DailyDuration: implement time_match() 2021-11-10 10:15:40 +01:00
245e2aea23 New DailyDuration type with nom parser
We will use this to specify timesframes for network rate limits (only
apply limite when inside the time frame).

Note: This is not systemd related, but we can reuse some of the parser
method.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
b9d588ffde implement Servive for RateLimitedStream
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
e4bc3e0e8d proxmox-backup-client: add rate/burst parameter to backup CLI
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:40 +01:00
2419dc0de9 pbs-client: add option to use the new RateLimiter
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-10 10:15:32 +01:00
68fd9ca6d6 openid_login: vertify that firstname, lastname and email fits our schema definitions
If not, we do not copy the values to our user.cfg.
2021-11-10 06:48:40 +01:00
4beb7d2dbe correctly lock remote config
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-11-06 17:35:10 +01:00
2bc1250c28 docs: language fixup: faq and appendix
minor formatting and language fixes to the faq section and the appendix

Signed-off-by: Dylan Whyte <d.whyte@proxmox.com>
2021-11-02 07:12:07 +01:00
9b1e2ae83c api: admin/datastore: reuse 'is_protected' implementation
we already have that

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 12:54:54 +02:00
9b5ecbe2ff backup-client: use () instead of Value as return type
shorter and we do a conversion anyway

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 12:54:54 +02:00
342ed4aea0 PruneMark: implement display without the write! macro
by using write_str instead

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 12:54:54 +02:00
d4e9d5470e PruneMark: use copied values instead of references
the type is small enough

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 12:54:54 +02:00
5c1cabdea1 rrd: use saturating_sub to avoid underflow
Without this, the tests fail in debug mode.
Also having start (u64) underflow to a value greater than end does
not really make sense

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 12:54:54 +02:00
38517ca053 docs: add info about protection flag to client docs
and mention that sync/pull does not sync the protected flag

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:32 +02:00
e33758d1b8 fix #3602: ui: datastore/Content: add action to set protection status
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:28 +02:00
aba6189c4f ui: add protected icon to snapshots
if they are protected

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:23 +02:00
adcc21716b ui: PruneInputPanel: add keepReason 'protected' for protected backups
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:21 +02:00
87e17fb4d1 proxmox-backup-client: add 'protected' commands
includes 'update' and 'show' similar to the notes commands

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:16 +02:00
8292d3d20e api2/admin/datastore: add get/set_protection
for gettin/setting the protected flag for snapshots (akin to notes)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:11 +02:00
5cc7d89139 api2: datastore/delete_group: throw error for partially removed group
when a group could not be completely removed due to protected snapshot,
throw an error

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:07 +02:00
343392613d pull_store/group: dont try remove locally protected snapshots
and log if a vanished groups could not be completely deleted if it
contains protected snapshots

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:04 +02:00
de91418b79 backup/datastore: prevent protected snapshots to be removed
by throwing an error for remove_backup_dir, and skipping for
remove_backup_group

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:31:00 +02:00
fe9c47ab4f tests/prune: add tests for protecteded backups
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:30:56 +02:00
02db72678f add protected info of snapshots to api and task logs
adds the info that a snapshot is protected to:
* snapshot list
* manual pruning (also dry-run)
* prune jobs

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:30:51 +02:00
db4b469285 pbs-datastore: skip protected backups in pruning
as a separate keep reason so it will not be calculated for the other reasons

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:30:47 +02:00
92c5cf42d1 pbs-datastore: add protection info to BackupInfo
and add necessary helper functions (protected_file/is_protected)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-28 11:30:44 +02:00
e9558f290a ui: datastore content: improve sorting verification column
sort failed < no verify < outdated < all ok

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-27 16:29:59 +02:00
572e6594d2 fix typo s/CGM/GCM/i
only user visible change is in the error message

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-27 16:28:02 +02:00
88691284d8 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-22 14:30:00 +02:00
85c622807e Cargo.toml: set udev dependency to 0.4
we don't need to bother with 0.3 anymore

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-22 14:28:33 +02:00
9d42e0475b acme: interpret no TOS as accepted
some custom ACME endpoints do not have TOS, interpret this as
'the user has accepted the TOS', like we do for PVE.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-22 10:55:14 +02:00
181a335bfa bump proxmox-acme-rs dependency to 0.3
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-22 10:54:43 +02:00
0a33951e9e acme: new_account: prevent replacing existing accounts
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-22 08:35:24 +02:00
7a356a748a bump version to 2.0.13-1
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-21 08:36:41 +02:00
1c402740a2 update dedian/control
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-21 07:59:45 +02:00
e0a19d3313 use new fsync parameter to replace_file and atomic_open_or_create
Depend on proxmox 0.15.0 and proxmox-openid 0.8.1

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-21 07:28:32 +02:00
6b8329ee34 tape: simplify export_media_set for pool writer
our export code can handle if the tape is inside the drive, so unloading
it first does not have an benefit, it even makes the exporting slower,
since we first unload it into its original slot, and then moving it
to an import/export slot

so drop the code that unloads the tape from the drive, and let the
export code itself handle that

change the 'eject' into a 'rewind' and comment why we do that first

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-21 06:37:48 +02:00
1d4448998a rest-server: use hashmap for parameter errors
our ui expects a map here with 'field: "error"'. This way it can mark
the relevant field as invalid and correctly shows the complete error
message

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-21 06:32:23 +02:00
d6473f5359 proxmox-rrd: use fsync instead of syncfs
syncfs can sync unrelated data, and we do not want that.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-20 11:46:59 +02:00
f5f9ec81d2 proxmox-rrd: fix regression tests 2021-10-19 18:41:03 +02:00
fea950155f proxmox-rrd: improve dev docs
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-19 11:17:09 +02:00
ef2944bc24 proxmox-rrd: cleanup - impl FromStr for JournalEntry
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-19 11:17:09 +02:00
934c8724e2 proxmox-rrd: add option to avoid page cache for load/save
use fadvice(.., POSIX_FADV_DONTNEED) for RRD files. We read those files only once,
and always rewrite them.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-19 11:17:09 +02:00
98eb435d90 proxmox-rrd: use syncfs after writing rrd files
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
2021-10-19 11:17:09 +02:00
bd10af6eda bump version to 2.0.12-1
note, this bump happened outside the main branch as it wasn't in a
good state and there was need for bumping (log/task rotate stuff).

Cherry picking the actual bump to avoid changelog/versioning
confusion on the next one, that should again happen on the main
branch.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
(cherry picked from commit edc876c58e)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-19 11:13:06 +02:00
7f381a6246 proxmox-rrd: use fine grained locking in commit_journal_impl
Aquire the rrd_map lock for each file (else we block access for a long time)
2021-10-18 14:55:47 +02:00
c17fbbbc07 proxmox-rrd: log all errors from apply_and_commit_journal_thread (but only once) 2021-10-18 11:57:19 +02:00
ac2ca6c341 tape: improve export_media error message for not found tape
'export_media' can handle if the tape is in either a normal slot of the
library, or in the drive assigned to the current pool writer.
(because we need to lock the drive)

if it is, for some reason, in a different drive, the error message
 'media is not online'
could be slightly confusing for a user, since it would appear in the drive list

add the 'or a differen drive' to make it clearer

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-18 10:40:56 +02:00
d26865c52c proxmox-rrd: cleanup list_old_journals 2021-10-18 10:00:58 +02:00
2b05008a11 proxmox-rrd: cleanup - use struct instead of tuple 2021-10-16 12:45:03 +02:00
45700e2ecf proxmox-rrd: move RRDMap into extra file 2021-10-16 12:45:03 +02:00
f84304235b proxmox-rrd: move JournalState into extra file 2021-10-16 12:45:03 +02:00
0ca41155b2 proxmox-rrd: implement non blocking journal
Do not block while applying the journal.
2021-10-16 12:45:03 +02:00
a291ab59ba proxmox-rrd: rename RRDCacheState to JournalState 2021-10-15 09:35:44 +02:00
fce7cd0d36 proxmox-rrd: avoild blocking readers while applying the journal
By using and extra RwLock<RRDMap> on the rrd data.
2021-10-15 09:22:07 +02:00
658357c5a8 proxmox-rrd: log journal apply/flush times, split apply and flush
We need to apply the journal only once.
2021-10-15 07:16:41 +02:00
7484fce24d proxmox-rrd: cleanup - use slot_end_time() 2021-10-14 16:29:00 +02:00
f28a713e2b proxmox-rrd: cleanup - use staturating_add instead of if/else 2021-10-14 16:10:55 +02:00
a9017805b7 proxmox-rrd: improve dev docs 2021-10-14 11:53:54 +02:00
2e3f94e12f proxmox-rrd: make rrd load callback configurable 2021-10-14 11:41:26 +02:00
d531c7ae61 proxmox-rrd: add more regression tests 2021-10-14 10:55:12 +02:00
7df1580fa6 proxmox-rrd: add regression tests and two minor fixes 2021-10-14 10:17:07 +02:00
58f70bccbb proxmox-rrd: pass time and value to update function 2021-10-14 08:12:56 +02:00
fae4f6c509 cleanup: move rrd cache related code into extra file 2021-10-14 07:57:27 +02:00
ddafb28572 proxmox-rrd: add some integration tests (file format tests) 2021-10-13 18:21:23 +02:00
642c7b9915 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-13 14:47:24 +02:00
5a8726e6d2 pbs-tools: drop borrow module
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-13 14:14:03 +02:00
b3f279e2d9 use complete_file_name from proxmox-router 1.1 2021-10-13 14:10:02 +02:00
82f5ad18f0 proxmox-rrd: move unshipped cli tool to examples
it's a rather low-level tool mostly useful for debugging and some of
it is rather "dumb" (by design) anyway, e.g., it does not
transparently applies journal but really only operates on the DB
files as is (which can conflict with daemon operations).

In summary, not (yet) a tool meant for end user consumption.
Move it to examples folder to avoid compilation on packaging (we do
not ship it anyway) which allows us to move the rather expensive
proxmox-router (pulls in hyper) to the dev-dependencies section.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
bacc99c7f8 proxmox-rrd: add more commands to the rrd cli tool
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
6728d0977b proxmox-rrd: rename last_counter to last_value
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
bff7c027c9 proxmox-rrd: protect against negative update time
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
79b3113361 proxmox-rrd: new helpers: slot, slot_start_time & slot_end_time
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
5885767b91 proxmox-rrd: avoid expensive modulo (%) inside loop
Modulo is very slow, so we try to avoid it inside loops.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
ec08247e5c proxmox-rrd: add binary to create/manage rrd files
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
400f081487 proxmox-rrd: split out load_rrd (cleanup)
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
03664514ab proxmox-rrd: support CF::Last
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
c68fa58a59 remove proxmox-rrd-api-types crate, s/RRDTimeFrameResolution/RRDTimeFrame/
Because the types used inside the RRD have other requirements
than the API types:

- other serialization format
- the API may not support all RRD features

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
426dda0730 proxmox-rrd: extract_data: include values from current slot
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
eb37d4ece2 proxmox-rrd: remove dependency to proxmox-rrd-api-types
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
1198f8d4e6 proxmox-rrd: implement new CBOR based format
Storing much more data points now got get better graphs.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
4b709ade68 proxmox-backup-proxy: use tokio::task::spawn_blocking instead of block_in_place
allow the current thread to do some other work in-between

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
fa49d0fde9 RRD_CACHE: use a OnceCell instead of lazy_static
And initialize only with proxmox-backup-proxy. Other binaries dont need it.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
1d44f175c6 proxmox-rrd: use a journal to reduce amount of bytes written
Append pending changes in a simple text based format that allows for
lockless appends as long as we stay below 4 KiB data per write.

Apply the journal every 30 minutes and on daemon startup.

Note that we do not ensure that the journal is synced, this is a
perfomance optimization we can make as the kernel defaults to
writeback in-flight data every 30s (sysctl vm/dirty_expire_centisecs)
anyway, so we lose at max half a minute of data on a crash, here one
should have in mind that we normally expose 1 minute as finest
granularity anyway, so not really much lost.

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-13 13:36:02 +02:00
890b88cbef remove pbs-tools::ops::ControlFlow
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-12 14:36:40 +02:00
27709b49d5 pbs-config: drop default-features on proxmox-router dep
we don't need the 'cli' feature in there

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-12 13:11:08 +02:00
7ccbce03d3 docs: language and formatting fixup
Some minor langague and formatting fixes to sections: Proxmox VE
Integration, pxar Command Line Tool, Managing Remotes, Maintenance
Tasks, Host System Administration, Network Management, and Technical
Overview.

Signed-off-by: Dylan Whyte <d.whyte@proxmox.com>
2021-10-12 08:31:37 +02:00
5fb852afed docs: backup-client: langauge and formatting fixup
also remove todo item for scheduling garbage collect with cron, and add
note about schedule configuration through proxmox-backup-manager/PBS GUI

Signed-off-by: Dylan Whyte <d.whyte@proxmox.com>
2021-10-12 08:30:39 +02:00
60589e6066 docs: Update for new features/functionality
Update GUI section and GUI instructions to reflect current layout and
features

List OpenID connect in possible realms (user management)

Link Access Control section when referring to it (user management)

Include Tape roles in access control section

Minor formatting changes

Signed-off-by: Dylan Whyte <d.whyte@proxmox.com>
2021-10-12 08:28:29 +02:00
717ce40612 docs: language and formatting fixup
Some minor changes to the sections: Introduction, Installation,
Terminology, GUI, Storage, and User Management

Mention tape backup in main features

Update epilog.rst with link for 'LXC'.
Remove FIXME from epilog.rst (I believe this was a note to repair
the not-yet-created pbs wiki link).

Signed-off-by: Dylan Whyte <d.whyte@proxmox.com>
2021-10-12 08:26:13 +02:00
75442e813e api daemons: fix sending log-reopen command
send_command serializes everything so it cannot be used to send a
raw, optimized command. Normally that means we get an error like
> 'unable to parse parameters (expected json object)'
when used that way.

Switch over to send_raw_command which does not re-serializes the
command.

Fixes: 45b8a032 ("refactor send_command")
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-11 14:35:50 +02:00
853c55a049 bump d/control
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-11 12:08:57 +02:00
6ef1b649d9 update to first proxmox crate split
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-11 11:58:49 +02:00
e3f3359c86 bump proxmox dependency to 0.14.0 and proxmox-http to 0.5.0
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-08 11:18:22 +02:00
0e1edf19b1 proxmox-backup-proxy: clean up old tasks when the task log was rotated
we maybe have old tasks when the task list was rotated, so clean them up

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-08 06:47:38 +02:00
de55fff226 rest-server: add cleanup_old_tasks
this is a helper that removes task log files that are not referenced
by the task archive anymore

it gets the oldest task archive file, gets the first endtime (the
oldest) and removes all files in the taskdir where the mtime is older
than that

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-08 06:38:52 +02:00
b3a67f1f14 proxmox-rrd: use correct directory options in create_rrdb_dir 2021-10-07 08:50:50 +02:00
3cc23ca6cc proxmox-rrd: cleanup error handling 2021-10-07 08:01:12 +02:00
3def6bfc64 proxmox-rrd: use log crate instead of eprintln, avoid duplicate logs 2021-10-06 18:19:22 +02:00
18e8bc17e4 proxmox-rrd: fix update (do not update) when time is in the past 2021-10-06 18:01:48 +02:00
f66d66aafe drop dynamic_index.rs duplicate in pbs-client
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-06 15:29:27 +02:00
7380c48dff pbs-tools::io::pipe: use nix Error type
there's no need to upgrade to anyhow::Error there already

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-06 15:28:58 +02:00
0191759316 proxmox-rrd: improve developer docs 2021-10-06 12:19:54 +02:00
dbc42e6f75 proxmox-rrd: remove serde dependency 2021-10-06 10:55:46 +02:00
d1c3bc5350 split out RRD api types into proxmox-rrd-api-types crate 2021-10-06 09:49:51 +02:00
a97301350f proxmox-rrd: use create_path instead of std::fs::create_dir_all
To ensure correct file ownership.
2021-10-06 08:37:14 +02:00
09340f28f5 move RRD code into proxmox-rrd crate 2021-10-06 08:13:28 +02:00
20497c6346 bump version to 2.0.11-1
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-05 16:34:35 +02:00
d0f7d0d9c1 d/changelog: fixup release
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-05 14:23:28 +02:00
608806e884 proxmox-rest-server: use new ServerAdapter trait instead of callbacks
Async callbacks are a PITA, so we now pass a single trait object which
implements check_auth and get_index.
2021-10-05 11:13:10 +02:00
48176b0a77 proxmox-rest-server: pass owned RestEnvironment to get_index
This way we avoid pointers with lifetimes.
2021-10-05 11:12:53 +02:00
3483a3b3a1 proxmox-rest-server: cleanup, access api_auth using a method 2021-10-05 11:12:53 +02:00
347e0d4c57 fix deprecated use of std::u64/... modules
integer primitive type modules are deprecated, use
associated constants instead

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-10-04 15:02:30 +02:00
ae9b5c077a ui: datastore/Content: add empty text for no snapshots
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-04 10:28:10 +02:00
747446eb50 ui: datastore/Content: reload in activate listener
when we trigger the first load before the panel was fully created,
there was no load mask for it (but the snapshots would "pop in" on load)

move the first reload into the 'activate' listener. this will be called
the every time a user opens the content tab of a datastore, so guard
it by a 'firstLoad' bool.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2021-10-04 10:28:10 +02:00
e1c8c27f47 rest: daemon: group systemd FFI together
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-02 11:45:34 +02:00
63cec1622a rest: daemon: sd notify: code cleanup
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-02 11:45:34 +02:00
31142ef291 rest: daemon: sd notify barrier: avoid barging in between SystemdNotify enum and systemd_notify
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-02 11:45:34 +02:00
058b4b9708 rest: daemon: sd notify barrier: allow caller to set timeout
else it's rather to subtle and not a nice interface considering that
we only want to have a thin wrapper for sd_notify_barrier..

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-02 11:44:20 +02:00
9a1330c72e rest: daemon: comment why using a systemd barrier is important for main PID handover
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-02 11:44:20 +02:00
0a6df20986 rest-server/daemon: use sd_notify_barrier for service reloading
until now, we manually polled the systemd service state during a reload
so that the sd_notify messages get processed in the correct order
(RELOAD(old) -> MAINPID(old) -> READY(new))

with systemd >= 246 there is now 'sd_notify_barrier' which
blocks until systemd processed all prior messages

with that change, the daemon does not need to know the service name anymore

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-10-02 11:44:20 +02:00
6680878b5c proxmox-rest-server: make get_index async 2021-10-01 09:38:10 +02:00
593043ed53 proxmox-rest-server: add comment why ApiService needs to be 'pub' 2021-10-01 08:35:51 +02:00
038f385089 proxmox-rest-server: make check_auth async 2021-10-01 07:53:59 +02:00
b914b94773 proxmox-rest-server: fix spelling errors 2021-10-01 06:43:30 +02:00
2194bc59c8 proxmox-rest-server: improve ApiService docs 2021-09-30 17:18:47 +02:00
a98a288e2d proxmox-rest-server: start module docs 2021-09-30 13:49:29 +02:00
49e25688f1 rename CommandoSocket to CommandSocket 2021-09-30 12:52:35 +02:00
d7eedbd24b tools::format: avoid some string copies
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-30 12:43:33 +02:00
5b17a02da4 drop str::join helper
the standard join method can do this now

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-30 12:43:33 +02:00
8735247f29 drop fd_change_cloexec from proxmox-rest-server
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-30 12:43:22 +02:00
0d5d15c9d1 proxmox-rest-server: improve docs
And rename enable_file_log to enable_access_log.
2021-09-30 12:29:15 +02:00
2e44983a37 proxmox-rest-server: improve docs
And renames abort_worker_async to abort_worker_nowait (avoid confusion,
because the function itself is not async).
2021-09-30 10:51:41 +02:00
c76ff4b472 proxmox-rest-server: cleanup FileLogger docs 2021-09-30 10:51:31 +02:00
aaf4f40285 subscription: switch verification domain over to shop.proxmox.com
With the merger the shop got moved from shop.maurer-it to
shop.proxmox.com, while we transparently redirect we also want to
stop doing that in a few years, so use new domain.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-30 10:28:53 +02:00
e64f77b716 cleanup: move use clause to top 2021-09-30 08:42:37 +02:00
fd1b65cc3c proxmox-rest-server: allow to catch SIGINT and SIGHUP separately
And make ServerState private.
2021-09-30 08:41:30 +02:00
11148dce43 proxmox-rtest-server: make Reloader and Reloadable private 2021-09-30 07:44:19 +02:00
38da8ca1bc proxmox-rest-server: improve logging
And rename server_state_init() into catch_shutdown_and_reload_signals().
2021-09-29 14:48:46 +02:00
a0ffd4a413 proxmox-rest-server: avoid useless call to request_shutdown
Also avoid unsafe code.
2021-09-29 14:37:07 +02:00
450105b0c3 make pbs_tools::cert not depend on pbs-buildcfg
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-29 14:11:26 +02:00
b62edce929 remove pbs_client::connect_to_localhost
It also used `CertInfo` from pbs-tools which is also server
specific.

The original helper is now in the main crate's
client_helpers instead.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-29 14:11:26 +02:00
67678ec39c add all autotraits to output_or_stdout trait object
just in case we ever need any of them in async code that
requires them and loses it because of accessing such a trait
object...

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-29 13:59:02 +02:00
bf95fba72e remove wrong calls to systemd_notify
We alrteady call systemd_notify inside the create_service future.
2021-09-29 12:04:48 +02:00
d265420025 daemon: simlify code (make it easier to use) 2021-09-29 12:04:48 +02:00
01a080215d drop pbs_tools::auth
`pbs_client::connect_to_localhost` now requires the key as
optional parameter

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2021-09-29 11:08:52 +02:00
8cf445ecc4 cleanup: make BoxedStoreFunc private
There is no need to export this type.
2021-09-29 09:55:43 +02:00
20def38e96 examples: add example for a simple rest server with a small api
show how to generally start a daemon that serves a rest api + index page

api calls are (prefixed with either /api2/json or /api2/extjs):
/		GET	listing
/ping		GET	returns "pong"
/items		GET	lists existing items
		POST	lets user create new items
/items/{id}	GET	returns the content of a single item
		PUT	updates an item
		DELETE	deletes an item

Contains a small dummy user/authinfo

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-29 09:48:47 +02:00
be5b43cb87 remove tools/async_io.rs
nothing from here is used anymore, so remove it

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-29 09:38:40 +02:00
6f0565fa60 rest-server: use hypers AddrIncoming for proxmox-backup-api
this has a 'from_listener' (tokio::net::TcpListener) since hyper 0.14.5 in
the 'tcp' feature (we use 'full', which includes that; since 0.14.13
it is not behind a feature flag anymore).

this makes it possible to create a hyper server without our
'StaticIncoming' wrapper and thus makes it unnecessary.

The only other thing we have to do is to change the Service impl from
tokio::net::TcpStream to hyper::server::conn::AddStream to fulfill the trait
requirements.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-29 09:38:40 +02:00
99940358e3 ExtJsFormatter: use ParameterError to correctly compute 'errors'
By default, 'errors' is now empty.

Depend on proxmox 0.13.5.
2021-09-28 10:19:55 +02:00
53daae8e89 proxmox-rest-server: cleanup formatter, improve docs
Use trait for OutputFormatter. This is functionally equivalent,
but more rust-like...
2021-09-28 07:45:50 +02:00
8a23ea4656 move src/backup/read_chunk.rs to pbs-datastore/src/local_chunk_reader.rs 2021-09-27 11:10:14 +02:00
c95c1c83b0 move src/backup/snapshot_reader.rs to pbs_datastore crate 2021-09-27 09:58:20 +02:00
b446fa14c5 WorkerTaskContext: make it Send + Sync 2021-09-27 09:11:38 +02:00
6d5d305d9d move src/backup/datastore.rs into pbs_datastore crate 2021-09-27 09:11:38 +02:00
af2eb422d5 tools: smart: only throw error for smartctl fatal errors
only bit 0-2 are fatal errors, bit 3-7 are used to indicate
some drive conditions. for details see the manpage of smartctl(8)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [ Thomas: resolved merge-conflict due to moved run_command ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-27 08:59:13 +02:00
bbd57396d7 proxmox-backup-manager: avoid proxmox_rest_server::init_worker_tasks() for "bashcomplete" and "printdoc" 2021-09-24 12:31:42 +02:00
0fd55b08d9 WorkerTaskContext: add shutdown_requested() and fail_on_shutdown() 2021-09-24 12:04:31 +02:00
619cd5cbcb cleanup WorkerTaskContext 2021-09-24 11:39:30 +02:00
1ec0d70d09 cleanup worker task logging
In order to avoid name conflicts with WorkerTaskContext

- renamed WorkerTask::log to WorkerTask::log_message

Note: Methods have different fuction signatures

Also renamed WorkerTask::warn to WorkerTask::log_warning for
consistency reasons.

Use the task_log!() and task_warn!() macros more often.
2021-09-24 10:34:11 +02:00
c8449217dc rename TaskState to WorkerTaskContext 2021-09-24 10:33:49 +02:00
f7348a23cd move src/server/h2service.rs into proxmox-rest-server crate 2021-09-24 10:28:17 +02:00
ae18c436dd proxmox-backup-manager: setup worker and command socket 2021-09-24 10:28:17 +02:00
b0e20a71e2 proxmox-daily-update: setup worker and command socket 2021-09-24 10:28:17 +02:00
b9700a9fe5 move worker_task.rs into proxmox-rest-server crate
Also moved pbs-datastore/src/task.rs to pbs-tools, which now depends on 'log'.
2021-09-24 10:28:17 +02:00
81867f0539 use UPID and systemd helpers from proxmox 0.13.4 2021-09-23 12:01:43 +02:00
0a33fba49c worker task: allow to configure path and owner/group
And application now needs to call init_worker_tasks() before using
worker tasks.

Notable changes:
- need to call  init_worker_tasks() before using worker tasks.
- create_task_log_dirs() ís called inside init_worker_tasks()
- removed UpidExt trait
- use atomic_open_or_create_file()
- remove pbs_config and pbs_buildcfg dependency
2021-09-23 11:59:45 +02:00
049a22a3a3 src/server/worker_task.rs: Avoid using pbs-api-type::Authid
Because we want to move worker_task.rs into proxmox-rest-server crate.
2021-09-23 11:59:25 +02:00
4d4f94dedf buildsys: better group and sort --bin arguments
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-22 16:27:37 +02:00
a844fa0ba0 move dump-catalog-shell-cli doc-helper to proxmox-backup-client crate
it's only used for generating the docs for the interactive-shell
parts of the client.

Ideally we'd avoid that whole separate binary in the first place and
let the client dump it, but we'd need to have some more elaborate
"hide this command from the help/usage" mechanisms in the CLI
helper/formatter code to make that play out more nicely.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2021-09-22 16:25:09 +02:00
564 changed files with 37026 additions and 26202 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "proxmox-backup"
version = "2.0.10"
version = "2.2.3"
authors = [
"Dietmar Maurer <dietmar@proxmox.com>",
"Dominik Csapak <d.csapak@proxmox.com>",
@ -25,9 +25,8 @@ members = [
"pbs-config",
"pbs-datastore",
"pbs-fuse-loop",
"pbs-runtime",
"proxmox-rest-server",
"proxmox-systemd",
"proxmox-rrd",
"pbs-tape",
"pbs-tools",
@ -44,32 +43,33 @@ path = "src/lib.rs"
[dependencies]
apt-pkg-native = "0.3.2"
base64 = "0.12"
base64 = "0.13"
bitflags = "1.2.1"
bytes = "1.0"
cidr = "0.2.1"
crc32fast = "1"
endian_trait = { version = "0.6", features = ["arrays"] }
env_logger = "0.7"
flate2 = "1.0"
anyhow = "1.0"
thiserror = "1.0"
futures = "0.3"
h2 = { version = "0.3", features = [ "stream" ] }
handlebars = "3.0"
hex = "0.4.3"
http = "0.2"
hyper = { version = "0.14", features = [ "full" ] }
lazy_static = "1.4"
libc = "0.2"
log = "0.4"
nix = "0.19.1"
log = "0.4.17"
nix = "0.24"
num-traits = "0.2"
once_cell = "1.3.1"
openssl = "0.10"
openssl = "0.10.38" # currently patched!
pam = "0.7"
pam-sys = "0.5"
percent-encoding = "2.1"
regex = "1.2"
rustyline = "7"
regex = "1.5.5"
rustyline = "9"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
siphasher = "0.3"
@ -77,13 +77,12 @@ syslog = "4.0"
tokio = { version = "1.6", features = [ "fs", "io-util", "io-std", "macros", "net", "parking_lot", "process", "rt", "rt-multi-thread", "signal", "time" ] }
tokio-openssl = "0.6.1"
tokio-stream = "0.1.0"
tokio-util = { version = "0.6", features = [ "codec", "io" ] }
tokio-util = { version = "0.7", features = [ "codec", "io" ] }
tower-service = "0.3.0"
udev = ">= 0.3, <0.5"
udev = "0.4"
url = "2.1"
#valgrind_request = { git = "https://github.com/edef1c/libvalgrind_request", version = "1.1.0", optional = true }
walkdir = "2"
webauthn-rs = "0.2.5"
xdg = "2.2"
nom = "5.1"
crossbeam-channel = "0.5"
@ -94,28 +93,58 @@ zstd = { version = "0.6", features = [ "bindgen" ] }
pathpatterns = "0.1.2"
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
proxmox = { version = "0.13.3", features = [ "sortable-macro", "api-macro", "cli", "router", "tfa" ] }
proxmox-acme-rs = "0.2.1"
proxmox-apt = "0.7.0"
proxmox-http = { version = "0.4.0", features = [ "client", "http-helpers", "websocket" ] }
proxmox-openid = "0.7.0"
proxmox-http = { version = "0.6.1", features = [ "client", "http-helpers", "websocket" ] }
proxmox-io = "1"
proxmox-lang = "1.1"
proxmox-router = { version = "1.2.2", features = [ "cli" ] }
proxmox-schema = { version = "1.3.1", features = [ "api-macro" ] }
proxmox-section-config = "1"
proxmox-tfa = { version = "2", features = [ "api", "api-types" ] }
proxmox-time = "1.1.2"
proxmox-uuid = "1"
proxmox-serde = "0.1"
proxmox-shared-memory = "0.2"
proxmox-sys = { version = "0.3", features = [ "sortable-macro" ] }
proxmox-compression = "0.1"
proxmox-acme-rs = "0.4"
proxmox-apt = "0.8.0"
proxmox-async = "0.4"
proxmox-openid = "0.9.0"
pbs-api-types = { path = "pbs-api-types" }
pbs-buildcfg = { path = "pbs-buildcfg" }
pbs-client = { path = "pbs-client" }
pbs-config = { path = "pbs-config" }
pbs-datastore = { path = "pbs-datastore" }
pbs-runtime = { path = "pbs-runtime" }
proxmox-rest-server = { path = "proxmox-rest-server" }
proxmox-systemd = { path = "proxmox-systemd" }
proxmox-rrd = { path = "proxmox-rrd" }
pbs-tools = { path = "pbs-tools" }
pbs-tape = { path = "pbs-tape" }
# Local path overrides
# NOTE: You must run `cargo update` after changing this for it to take effect!
[patch.crates-io]
#proxmox = { path = "../proxmox/proxmox" }
#proxmox-acme-rs = { path = "../proxmox-acme-rs" }
#proxmox-apt = { path = "../proxmox-apt" }
#proxmox-async = { path = "../proxmox/proxmox-async" }
#proxmox-compression = { path = "../proxmox/proxmox-compression" }
#proxmox-borrow = { path = "../proxmox/proxmox-borrow" }
#proxmox-fuse = { path = "../proxmox-fuse" }
#proxmox-http = { path = "../proxmox/proxmox-http" }
#proxmox-io = { path = "../proxmox/proxmox-io" }
#proxmox-lang = { path = "../proxmox/proxmox-lang" }
#proxmox-openid = { path = "../proxmox-openid-rs" }
#proxmox-router = { path = "../proxmox/proxmox-router" }
#proxmox-schema = { path = "../proxmox/proxmox-schema" }
#proxmox-section-config = { path = "../proxmox/proxmox-section-config" }
#proxmox-shared-memory = { path = "../proxmox/proxmox-shared-memory" }
#proxmox-sys = { path = "../proxmox/proxmox-sys" }
#proxmox-serde = { path = "../proxmox/proxmox-serde" }
#proxmox-tfa = { path = "../proxmox/proxmox-tfa" }
#proxmox-time = { path = "../proxmox/proxmox-time" }
#proxmox-uuid = { path = "../proxmox/proxmox-uuid" }
#pxar = { path = "../pxar" }
[features]

View File

@ -38,9 +38,8 @@ SUBCRATES := \
pbs-config \
pbs-datastore \
pbs-fuse-loop \
pbs-runtime \
proxmox-rest-server \
proxmox-systemd \
proxmox-rrd \
pbs-tape \
pbs-tools \
proxmox-backup-banner \
@ -171,14 +170,11 @@ cargo-build:
$(COMPILED_BINS) $(COMPILEDIR)/dump-catalog-shell-cli $(COMPILEDIR)/docgen: .do-cargo-build
.do-cargo-build:
$(CARGO) build $(CARGO_BUILD_ARGS) \
--bin proxmox-backup-api \
--bin proxmox-backup-proxy \
--bin proxmox-backup-manager \
--bin docgen \
--package proxmox-backup-banner \
--bin proxmox-backup-banner \
--package proxmox-backup-client \
--bin proxmox-backup-client \
--bin dump-catalog-shell-cli \
--bin proxmox-backup-debug \
--package proxmox-file-restore \
--bin proxmox-file-restore \
@ -190,7 +186,10 @@ $(COMPILED_BINS) $(COMPILEDIR)/dump-catalog-shell-cli $(COMPILEDIR)/docgen: .do-
--package proxmox-restore-daemon \
--bin proxmox-restore-daemon \
--package proxmox-backup \
--bin dump-catalog-shell-cli \
--bin docgen \
--bin proxmox-backup-api \
--bin proxmox-backup-manager \
--bin proxmox-backup-proxy \
--bin proxmox-daily-update \
--bin proxmox-file-restore \
--bin proxmox-tape \
@ -222,9 +221,6 @@ install: $(COMPILED_BINS)
install -m755 $(COMPILEDIR)/$(i) $(DESTDIR)$(LIBEXECDIR)/proxmox-backup/ ;)
$(MAKE) -C www install
$(MAKE) -C docs install
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
$(MAKE) test # HACK, only test now to avoid clobbering build files with wrong config
endif
.PHONY: upload
upload: ${SERVER_DEB} ${CLIENT_DEB} ${RESTORE_DEB} ${DOC_DEB} ${DEBUG_DEB}

View File

@ -1,3 +1,7 @@
Build & Release Notes
*********************
``rustup`` Toolchain
====================
@ -40,41 +44,44 @@ example for proxmox crate above).
Build
=====
on Debian Buster
on Debian 11 Bullseye
Setup:
1. # echo 'deb http://download.proxmox.com/debian/devel/ buster main' >> /etc/apt/sources.list.d/proxmox-devel.list
2. # sudo wget http://download.proxmox.com/debian/proxmox-ve-release-6.x.gpg -O /etc/apt/trusted.gpg.d/proxmox-ve-release-6.x.gpg
1. # echo 'deb http://download.proxmox.com/debian/devel/ bullseye main' | sudo tee /etc/apt/sources.list.d/proxmox-devel.list
2. # sudo wget https://enterprise.proxmox.com/debian/proxmox-release-bullseye.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bullseye.gpg
3. # sudo apt update
4. # sudo apt install devscripts debcargo clang
5. # git clone git://git.proxmox.com/git/proxmox-backup.git
6. # sudo mk-build-deps -ir
6. # cd proxmox-backup; sudo mk-build-deps -ir
Note: 2. may be skipped if you already added the PVE or PBS package repository
You are now able to build using the Makefile or cargo itself.
You are now able to build using the Makefile or cargo itself, e.g.::
# make deb-all
# # or for a non-package build
# cargo build --all --release
Design Notes
============
************
Here are some random thought about the software design (unless I find a better place).
Large chunk sizes
-----------------
=================
It is important to notice that large chunk sizes are crucial for
performance. We have a multi-user system, where different people can do
different operations on a datastore at the same time, and most operation
involves reading a series of chunks.
It is important to notice that large chunk sizes are crucial for performance.
We have a multi-user system, where different people can do different operations
on a datastore at the same time, and most operation involves reading a series
of chunks.
So what is the maximal theoretical speed we can get when reading a
series of chunks? Reading a chunk sequence need the following steps:
So what is the maximal theoretical speed we can get when reading a series of
chunks? Reading a chunk sequence need the following steps:
- seek to the first chunk start location
- seek to the first chunk's start location
- read the chunk data
- seek to the first chunk start location
- seek to the next chunk's start location
- read the chunk data
- ...

552
debian/changelog vendored
View File

@ -1,4 +1,554 @@
rust-proxmox-backup (2.0.10-1) UNRELEASED; urgency=medium
rust-proxmox-backup (2.2.3-1) bullseye; urgency=medium
* datastore: swap dirtying the datastore cache every 60s by just using the
available config digest to detect any changes accuratly when the actually
happen
* api: datastore list and datastore status: avoid opening datastore and
possibly iterating over namespace (for lesser privileged users), but
rather use the in-memory ACL tree directly to check if there's access to
any namespace below.
-- Proxmox Support Team <support@proxmox.com> Sat, 04 Jun 2022 16:30:05 +0200
rust-proxmox-backup (2.2.2-3) bullseye; urgency=medium
* datastore: lookup: reuse ChunkStore on stale datastore re-open
* bump tokio (async framework) dependency
-- Proxmox Support Team <support@proxmox.com> Thu, 02 Jun 2022 17:25:01 +0200
rust-proxmox-backup (2.2.2-2) bullseye; urgency=medium
* improvement of error handling when removing status files and locks from
jobs that were never executed.
-- Proxmox Support Team <support@proxmox.com> Wed, 01 Jun 2022 16:22:22 +0200
rust-proxmox-backup (2.2.2-1) bullseye; urgency=medium
* Revert "verify: allow '0' days for reverification", was already possible
by setting "ignore-verified" to false
* ui: datastore permissions: allow ACL path edit & query namespaces
* accessible group iter: allow NS descending with DATASTORE_READ privilege
* prune datastore: rework worker tak log
* prune datastore: support max-depth and improve priv checks
* ui: prune input: support opt-in recursive/max-depth field
* add prune job config and api, allowing one to setup a scheduled pruning
for a specific namespace only
* ui: add ui for prune jobs
* api: disable setting prune options in datastore.cfg and transform any
existing prune tasks from datastore config to new prune job config in a
post installation hook
* proxmox-tape: use correct api call for 'load-media-from-slot'
* avoid overly strict privilege restrictions for some API endpoints and
actions when using namespaces. Better support navigating the user
interface when only having Datastore.Admin on a (sub) namespace.
* include required privilege names in some permission errors
* docs: fix some typos
* api: status: include empty entry for stores with ns-only privs
* ui: datastore options: avoid breakage if rrd store ore active-ops cannot
be queried
* ui: datastore content: only mask the inner treeview, not the top bar on
error to allow a user to trigger a manual reload
* ui: system config: improve bottom margins and scroll behavior
-- Proxmox Support Team <support@proxmox.com> Wed, 01 Jun 2022 15:09:36 +0200
rust-proxmox-backup (2.2.1-1) bullseye; urgency=medium
* docs: update some screenshots and add new ones
* docs: port overcertificate management chapters from Proxmox VE
* ui: datastore/Summary: correctly show the io-delay chart
* ui: sync/verify jobs: use pmxDisplayEditField to fix editing
* ui: server status: use power of two base for memory and swap
* ui: use base 10 (SI) for all storage related displays
* ui: datastore selector: show maintenance mode in selector
* docs: basic maintenance mode section
* docs: storage: refer to options
* storage: add some initial namespace docs
* ui: tape restore: fix form validation for datastore mapping
* ui: namespace selector: show picker empty text if no namespace
-- Proxmox Support Team <support@proxmox.com> Tue, 17 May 2022 13:56:50 +0200
rust-proxmox-backup (2.2.0-2) bullseye; urgency=medium
* client: add CLI auto-completion callbacks for ns parameters
* ui: fix setting protection in namespace
* ui: switch summary repo status to widget toolkit one
* ui: verify outdated: disallow blank and drop wrong empty text
* docs: add namespace section to sync documentation
* ui: datastore summary: add maintenance mask for offline entries
* ui: verify/sync: allow to optionally override ID again
* prune: fix workerid issues
-- Proxmox Support Team <support@proxmox.com> Mon, 16 May 2022 19:01:13 +0200
rust-proxmox-backup (2.2.0-1) bullseye; urgency=medium
* cli: improve namespace integration in proxmox-backup-client and
proxmox-tape
* docs: tape: add information about namespaces
* api: datastore status: make counts for groups and snapshots iterate over
all accessible namespaces recursively
* ui: fix storeId casing to register store correctly, so that we can query
it again for the ACL permission path selector
* ui: trigger datastore update after maintenance mode edit
* ui: namespace selector: set queryMode to local to avoid bogus background
requests on typing
* ui: sync job: fix clearing value of remote target-namespace by mistake on
edit
* ui: remote target ns selector: add clear trigger
* ui: prune group: add namespace info to title
* fix #4001: ui: add prefix to files downloaded through the pxar browser
* ui: datastore: reload content tree on successful datastore add
* ui: datastore: allow deleting currently shown namespace
* docs: rework access control, list available privileges
* docs: access control: add "Objects and Paths" section and fix
add-permission screenshot
-- Proxmox Support Team <support@proxmox.com> Mon, 16 May 2022 11:06:05 +0200
rust-proxmox-backup (2.1.10-1) bullseye; urgency=medium
* datastore: drop bogus chunk size check, can cause trouble
* pull/sync: detect remote lack of namespace support
* pull/sync: correctly query with remote-ns as parent
* ui: sync: add reduced max-depth selector
* ui: group filter: make also local filter NS aware
* api types: set NS_MAX_DEPTH schema default to MAX_NAMESPACE_DEPTH instead
of 0
* tape: notify when arriving at end of media
* tree-wide: rename 'backup-ns' API parameters to 'ns'
* tape: add namespaces/recursion depth to tape backup jobs
* api: tape/restore: add namespace mapping
* tape: bump catalog/snapshot archive magic
* ui: tape: backup overview: show namespaces as their own level above groups
* ui: tape restore: allow simple namespace mapping
-- Proxmox Support Team <support@proxmox.com> Fri, 13 May 2022 14:26:32 +0200
rust-proxmox-backup (2.1.9-2) bullseye; urgency=medium
* api: tape restore: lock the target datastore, not the source one
* chunk store: force write chunk again if it exist but its metadata length
is zero
* completion: fix 'group-filter' parameter name
* implement backup namespaces for datastores, allowing one to reuse a single
chunkstore deduplication domain for multiple sources without naming
conflicts and with fine-grained access control.
* make various datastore related API calls backup namespace aware
* make sync and pull backup namespace aware
* ui: datastore content: show namespaces but only one level at a time
* ui: make various datastore related UI components namespace aware
* fix various bugs, add namespace support to file-restore
-- Proxmox Support Team <support@proxmox.com> Thu, 12 May 2022 14:25:53 +0200
rust-proxmox-backup (2.1.8-1) bullseye; urgency=medium
* api: status: return gc-status again
* proxmox-backup-proxy: stop accept() loop on daemon shutdown to avoid that
new request get accepted while the REST stack is already stopped, for
example on the reload triggered by a package upgrade.
* pull: improve filtering local removal candidates
-- Proxmox Support Team <support@proxmox.com> Mon, 02 May 2022 17:36:11 +0200
rust-proxmox-backup (2.1.7-1) bullseye; urgency=medium
* pbs-tape: sgutils2: check sense data when status is 'CHECK_CONDITION'
* rework & refactor datastore implementation for a more hierarchical access
structure
* datastore: implement Iterator for backup group and snapshot listing to
allow more efficient access for cases where we do not need the whole list
in memory
* pbs-client: extract: rewrite create_zip with sequential decoder
* pbs-client: extract: add top-level dir in tar.zst
* fix #3067: ui: add a separate notes view for longer markdown notes and
copy the markdown primer from Proxmox VE to Proxmox Backup Server docs
* restore-daemon: start disk initialization in parallel to the api
* restore-daemon: put blocking code into 'block_in_place'
* restore-daemon: avoid auto-pre-mounting zpools completely, the upfront
(time) cost can be to big to pay up initially, e.g., if there are many
subvolumes present, so only mount on demand.
* file-restore: add 'timeout' and 'json-error' parameter
* ui: add summary mask when in maintenance mode
* ui: update datastore's navigation icon and tooltip if it is in maintenance
mode
-- Proxmox Support Team <support@proxmox.com> Wed, 27 Apr 2022 19:53:53 +0200
rust-proxmox-backup (2.1.6-1) bullseye; urgency=medium
* api: verify: allow passing '0 days' for immediate re-verification
* fix #3103. node configuration: allow to configure default UI language
* fix #3856: tape: encryption key's password hint parameter is not optional
* re-use PROXMOX_DEBUG environment variable to control log level filter
* ui: WebAuthn: fix stopping store upgrades on destroy and decrease interval
* report: add tape, traffic control and disk infos and tune output order
* fix #3853: cli/api: add force option to tape key change-passphrase
* fix #3323: cli client: add dry-run option for backup command
* tape: make iterating over chunks to backup smarter to avoid some work
* bin: daily-update: make single checks/updates fail gracefully and log
to syslog directly instead of going through stdout indirectly.
* datastore: allow to turn of inode-sorting for chunk iteration. While inode
sorting benefits read-performance on block devices with higher latency
(e.g., spinning disks), it's also some extra work to get the metadata
required for sorting, so its a trade-off. For setups that have either very
slow or very fast metadata IO the benefits may turn into a net cost.
* docs: explain retention time for event allocation policy in more detail
* docs: add tape schedule examples
* proxmox-backup-debug api: parse parameters before sending to api
* ui: fix panel height in the dashboard for three-column view mode
* fix #3934 tape owner-selector to auth-id (user OR token)
* fix #3067: api: add support for multi-line comments in the node
configuration
* pbs-client: print error when we couldn't download previous FIDX/DIDX for
incremental change tracking
* fix #3854 add command to import a key from a file (json or paper-key
format) to proxmox-tape
* improve IO access pattern for some scenarios like TFA with high user and
login count or the file-restore-for-block-backup VM's internal driver.
* pxar create: fix anchored path pattern matching when adding entries
* docs: client: file exclusion: add note about leading slash
* rest-server: add option to rotate task logs by 'max_days' instead of
'max_files'
* pbs-datastore: add active operations tracking and use it to implement a
graceful transition into the also newly added maintenance mode (read-only
or offline) for datastores. Note that the UI implementation may still show
some rough edges if a datastore is in offline mode for maintenance.
* add new streaming-response type for API call responses and enable it for
the snapshot and task-log list, which can both get rather big. This avoids
allocation of a potentially big intermediate memory buffer and thus
overall memory usage.
* pxar: accompany existing .zip download support with a tar.zst(d) one. The
tar archive supports more file types (e.g., hard links or device nodes)
and zstd allows for a efficient but still effective compression.
-- Proxmox Support Team <support@proxmox.com> Wed, 13 Apr 2022 17:00:53 +0200
rust-proxmox-backup (2.1.5-1) bullseye; urgency=medium
* tell system allocator to always use mmap for allocations >= 128 KiB to
improve reclaimability of free'd memory to the OS and reduce peak and avg.
RSS consumption
* file restore: always wait up to 25s for the file-restore-VM to have
scanned all possible filesystems in a backup. While theoretically there
are some edge cases where the tool waits less now, most common ones should
be waiting more compared to the 12s "worst" case previously.
-- Proxmox Support Team <support@proxmox.com> Wed, 26 Jan 2022 16:23:09 +0100
rust-proxmox-backup (2.1.4-1) bullseye; urgency=medium
* config: add tls ciphers to NodeConfig
* pbs-tools: improve memory foot print of LRU Cache
* update dependencies to avoid a ref-count leak in async helpers
-- Proxmox Support Team <support@proxmox.com> Fri, 21 Jan 2022 10:48:14 +0100
rust-proxmox-backup (2.1.3-1) bullseye; urgency=medium
* fix #3618: proxmox-async: zip: add conditional EFS flag to zip files to
improve non-ascii code point extraction under windows.
* OpenID Connect login: improve error message for disabled users
* ui: tape: backup job: add second tab for group-filters to add/edit window
* ui: sync job: add second tab for group-filters to add/edit window
* ui: calendar event: add once daily example and clarify the workday one
* fix #3794: api types: set backup time (since the UNIX epoch) lower limit
to 1
* ui: fix opening settings window in datastore panel
* api: zfs: create zpool with `relatime=on` flag set
* fix #3763: disable SSL/TLS renegotiation
* node config: add email-from parameter to control notification sender
address
* ui: configuration: rename the "Authentication" tab to "Other" and add a
"General" section with HTTP-proxy and email-from settings
* datastore stats: not include the unavailable `io_ticks` for ZFS
datastores
* ui: hide RRD chart for IO delay if no `io_ticks` are returned
* fix #3058: ui: improve remote edit UX by clarifying ID vs host fields
* docs: fix some minor typos
* api-types: relax nodename API schema, make it a simple regex check like in
Proxmox VE
-- Proxmox Support Team <support@proxmox.com> Wed, 12 Jan 2022 16:49:13 +0100
rust-proxmox-backup (2.1.2-1) bullseye; urgency=medium
* docs: backup-client: fix wrong reference
* docs: remotes: note that protected flags will not be synced
* sync job: correctly apply rate limit
-- Proxmox Support Team <support@proxmox.com> Tue, 23 Nov 2021 13:56:15 +0100
rust-proxmox-backup (2.1.1-2) bullseye; urgency=medium
* docs: update and add traffic control related screenshots
* docs: mention traffic control (bandwidth limits) for sync jobs
-- Proxmox Support Team <support@proxmox.com> Mon, 22 Nov 2021 16:07:39 +0100
rust-proxmox-backup (2.1.1-1) bullseye; urgency=medium
* fix proxmox-backup-manager sync-job list
* ui, api: sync-job: allow one to configure a rate limit
* api: snapshot list: set default for 'protected' flag
* ui: datastore content: rework rendering protection state
* docs: update traffic control docs (use HumanBytes)
* ui: traffic-control: include ipv6 in 'all' networks
* ui: traffic-control edit: add spaces between networks for more
readabillity
* tape: fix passing-through key-fingerprint
* avoid a bogus error regarding logrotate-path due to a reversed check
-- Proxmox Support Team <support@proxmox.com> Mon, 22 Nov 2021 12:24:31 +0100
rust-proxmox-backup (2.1.0-1) bullseye; urgency=medium
* rest server: make successful-ticket auth log a debug one to avoid
syslog spam
* traffic-controls: add API/CLI to show current traffic
* docs: add traffic control section
* ui: use TFA widgets from widget toolkit
* sync: allow pulling groups selectively
* fix #3533: tape backup: filter groups according to config
* proxmox-tape: add missing notify-user option to backup command
* openid: allow arbitrary username-claims
* openid: support configuring the prompt, scopes and ACR values
* use human-byte for traffic-control rate-in/out and burst-in/out config
* ui: add traffic control view and editor
-- Proxmox Support Team <support@proxmox.com> Sat, 20 Nov 2021 22:44:07 +0100
rust-proxmox-backup (2.0.14-1) bullseye; urgency=medium
* fix directory permission problems
* add traffic control configuration config with API
* proxmox-backup-proxy: implement traffic control
* proxmox-backup-client: add rate/burst parameter to backup/restore CLI
* openid_login: vertify that firstname, lastname and email fits our
schema definitions
* docs: add info about protection flag to client docs
* fix #3602: ui: datastore/Content: add action to set protection status
* ui: add protected icon to snapshot (if they are protected)
* ui: PruneInputPanel: add keepReason 'protected' for protected backups
* proxmox-backup-client: add 'protected' commands
* acme: interpret no TOS as accepted
* acme: new_account: prevent replacing existing accounts
-- Proxmox Support Team <support@proxmox.com> Fri, 12 Nov 2021 08:04:55 +0100
rust-proxmox-backup (2.0.13-1) bullseye; urgency=medium
* tape: simplify export_media_set for pool writer
* tape: improve export_media error message for not found tape
* rest-server: use hashmap for parameter errors
* proxmox-rrd: use new file firmat with higher resolution
* proxmox-rrd: use a journal to reduce amount of bytes written
* use new fsync parameter to replace_file and atomic_open_or_create
* docs: langauge and formatting fixup
* docs: Update for new features/functionality
-- Proxmox Support Team <support@proxmox.com> Thu, 21 Oct 2021 08:17:00 +0200
rust-proxmox-backup (2.0.12-1) bullseye; urgency=medium
* proxmox-backup-proxy: clean up old tasks when their reference was rotated
out of the task-log index
* api daemons: fix sending log-reopen command
-- Proxmox Support Team <support@proxmox.com> Tue, 19 Oct 2021 10:48:28 +0200
rust-proxmox-backup (2.0.11-1) bullseye; urgency=medium
* drop aritifical limits for task-UPID length
* tools: smart: only throw error for the fatal usage errors of smartctl
* api: improve returning errors for extjs formatter
* proxmox-rest-server: improve logging
* subscription: switch verification domain over to shop.proxmox.com
* rest-server/daemon: use new sd_notify_barrier helper for handling
synchronization with systemd on service reloading
* ui: datastore/Content: add empty text for no snapshots
* ui: datastore/Content: move first store-load into activate listener to
ensure we've a proper loading mask for better UX
-- Proxmox Support Team <support@proxmox.com> Tue, 05 Oct 2021 16:34:14 +0200
rust-proxmox-backup (2.0.10-1) bullseye; urgency=medium
* ui: fix order of prune keep reasons

79
debian/control vendored
View File

@ -8,56 +8,77 @@ Build-Depends: debhelper (>= 12),
libstd-rust-dev,
librust-anyhow-1+default-dev,
librust-apt-pkg-native-0.3+default-dev (>= 0.3.2-~~),
librust-base64-0.12+default-dev,
librust-base64-0.13+default-dev,
librust-bitflags-1+default-dev (>= 1.2.1-~~),
librust-bytes-1+default-dev,
librust-cidr-0.2+default-dev (>= 0.2.1-~~),
librust-crc32fast-1+default-dev,
librust-crossbeam-channel-0.5+default-dev,
librust-endian-trait-0.6+arrays-dev,
librust-endian-trait-0.6+default-dev,
librust-env-logger-0.7+default-dev,
librust-env-logger-0.9+default-dev,
librust-flate2-1+default-dev,
librust-foreign-types-0.3+default-dev,
librust-futures-0.3+default-dev,
librust-h2-0.3+default-dev,
librust-h2-0.3+stream-dev,
librust-handlebars-3+default-dev,
librust-hex-0.4+default-dev (>= 0.4.3-~~),
librust-hex-0.4+serde-dev (>= 0.4.3-~~),
librust-http-0.2+default-dev,
librust-hyper-0.14+default-dev,
librust-hyper-0.14+full-dev,
librust-hyper-0.14+default-dev (>= 0.14.5-~~),
librust-hyper-0.14+full-dev (>= 0.14.5-~~),
librust-lazy-static-1+default-dev (>= 1.4-~~),
librust-libc-0.2+default-dev,
librust-log-0.4+default-dev,
librust-nix-0.19+default-dev (>= 0.19.1-~~),
librust-log-0.4+default-dev (>= 0.4.17-~~) <!nocheck>,
librust-nix-0.24+default-dev,
librust-nom-5+default-dev (>= 5.1-~~),
librust-num-traits-0.2+default-dev,
librust-once-cell-1+default-dev (>= 1.3.1-~~),
librust-openssl-0.10+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.38-~~),
librust-pam-0.7+default-dev,
librust-pam-sys-0.5+default-dev,
librust-pathpatterns-0.1+default-dev (>= 0.1.2-~~),
librust-percent-encoding-2+default-dev (>= 2.1-~~),
librust-pin-project-lite-0.2+default-dev,
librust-proxmox-0.13+api-macro-dev,
librust-proxmox-0.13+cli-dev,
librust-proxmox-0.13+default-dev,
librust-proxmox-0.13+router-dev,
librust-proxmox-0.13+sortable-macro-dev,
librust-proxmox-0.13+tfa-dev,
librust-proxmox-acme-rs-0.2+default-dev (>= 0.2.1-~~),
librust-proxmox-apt-0.7+default-dev,
librust-proxmox-acme-rs-0.4+default-dev,
librust-proxmox-apt-0.8+default-dev,
librust-proxmox-async-0.4+default-dev,
librust-proxmox-borrow-1+default-dev,
librust-proxmox-compression-0.1+default-dev (>= 0.1.1-~~),
librust-proxmox-fuse-0.1+default-dev (>= 0.1.1-~~),
librust-proxmox-http-0.4+client-dev,
librust-proxmox-http-0.4+default-dev ,
librust-proxmox-http-0.4+http-helpers-dev,
librust-proxmox-http-0.4+websocket-dev,
librust-proxmox-openid-0.7+default-dev,
librust-proxmox-http-0.6+client-dev (>= 0.6.1-~~),
librust-proxmox-http-0.6+default-dev (>= 0.6.1-~~),
librust-proxmox-http-0.6+http-helpers-dev (>= 0.6.1-~~),
librust-proxmox-http-0.6+websocket-dev (>= 0.6.1-~~),
librust-proxmox-io-1+default-dev (>= 1.0.1-~~),
librust-proxmox-io-1+tokio-dev (>= 1.0.1-~~),
librust-proxmox-lang-1+default-dev (>= 1.1-~~),
librust-proxmox-openid-0.9+default-dev,
librust-proxmox-router-1+cli-dev (>= 1.2-~~),
librust-proxmox-router-1+default-dev (>= 1.2.2-~~),
librust-proxmox-schema-1+api-macro-dev (>= 1.3.1-~~),
librust-proxmox-schema-1+default-dev (>= 1.3.1-~~),
librust-proxmox-schema-1+upid-api-impl-dev (>= 1.3.1-~~),
librust-proxmox-section-config-1+default-dev,
librust-proxmox-serde-0.1+default-dev,
librust-proxmox-shared-memory-0.2+default-dev,
librust-proxmox-sys-0.3+default-dev,
librust-proxmox-sys-0.3+logrotate-dev,
librust-proxmox-sys-0.3+sortable-macro-dev,
librust-proxmox-tfa-2+api-dev,
librust-proxmox-tfa-2+api-types-dev,
librust-proxmox-tfa-2+default-dev,
librust-proxmox-time-1+default-dev (>= 1.1.2-~~),
librust-proxmox-uuid-1+default-dev,
librust-proxmox-uuid-1+serde-dev,
librust-pxar-0.10+default-dev (>= 0.10.1-~~),
librust-pxar-0.10+tokio-io-dev (>= 0.10.1-~~),
librust-regex-1+default-dev (>= 1.2-~~),
librust-rustyline-7+default-dev,
librust-regex-1+default-dev (>= 1.5.5-~~),
librust-rustyline-9+default-dev,
librust-serde-1+default-dev,
librust-serde-1+derive-dev,
librust-serde-cbor-0.11+default-dev (>= 0.11.1-~~),
librust-serde-json-1+default-dev,
librust-siphasher-0.3+default-dev,
librust-syslog-4+default-dev,
@ -73,23 +94,23 @@ Build-Depends: debhelper (>= 12),
librust-tokio-1+rt-dev (>= 1.6-~~),
librust-tokio-1+rt-multi-thread-dev (>= 1.6-~~),
librust-tokio-1+signal-dev (>= 1.6-~~),
librust-tokio-1+sync-dev (>= 1.6-~~),
librust-tokio-1+time-dev (>= 1.6-~~),
librust-tokio-openssl-0.6+default-dev (>= 0.6.1-~~),
librust-tokio-stream-0.1+default-dev,
librust-tokio-util-0.6+codec-dev,
librust-tokio-util-0.6+default-dev,
librust-tokio-util-0.6+io-dev,
librust-tokio-util-0.7+codec-dev,
librust-tokio-util-0.7+default-dev,
librust-tokio-util-0.7+io-dev,
librust-tower-service-0.3+default-dev,
librust-udev-0.4+default-dev | librust-udev-0.3+default-dev,
librust-udev-0.4+default-dev,
librust-url-2+default-dev (>= 2.1-~~),
librust-walkdir-2+default-dev,
librust-webauthn-rs-0.2+default-dev (>= 0.2.5-~~),
librust-xdg-2+default-dev (>= 2.2-~~),
librust-zstd-0.6+bindgen-dev,
librust-zstd-0.6+default-dev,
libacl1-dev,
libfuse3-dev,
libsystemd-dev,
libsystemd-dev (>= 246-~~),
uuid-dev,
libsgutils2-dev,
bash-completion,
@ -131,7 +152,7 @@ Depends: fonts-font-awesome,
postfix | mail-transport-agent,
proxmox-backup-docs,
proxmox-mini-journalreader,
proxmox-widget-toolkit (>= 3.3-2),
proxmox-widget-toolkit (>= 3.4-3),
pve-xtermjs (>= 4.7.0-1),
sg3-utils,
smartmontools,

38
debian/postinst vendored
View File

@ -4,6 +4,14 @@ set -e
#DEBHELPER#
update_sync_job() {
job="$1"
echo "Updating sync job '$job' to make old 'remove-vanished' default explicit.."
proxmox-backup-manager sync-job update "$job" --remove-vanished true \
|| echo "Failed, please check sync.cfg manually!"
}
case "$1" in
configure)
# need to have user backup in the tape group
@ -32,6 +40,36 @@ case "$1" in
echo "Fixing up termproxy user id in task log..."
flock -w 30 /var/log/proxmox-backup/tasks/active.lock sed -i 's/:termproxy::\([^@]\+\): /:termproxy::\1@pam: /' /var/log/proxmox-backup/tasks/active || true
fi
if dpkg --compare-versions "$2" 'lt' '2.2.2~'; then
echo "moving prune schedule from datacenter config to new prune job config"
proxmox-backup-manager update-to-prune-jobs-config \
|| echo "Failed to move prune jobs, please check manually"
true
fi
if dpkg --compare-versions "$2" 'lt' '2.1.3~' && test -e /etc/proxmox-backup/sync.cfg; then
prev_job=""
# read from HERE doc because POSIX sh limitations
while read -r key value; do
if test "$key" = "sync:"; then
if test -n "$prev_job"; then
# previous job doesn't have an explicit value
update_sync_job "$prev_job"
fi
prev_job=$value
else
prev_job=""
fi
done <<EOF
$(grep -e '^sync:' -e 'remove-vanished' /etc/proxmox-backup/sync.cfg)
EOF
if test -n "$prev_job"; then
# last job doesn't have an explicit value
update_sync_job "$prev_job"
fi
fi
fi
;;

3
debian/rules vendored
View File

@ -32,9 +32,6 @@ override_dh_auto_build:
override_dh_missing:
dh_missing --fail-missing
override_dh_auto_test:
# ignore here to avoid rebuilding the binaries with the wrong target
override_dh_auto_install:
dh_auto_install -- \
PROXY_USER=backup \

View File

@ -1,31 +1,33 @@
Backup Client Usage
===================
The command line client is called :command:`proxmox-backup-client`.
The command line client for Proxmox Backup Server is called
:command:`proxmox-backup-client`.
.. _client_repository:
Backup Repository Locations
---------------------------
The client uses the following notation to specify a datastore repository
on the backup server.
The client uses the following format to specify a datastore repository
on the backup server (where username is specified in the form of user@realm):
[[username@]server[:port]:]datastore
The default value for ``username`` is ``root@pam``. If no server is specified,
the default is the local host (``localhost``).
You can specify a port if your backup server is only reachable on a different
port (e.g. with NAT and port forwarding).
You can specify a port if your backup server is only reachable on a non-default
port (for example, with NAT and port forwarding configurations).
Note that if the server is an IPv6 address, you have to write it with square
Note that if the server uses an IPv6 address, you have to write it with square
brackets (for example, `[fe80::01]`).
You can pass the repository with the ``--repository`` command line option, or
by setting the ``PBS_REPOSITORY`` environment variable.
Here some examples of valid repositories and the real values
Below are some examples of valid repositories and their corresponding real
values:
================================ ================== ================== ===========
Example User Host:Port Datastore
@ -46,8 +48,8 @@ Environment Variables
The default backup repository.
``PBS_PASSWORD``
When set, this value is used for the password required for the backup server.
You can also set this to a API token secret.
When set, this value is used as the password for the backup server.
You can also set this to an API token secret.
``PBS_PASSWORD_FD``, ``PBS_PASSWORD_FILE``, ``PBS_PASSWORD_CMD``
Like ``PBS_PASSWORD``, but read data from an open file descriptor, a file
@ -63,15 +65,14 @@ Environment Variables
a file name or from the `stdout` of a command, respectively. The first
defined environment variable from the order above is preferred.
``PBS_FINGERPRINT`` When set, this value is used to verify the server
certificate (only used if the system CA certificates cannot validate the
certificate).
``PBS_FINGERPRINT``
When set, this value is used to verify the server certificate (only used if
the system CA certificates cannot validate the certificate).
.. Note:: Passwords must be valid UTF8 an may not contain
newlines. For your convienience, we just use the first line as
password, so you can add arbitrary comments after the
first newline.
.. Note:: Passwords must be valid UTF-8 and may not contain newlines. For your
convenience, Proxmox Backup Server only uses the first line as password, so
you can add arbitrary comments after the first newline.
Output Format
@ -86,14 +87,15 @@ Creating Backups
----------------
This section explains how to create a backup from within the machine. This can
be a physical host, a virtual machine, or a container. Such backups may contain file
and image archives. There are no restrictions in this case.
be a physical host, a virtual machine, or a container. Such backups may contain
file and image archives. There are no restrictions in this case.
.. note:: If you want to backup virtual machines or containers on Proxmox VE, see :ref:`pve-integration`.
.. Note:: If you want to backup virtual machines or containers on Proxmox VE,
see :ref:`pve-integration`.
For the following example you need to have a backup server set up, working
credentials and need to know the repository name.
In the following examples we use ``backup-server:store1``.
For the following example, you need to have a backup server set up, have working
credentials, and know the repository name.
In the following examples, we use ``backup-server:store1``.
.. code-block:: console
@ -107,32 +109,32 @@ In the following examples we use ``backup-server:store1``.
Uploaded 12129 chunks in 87 seconds (564 MB/s).
End Time: 2019-12-03T10:36:29+01:00
This will prompt you for a password and then uploads a file archive named
This will prompt you for a password, then upload a file archive named
``root.pxar`` containing all the files in the ``/`` directory.
.. Caution:: Please note that the proxmox-backup-client does not
.. Caution:: Please note that proxmox-backup-client does not
automatically include mount points. Instead, you will see a short
``skip mount point`` notice for each of them. The idea is to
``skip mount point`` message for each of them. The idea is to
create a separate file archive for each mounted disk. You can
explicitly include them using the ``--include-dev`` option
(i.e. ``--include-dev /boot/efi``). You can use this option
multiple times for each mount point that should be included.
The ``--repository`` option can get quite long and is used by all
commands. You can avoid having to enter this value by setting the
environment variable ``PBS_REPOSITORY``. Note that if you would like this to remain set
over multiple sessions, you should instead add the below line to your
``.bashrc`` file.
The ``--repository`` option can get quite long and is used by all commands. You
can avoid having to enter this value by setting the environment variable
``PBS_REPOSITORY``. Note that if you would like this to remain set over
multiple sessions, you should instead add the below line to your ``.bashrc``
file.
.. code-block:: console
# export PBS_REPOSITORY=backup-server:store1
After this you can execute all commands without specifying the ``--repository``
option.
After this, you can execute all commands without having to specify the
``--repository`` option.
One single backup is allowed to contain more than one archive. For example, if
you want to backup two disks mounted at ``/mnt/disk1`` and ``/mnt/disk2``:
A single backup is allowed to contain more than one archive. For example, if
you want to back up two disks mounted at ``/mnt/disk1`` and ``/mnt/disk2``:
.. code-block:: console
@ -140,59 +142,71 @@ you want to backup two disks mounted at ``/mnt/disk1`` and ``/mnt/disk2``:
This creates a backup of both disks.
The backup command takes a list of backup specifications, which
include the archive name on the server, the type of the archive, and the
archive source at the client. The format is:
If you want to use a namespace for the backup target you can add the `--ns`
parameter:
.. code-block:: console
# proxmox-backup-client backup disk1.pxar:/mnt/disk1 disk2.pxar:/mnt/disk2 --ns a/b/c
The backup command takes a list of backup specifications, which include the
archive name on the server, the type of the archive, and the archive source at
the client. The format is:
<archive-name>.<type>:<source-path>
Common types are ``.pxar`` for file archives, and ``.img`` for block
device images. To create a backup of a block device run the following command:
Common types are ``.pxar`` for file archives and ``.img`` for block
device images. To create a backup of a block device, run the following command:
.. code-block:: console
# proxmox-backup-client backup mydata.img:/dev/mylvm/mydata
Excluding files/folders from a backup
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Excluding Files/Directories from a Backup
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sometimes it is desired to exclude certain files or folders from a backup archive.
To tell the Proxmox Backup client when and how to ignore files and directories,
place a text file called ``.pxarexclude`` in the filesystem hierarchy.
Whenever the backup client encounters such a file in a directory, it interprets
each line as glob match patterns for files and directories that are to be excluded
from the backup.
Sometimes it is desired to exclude certain files or directories from a backup
archive. To tell the Proxmox Backup client when and how to ignore files and
directories, place a text file named ``.pxarexclude`` in the filesystem
hierarchy. Whenever the backup client encounters such a file in a directory,
it interprets each line as a glob match pattern for files and directories that
are to be excluded from the backup.
The file must contain a single glob pattern per line. Empty lines are ignored.
The same is true for lines starting with ``#``, which indicates a comment.
A ``!`` at the beginning of a line reverses the glob match pattern from an exclusion
to an explicit inclusion. This makes it possible to exclude all entries in a
directory except for a few single files/subdirectories.
The file must contain a single glob pattern per line. Empty lines and lines
starting with ``#`` (indicating a comment) are ignored.
A ``!`` at the beginning of a line reverses the glob match pattern from an
exclusion to an explicit inclusion. This makes it possible to exclude all
entries in a directory except for a few single files/subdirectories.
Lines ending in ``/`` match only on directories.
The directory containing the ``.pxarexclude`` file is considered to be the root of
the given patterns. It is only possible to match files in this directory and its subdirectories.
The directory containing the ``.pxarexclude`` file is considered to be the root
of the given patterns. It is only possible to match files in this directory and
its subdirectories.
.. Note:: Patterns without a leading ``/`` will also match in subdirectories,
while patterns with a leading ``/`` will only match in the current directory.
``\`` is used to escape special glob characters.
``?`` matches any single character.
``*`` matches any character, including an empty string.
``**`` is used to match subdirectories. It can be used to, for example, exclude
all files ending in ``.tmp`` within the directory or subdirectories with the
following pattern ``**/*.tmp``.
``**`` is used to match current directory and subdirectories. For example, with
the pattern ``**/*.tmp``, it would exclude all files ending in ``.tmp`` within
a directory and its subdirectories.
``[...]`` matches a single character from any of the provided characters within
the brackets. ``[!...]`` does the complementary and matches any single character
not contained within the brackets. It is also possible to specify ranges with two
characters separated by ``-``. For example, ``[a-z]`` matches any lowercase
alphabetic character and ``[0-9]`` matches any one single digit.
the brackets. ``[!...]`` does the complementary and matches any single
character not contained within the brackets. It is also possible to specify
ranges with two characters separated by ``-``. For example, ``[a-z]`` matches
any lowercase alphabetic character, and ``[0-9]`` matches any single digit.
The order of the glob match patterns defines whether a file is included or
excluded, that is to say later entries override previous ones.
This is also true for match patterns encountered deeper down the directory tree,
which can override a previous exclusion.
Be aware that excluded directories will **not** be read by the backup client.
Thus, a ``.pxarexclude`` file in an excluded subdirectory will have no effect.
``.pxarexclude`` files are treated as regular files and will be included in the
backup archive.
excluded, that is to say, later entries override earlier ones.
This is also true for match patterns encountered deeper down the directory
tree, which can override a previous exclusion.
.. Note:: Excluded directories will **not** be read by the backup client. Thus,
a ``.pxarexclude`` file in an excluded subdirectory will have no effect.
``.pxarexclude`` files are treated as regular files and will be included in
the backup archive.
For example, consider the following directory structure:
@ -280,7 +294,7 @@ You can avoid entering the passwords by setting the environment
variables ``PBS_PASSWORD`` and ``PBS_ENCRYPTION_PASSWORD``.
Using a master key to store and recover encryption keys
Using a Master Key to Store and Recover Encryption Keys
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can also use ``proxmox-backup-client key`` to create an RSA public/private
@ -360,7 +374,7 @@ To set up a master key:
keep keys ordered and in a place that is separate from the contents being
backed up. It can happen, for example, that you back up an entire system, using
a key on that system. If the system then becomes inaccessible for any reason
and needs to be restored, this will not be possible as the encryption key will be
and needs to be restored, this will not be possible, as the encryption key will be
lost along with the broken system.
It is recommended that you keep your master key safe, but easily accessible, in
@ -382,10 +396,10 @@ version of your master key. The following command sends the output of the
Restoring Data
--------------
The regular creation of backups is a necessary step to avoiding data
loss. More importantly, however, is the restoration. It is good practice to perform
periodic recovery tests to ensure that you can access the data in
case of problems.
The regular creation of backups is a necessary step in avoiding data loss. More
importantly, however, is the restoration. It is good practice to perform
periodic recovery tests to ensure that you can access the data in case of
disaster.
First, you need to find the snapshot which you want to restore. The snapshot
list command provides a list of all the snapshots on the server:
@ -402,6 +416,11 @@ list command provides a list of all the snapshots on the server:
├────────────────────────────────┼─────────────┼────────────────────────────────────┤
...
.. tip:: List will by default only output the backup snapshots of the root
namespace itself. To list backups from another namespace use the ``--ns
<ns>`` option
You can inspect the catalog to find specific files.
.. code-block:: console
@ -444,23 +463,22 @@ to use the interactive recovery shell.
The interactive recovery shell is a minimal command line interface that
utilizes the metadata stored in the catalog to quickly list, navigate and
search files in a file archive.
search for files in a file archive.
To restore files, you can select them individually or match them with a glob
pattern.
Using the catalog for navigation reduces the overhead considerably because only
the catalog needs to be downloaded and, optionally, decrypted.
The actual chunks are only accessed if the metadata in the catalog is not enough
or for the actual restore.
The actual chunks are only accessed if the metadata in the catalog is
insufficient or for the actual restore.
Similar to common UNIX shells ``cd`` and ``ls`` are the commands used to change
Similar to common UNIX shells, ``cd`` and ``ls`` are the commands used to change
working directory and list directory contents in the archive.
``pwd`` shows the full path of the current working directory with respect to the
archive root.
Being able to quickly search the contents of the archive is a commonly needed feature.
That's where the catalog is most valuable.
For example:
The ability to quickly search the contents of the archive is a commonly required
feature. That's where the catalog is most valuable. For example:
.. code-block:: console
@ -471,8 +489,8 @@ For example:
pxar:/ > restore-selected /target/path
...
This will find and print all files ending in ``.txt`` located in ``etc/`` or a
subdirectory and add the corresponding pattern to the list for subsequent restores.
This will find and print all files ending in ``.txt`` located in ``etc/`` or its
subdirectories, and add the corresponding pattern to the list for subsequent restores.
``list-selected`` shows these patterns and ``restore-selected`` finally restores
all files in the archive matching the patterns to ``/target/path`` on the local
host. This will scan the whole archive.
@ -497,7 +515,7 @@ Mounting of Archives via FUSE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The :term:`FUSE` implementation for the pxar archive allows you to mount a
file archive as a read-only filesystem to a mountpoint on your host.
file archive as a read-only filesystem to a mount point on your host.
.. code-block:: console
@ -513,7 +531,7 @@ This allows you to access the full contents of the archive in a seamless manner.
load on your host, depending on the operations you perform on the mounted
filesystem.
To unmount the filesystem use the ``umount`` command on the mountpoint:
To unmount the filesystem, use the ``umount`` command on the mount point:
.. code-block:: console
@ -522,7 +540,7 @@ To unmount the filesystem use the ``umount`` command on the mountpoint:
Login and Logout
----------------
The client tool prompts you to enter the logon password as soon as you
The client tool prompts you to enter the login password as soon as you
want to access the backup server. The server checks your credentials
and responds with a ticket that is valid for two hours. The client
tool automatically stores that ticket and uses it for further requests
@ -560,10 +578,10 @@ user that has ``Datastore.Modify`` privileges on the datastore.
# proxmox-backup-client change-owner vm/103 john@pbs
This can also be done from within the web interface, by navigating to the
`Content` section of the datastore that contains the backup group and
selecting the user icon under the `Actions` column. Common cases for this could
be to change the owner of a sync job from ``root@pam``, or to repurpose a
backup group.
`Content` section of the datastore that contains the backup group and selecting
the user icon under the `Actions` column. Common cases for this could be to
change the owner of a sync job from ``root@pam``, or to repurpose a backup
group.
.. _backup-pruning:
@ -571,16 +589,24 @@ backup group.
Pruning and Removing Backups
----------------------------
You can manually delete a backup snapshot using the ``forget``
command:
You can manually delete a backup snapshot using the ``forget`` command:
.. code-block:: console
# proxmox-backup-client snapshot forget <snapshot>
.. caution:: This command removes all archives in this backup
snapshot. They will be inaccessible and unrecoverable.
.. caution:: This command removes all archives in this backup snapshot. They
will be inaccessible and *unrecoverable*.
Don't forget to add the namespace ``--ns`` parameter if you want to forget a
snapshot that is contained in the root namespace:
.. code-block:: console
# proxmox-backup-client snapshot forget <snapshot> --ns <ns>
Although manual removal is sometimes required, the ``prune``
@ -652,6 +678,25 @@ shows the list of existing snapshots and what actions prune would take.
in the chunk-store. The chunk-store still contains the data blocks. To free
space you need to perform :ref:`client_garbage-collection`.
It is also possible to protect single snapshots from being pruned or deleted:
.. code-block:: console
# proxmox-backup-client snapshot protected update <snapshot> true
This will set the protected flag on the snapshot and prevent pruning or manual
deletion of this snapshot untilt he flag is removed again with:
.. code-block:: console
# proxmox-backup-client snapshot protected update <snapshot> false
When a group is with a protected snapshot is deleted, only the non-protected
ones are removed and the group will remain.
.. note:: This flag will not be synced when using pull or sync jobs. If you
want to protect a synced snapshot, you have to manually to this again on
the target backup server.
.. _client_garbage-collection:
@ -677,7 +722,7 @@ unused data blocks are removed.
(access time) property. Filesystems are mounted with the ``relatime`` option
by default. This results in a better performance by only updating the
``atime`` property if the last access has been at least 24 hours ago. The
downside is, that touching a chunk within these 24 hours will not always
downside is that touching a chunk within these 24 hours will not always
update its ``atime`` property.
Chunks in the grace period will be logged at the end of the garbage
@ -701,8 +746,8 @@ unused data blocks are removed.
Average chunk size: 2486565
TASK OK
.. todo:: howto run garbage-collection at regular intervals (cron)
Garbage collection can also be scheduled using ``promxox-backup-manager`` or
from the Proxmox Backup Server's web interface.
Benchmarking
------------

View File

@ -1,10 +1,10 @@
Backup Protocol
===============
Proxmox Backup Server uses a REST based API. While the management
interface use normal HTTP, the actual backup and restore interface use
Proxmox Backup Server uses a REST-based API. While the management
interface uses normal HTTP, the actual backup and restore interface uses
HTTP/2 for improved performance. Both HTTP and HTTP/2 are well known
standards, so the following section assumes that you are familiar on
standards, so the following section assumes that you are familiar with
how to use them.
@ -13,35 +13,35 @@ Backup Protocol API
To start a new backup, the API call ``GET /api2/json/backup`` needs to
be upgraded to a HTTP/2 connection using
``proxmox-backup-protocol-v1`` as protocol name::
``proxmox-backup-protocol-v1`` as the protocol name::
GET /api2/json/backup HTTP/1.1
UPGRADE: proxmox-backup-protocol-v1
The server replies with HTTP 101 Switching Protocol status code,
and you can then issue REST commands on that updated HTTP/2 connection.
The server replies with the ``HTTP 101 Switching Protocol`` status code,
and you can then issue REST commands on the updated HTTP/2 connection.
The backup protocol allows you to upload three different kind of files:
- Chunks and blobs (binary data)
- Fixed Indexes (List of chunks with fixed size)
- Fixed indexes (List of chunks with fixed size)
- Dynamic Indexes (List of chunk with variable size)
- Dynamic indexes (List of chunks with variable size)
The following section gives a short introduction how to upload such
The following section provides a short introduction on how to upload such
files. Please use the `API Viewer <api-viewer/index.html>`_ for
details about available REST commands.
details about the available REST commands.
Upload Blobs
~~~~~~~~~~~~
Uploading blobs is done using ``POST /blob``. The HTTP body contains the
data encoded as :ref:`Data Blob <data-blob-format>`).
Blobs are uploaded using ``POST /blob``. The HTTP body contains the
data encoded as :ref:`Data Blob <data-blob-format>`.
The file name needs to end with ``.blob``, and is automatically added
to the backup manifest.
The file name must end with ``.blob``, and is automatically added
to the backup manifest, following the call to ``POST /finish``.
Upload Chunks
@ -56,40 +56,41 @@ encoded as :ref:`Data Blob <data-blob-format>`).
Upload Fixed Indexes
~~~~~~~~~~~~~~~~~~~~
Fixed indexes are use to store VM image data. The VM image is split
Fixed indexes are used to store VM image data. The VM image is split
into equally sized chunks, which are uploaded individually. The index
file simply contains a list to chunk digests.
file simply contains a list of chunk digests.
You create a fixed index with ``POST /fixed_index``. Then upload
You create a fixed index with ``POST /fixed_index``. Then, upload
chunks with ``POST /fixed_chunk``, and append them to the index with
``PUT /fixed_index``. When finished, you need to close the index using
``POST /fixed_close``.
The file name needs to end with ``.fidx``, and is automatically added
to the backup manifest.
to the backup manifest, following the call to ``POST /finish``.
Upload Dynamic Indexes
~~~~~~~~~~~~~~~~~~~~~~
Dynamic indexes are use to store file archive data. The archive data
Dynamic indexes are used to store file archive data. The archive data
is split into dynamically sized chunks, which are uploaded
individually. The index file simply contains a list to chunk digests
individually. The index file simply contains a list of chunk digests
and offsets.
You create a dynamic sized index with ``POST /dynamic_index``. Then
You can create a dynamically sized index with ``POST /dynamic_index``. Then,
upload chunks with ``POST /dynamic_chunk``, and append them to the index with
``PUT /dynamic_index``. When finished, you need to close the index using
``POST /dynamic_close``.
The file name needs to end with ``.didx``, and is automatically added
to the backup manifest.
The filename needs to end with ``.didx``, and is automatically added
to the backup manifest, following the call to ``POST /finish``.
Finish Backup
~~~~~~~~~~~~~
Once you have uploaded all data, you need to call ``POST
/finish``. This commits all data and ends the backup protocol.
Once you have uploaded all data, you need to call ``POST /finish``. This
commits all data and ends the backup protocol.
Restore/Reader Protocol API
@ -102,39 +103,39 @@ be upgraded to a HTTP/2 connection using
GET /api2/json/reader HTTP/1.1
UPGRADE: proxmox-backup-reader-protocol-v1
The server replies with HTTP 101 Switching Protocol status code,
The server replies with the ``HTTP 101 Switching Protocol`` status code,
and you can then issue REST commands on that updated HTTP/2 connection.
The reader protocol allows you to download three different kind of files:
The reader protocol allows you to download three different kinds of files:
- Chunks and blobs (binary data)
- Fixed Indexes (List of chunks with fixed size)
- Fixed indexes (list of chunks with fixed size)
- Dynamic Indexes (List of chunk with variable size)
- Dynamic indexes (list of chunks with variable size)
The following section gives a short introduction how to download such
The following section provides a short introduction on how to download such
files. Please use the `API Viewer <api-viewer/index.html>`_ for details about
available REST commands.
the available REST commands.
Download Blobs
~~~~~~~~~~~~~~
Downloading blobs is done using ``GET /download``. The HTTP body contains the
Blobs are downloaded using ``GET /download``. The HTTP body contains the
data encoded as :ref:`Data Blob <data-blob-format>`.
Download Chunks
~~~~~~~~~~~~~~~
Downloading chunks is done using ``GET /chunk``. The HTTP body contains the
data encoded as :ref:`Data Blob <data-blob-format>`).
Chunks are downloaded using ``GET /chunk``. The HTTP body contains the
data encoded as :ref:`Data Blob <data-blob-format>`.
Download Index Files
~~~~~~~~~~~~~~~~~~~~
Downloading index files is done using ``GET /download``. The HTTP body
Index files are downloaded using ``GET /download``. The HTTP body
contains the data encoded as :ref:`Fixed Index <fixed-index-format>`
or :ref:`Dynamic Index <dynamic-index-format>`.

View File

@ -37,7 +37,7 @@ Each field can contain multiple values in the following formats:
* and a combination of the above: e.g., 01,05..10,12/02
* or a `*` for every possible value: e.g., \*:00
There are some special values that have specific meaning:
There are some special values that have a specific meaning:
================================= ==============================
Value Syntax
@ -81,19 +81,19 @@ Not all features of systemd calendar events are implemented:
* no Unix timestamps (e.g. `@12345`): instead use date and time to specify
a specific point in time
* no timezone: all schedules use the set timezone on the server
* no timezone: all schedules use the timezone of the server
* no sub-second resolution
* no reverse day syntax (e.g. 2020-03~01)
* no repetition of ranges (e.g. 1..10/2)
Notes on scheduling
Notes on Scheduling
-------------------
In `Proxmox Backup`_ scheduling for most tasks is done in the
In `Proxmox Backup`_, scheduling for most tasks is done in the
`proxmox-backup-proxy`. This daemon checks all job schedules
if they are due every minute. This means that even if
every minute, to see if any are due. This means that even though
`calendar events` can contain seconds, it will only be checked
once a minute.
once per minute.
Also, all schedules will be checked against the timezone set
in the `Proxmox Backup`_ server.

View File

@ -0,0 +1,333 @@
.. _sysadmin_certificate_management:
Certificate Management
----------------------
Access to the API and thus the web-based administration interface is always
encrypted through ``https``. Each `Proxmox Backup`_ host creates by default its
own (self-signed) certificate. This certificate is used for encrypted
communication with the hosts ``proxmox-backup-proxy`` service, for any API
call between a user or backup-client and the web-interface.
Certificate verification when sending backups to a `Proxmox Backup`_ server
is either done based on pinning the certificate fingerprints in the storage/remote
configuration, or by using certificates, signed by a trusted certificate authority.
.. _sysadmin_certs_api_gui:
Certificates for the API and SMTP
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`Proxmox Backup`_ stores it certificate and key in:
- ``/etc/proxmox-backup/proxy.pem``
- ``/etc/proxmox-backup/proxy.key``
You have the following options for the certificate:
1. Keep using the default self-signed certificate in
``/etc/proxmox-backup/proxy.pem``.
2. Use an externally provided certificate (for example, signed by a
commercial Certificate Authority (CA)).
3. Use an ACME provider like Lets Encrypt to get a trusted certificate
with automatic renewal; this is also integrated in the `Proxmox Backup`_
API and web interface.
Certificates are managed through the `Proxmox Backup`_
web-interface/API or using the the ``proxmox-backup-manager`` CLI tool.
.. _sysadmin_certs_upload_custom:
Upload Custom Certificate
~~~~~~~~~~~~~~~~~~~~~~~~~
If you already have a certificate which you want to use for a Proxmox
Mail Gateway host, you can simply upload that certificate over the web
interface.
.. image:: images/screenshots/pbs-gui-certs-upload-custom.png
:align: right
:alt: Upload a custom certificate
Note that any certificate key files must not be password protected.
.. _sysadmin_certs_get_trusted_acme_cert:
Trusted certificates via Lets Encrypt (ACME)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`Proxmox Backup`_ includes an implementation of the **A**\ utomatic
**C**\ ertificate **M**\ anagement **E**\ nvironment (**ACME**)
protocol, allowing `Proxmox Backup`_ admins to use an ACME provider
like Lets Encrypt for easy setup of TLS certificates, which are
accepted and trusted by modern operating systems and web browsers out of
the box.
Currently, the two ACME endpoints implemented are the `Lets Encrypt
(LE) <https://letsencrypt.org>`_ production and staging environments.
Our ACME client supports validation of ``http-01`` challenges using a
built-in web server and validation of ``dns-01`` challenges using a DNS
plugin supporting all the DNS API endpoints
`acme.sh <https://acme.sh>`_ does.
.. _sysadmin_certs_acme_account:
ACME Account
^^^^^^^^^^^^
.. image:: images/screenshots/pbs-gui-acme-create-account.png
:align: right
:alt: Create ACME Account
You need to register an ACME account per cluster, with the endpoint you
want to use. The email address used for that account will serve as the
contact point for renewal-due or similar notifications from the ACME
endpoint.
You can register or deactivate ACME accounts over the web interface
``Certificates -> ACME Accounts`` or using the ``proxmox-backup-manager`` command
line tool.
::
proxmox-backup-manager acme account register <account-name> <mail@example.com>
.. tip::
Because of
`rate-limits <https://letsencrypt.org/docs/rate-limits/>`_ you
should use LE ``staging`` for experiments or if you use ACME for the
very first time until all is working there, and only then switch over
to the production directory.
.. _sysadmin_certs_acme_plugins:
ACME Plugins
^^^^^^^^^^^^
The ACME plugins role is to provide automatic verification that you,
and thus the `Proxmox Backup`_ server under your operation, are the
real owner of a domain. This is the basic building block of automatic
certificate management.
The ACME protocol specifies different types of challenges, for example
the ``http-01``, where a web server provides a file with a specific
token to prove that it controls a domain. Sometimes this isnt possible,
either because of technical limitations or if the address of a record is
not reachable from the public internet. The ``dns-01`` challenge can be
used in such cases. This challenge is fulfilled by creating a certain
DNS record in the domains zone.
.. image:: images/screenshots/pbs-gui-acme-create-challenge-plugin.png
:align: right
:alt: Create ACME Account
`Proxmox Backup`_ supports both of those challenge types out of the
box, you can configure plugins either over the web interface under
``Certificates -> ACME Challenges``, or using the
``proxmox-backup-manager acme plugin add`` command.
ACME Plugin configurations are stored in ``/etc/proxmox-backup/acme/plugins.cfg``.
.. _domains:
Domains
^^^^^^^
You can add new or manage existing domain entries under
``Certificates``, or using the ``proxmox-backup-manager`` command.
.. image:: images/screenshots/pbs-gui-acme-add-domain.png
:align: right
:alt: Add a Domain for ACME verification
After configuring the desired domain(s) for a node and ensuring that the
desired ACME account is selected, you can order your new certificate
over the web-interface. On success, the interface will reload after
roughly 10 seconds.
Renewal will happen `automatically <#sysadmin-certs-acme-automatic-renewal>`_
.. _sysadmin_certs_acme_http_challenge:
ACME HTTP Challenge Plugin
~~~~~~~~~~~~~~~~~~~~~~~~~~
There is always an implicitly configured ``standalone`` plugin for
validating ``http-01`` challenges via the built-in web server spawned on
port 80.
.. note::
The name ``standalone`` means that it can provide the validation on
its own, without any third party service.
There are a few prerequisites to use this for certificate management
with Lets Encrypts ACME.
- You have to accept the ToS of Lets Encrypt to register an account.
- **Port 80** of the node needs to be reachable from the internet.
- There **must** be no other listener on port 80.
- The requested (sub)domain needs to resolve to a public IP of the
`Proxmox Backup`_ host.
.. _sysadmin_certs_acme_dns_challenge:
ACME DNS API Challenge Plugin
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On systems where external access for validation via the ``http-01``
method is not possible or desired, it is possible to use the ``dns-01``
validation method. This validation method requires a DNS server that
allows provisioning of ``TXT`` records via an API.
.. _sysadmin_certs_acme_dns_api_config:
Configuring ACME DNS APIs for validation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
`Proxmox Backup`_ re-uses the DNS plugins developed for the
``acme.sh`` [1]_ project. Please refer to its documentation for details
on configuration of specific APIs.
The easiest way to configure a new plugin with the DNS API is using the
web interface (``Certificates -> ACME Accounts/Challenges``).
Here you can add a new challenge plugin by selecting your API provider
and entering the credential data to access your account over their API.
.. tip::
See the acme.sh `How to use DNS
API <https://github.com/acmesh-official/acme.sh/wiki/dnsapi#how-to-use-dns-api>`_
wiki for more detailed information about getting API credentials for
your provider. Configuration values do not need to be quoted with
single or double quotes; for some plugins that is even an error.
As there are many DNS providers and API endpoints, `Proxmox Backup`_
automatically generates the form for the credentials, but not all
providers are annotated yet. For those you will see a bigger text area,
into which you simply need to copy all the credentials
``KEY``\ =\ ``VALUE`` pairs.
.. _dns_validation_through_cname_alias:
DNS Validation through CNAME Alias
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A special ``alias`` mode can be used to handle validation on a different
domain/DNS server, in case your primary/real DNS does not support
provisioning via an API. Manually set up a permanent ``CNAME`` record
for ``_acme-challenge.domain1.example`` pointing to
``_acme-challenge.domain2.example``, and set the ``alias`` property in
the `Proxmox Backup`_ node configuration file ``/etc/proxmox-backup/node.cfg``
to ``domain2.example`` to allow the DNS server of ``domain2.example`` to
validate all challenges for ``domain1.example``.
.. _sysadmin_certs_acme_dns_wildcard:
Wildcard Certificates
^^^^^^^^^^^^^^^^^^^^^
Wildcard DNS names start with a ``*.`` prefix and are considered valid
for all (one-level) subdomain names of the verified domain. So a
certificate for ``*.domain.example`` is valid for ``foo.domain.example``
and ``bar.domain.example``, but not for ``baz.foo.domain.example``.
Currently, you can only create wildcard certificates with the `DNS
challenge
type <https://letsencrypt.org/docs/challenge-types/#dns-01-challenge>`_.
.. _combination_of_plugins:
Combination of Plugins
^^^^^^^^^^^^^^^^^^^^^^
Combining ``http-01`` and ``dns-01`` validation is possible in case your
node is reachable via multiple domains with different requirements / DNS
provisioning capabilities. Mixing DNS APIs from multiple providers or
instances is also possible by specifying different plugin instances per
domain.
.. tip::
Accessing the same service over multiple domains increases complexity
and should be avoided if possible.
.. _sysadmin_certs_acme_automatic_renewal:
Automatic renewal of ACME certificates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If a node has been successfully configured with an ACME-provided
certificate (either via ``proxmox-backup-manager`` or via the web-interface/API), the
certificate will be renewed automatically by the ``proxmox-backup-daily-update.service``.
Currently, renewal is triggered if the certificate either has already
expired or if it will expire in the next 30 days.
.. _manually_change_certificate_over_command_line:
Manually Change Certificate over Command-Line
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you want to get rid of certificate verification warnings, you have to
generate a valid certificate for your server.
Log in to your `Proxmox Backup`_ via ssh or use the console:
::
openssl req -newkey rsa:2048 -nodes -keyout key.pem -out req.pem
Follow the instructions on the screen, for example:
::
Country Name (2 letter code) [AU]: AT
State or Province Name (full name) [Some-State]:Vienna
Locality Name (eg, city) []:Vienna
Organization Name (eg, company) [Internet Widgits Pty Ltd]: Proxmox GmbH
Organizational Unit Name (eg, section) []:Proxmox Backup
Common Name (eg, YOUR name) []: yourproxmox.yourdomain.com
Email Address []:support@yourdomain.com
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []: not necessary
An optional company name []: not necessary
After you have finished the certificate request, you have to send the
file ``req.pem`` to your Certification Authority (CA). The CA will issue
the certificate (BASE64 encoded), based on your request save this file
as ``cert.pem`` to your `Proxmox Backup`_.
To activate the new certificate, do the following on your `Proxmox Backup`_
::
cp key.pem /etc/proxmox-backup/proxy.key
cp cert.pem /etc/proxmox-backup/proxy.pem
Then restart the API servers:
::
systemctl restart proxmox-backup-proxy
Test your new certificate, using your browser.
.. note::
To transfer files to and from your `Proxmox Backup`_, you can use
secure copy: If your desktop runs Linux, you can use the ``scp``
command line tool. If your desktop PC runs windows, please use an scp
client like WinSCP (see https://winscp.net/).
.. [1]
acme.sh https://github.com/acmesh-official/acme.sh

View File

@ -6,22 +6,37 @@ Command Line Tools
.. include:: proxmox-backup-client/description.rst
``proxmox-file-restore``
~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: proxmox-file-restore/description.rst
``proxmox-backup-manager``
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: proxmox-backup-manager/description.rst
``proxmox-tape``
~~~~~~~~~~~~~~~~
.. include:: proxmox-tape/description.rst
``pmt``
~~~~~~~
.. include:: pmt/description.rst
``pmtx``
~~~~~~~~
.. include:: pmtx/description.rst
``pxar``
~~~~~~~~
.. include:: pxar/description.rst
``proxmox-file-restore``
~~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: proxmox-file-restore/description.rst
``proxmox-backup-debug``
~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~
.. include:: proxmox-backup-debug/description.rst

View File

@ -10,7 +10,7 @@ Command Syntax
Catalog Shell Commands
~~~~~~~~~~~~~~~~~~~~~~
Those command are available when you start an interactive restore shell:
The following commands are available in an interactive restore shell:
.. code-block:: console
@ -51,3 +51,13 @@ Those command are available when you start an interactive restore shell:
--------
.. include:: pxar/synopsis.rst
``proxmox-file-restore``
------------------------
.. include:: proxmox-file-restore/synopsis.rst
``proxmox-backup-debug``
------------------------
.. include:: proxmox-backup-debug/synopsis.rst

View File

@ -77,7 +77,7 @@ project = 'Proxmox Backup'
copyright = '2019-2021, Proxmox Server Solutions GmbH'
author = 'Proxmox Support Team'
# The version info for the project you're documenting, acts as replacement for
# The version info for the project you're documenting, acts as a replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
@ -108,11 +108,14 @@ today_fmt = '%A, %d %B %Y'
exclude_patterns = [
'_build', 'Thumbs.db', '.DS_Store',
'*/man1.rst',
'certificate-management.rst',
'config/*/man5.rst',
'epilog.rst',
'pbs-copyright.rst',
'local-zfs.rst'
'local-zfs.rst',
'package-repositories.rst',
'system-booting.rst',
'traffic-control.rst',
]
# The reST default role (used for this markup: `text`) to use for all

View File

@ -2,13 +2,13 @@ This file contains the access control list for the Proxmox Backup
Server API.
Each line starts with ``acl:``, followed by 4 additional values
separated by collon.
separated by colon.
:propagate: Propagate permissions down the hierachrchy
:propagate: Propagate permissions down the hierarchy
:path: The object path
:User/Token: List of users and token
:User/Token: List of users and tokens
:Role: List of assigned roles

View File

@ -1,5 +1,5 @@
The file contains a list of datastore configuration sections. Each
section starts with a header ``datastore: <name>``, followed by the
This file contains a list of datastore configuration sections. Each
section starts with the header ``datastore: <name>``, followed by the
datastore configuration options.
::

View File

@ -1,4 +1,4 @@
Each entry starts with a header ``pool: <name>``, followed by the
Each entry starts with the header ``pool: <name>``, followed by the
media pool configuration options.
::

View File

@ -1,6 +1,6 @@
This file contains information used to access remote servers.
Each entry starts with a header ``remote: <name>``, followed by the
Each entry starts with the header ``remote: <name>``, followed by the
remote configuration options.
::

View File

@ -1,4 +1,4 @@
Each entry starts with a header ``sync: <name>``, followed by the
Each entry starts with the header ``sync: <name>``, followed by the
job configuration options.
::

View File

@ -1,4 +1,4 @@
Each entry starts with a header ``backup: <name>``, followed by the
Each entry starts with the header ``backup: <name>``, followed by the
job configuration options.
::

View File

@ -1,7 +1,7 @@
Each LTO drive configuration section starts with a header ``lto: <name>``,
Each LTO drive configuration section starts with the header ``lto: <name>``,
followed by the drive configuration options.
Tape changer configurations starts with ``changer: <name>``,
Tape changer configurations start with the header ``changer: <name>``,
followed by the changer configuration options.
::
@ -18,5 +18,5 @@ followed by the changer configuration options.
You can use the ``proxmox-tape drive`` and ``proxmox-tape changer``
commands to manipulate this file.
.. NOTE:: The ``virtual:`` drive type is experimental and onyl used
.. NOTE:: The ``virtual:`` drive type is experimental and should only be used
for debugging.

View File

@ -1,9 +1,9 @@
This file contains the list of API users and API tokens.
Each user configuration section starts with a header ``user: <name>``,
Each user configuration section starts with the header ``user: <name>``,
followed by the user configuration options.
API token configuration starts with a header ``token:
API token configuration starts with the header ``token:
<userid!token_name>``, followed by the token configuration. The data
used to authenticate tokens is stored in a separate file
(``token.shadow``).

View File

@ -1,4 +1,4 @@
Each entry starts with a header ``verification: <name>``, followed by the
Each entry starts with the header ``verification: <name>``, followed by the
job configuration options.
::

View File

@ -1,7 +1,7 @@
Configuration Files
===================
All Proxmox Backup Server configuration files resides inside directory
All Proxmox Backup Server configuration files reside in the directory
``/etc/proxmox-backup/``.

View File

@ -13,7 +13,6 @@
.. _Proxmox: https://www.proxmox.com
.. _Proxmox Community Forum: https://forum.proxmox.com
.. _Proxmox Virtual Environment: https://www.proxmox.com/proxmox-ve
.. FIXME
.. _Proxmox Backup: https://pbs.proxmox.com/wiki/index.php/Main_Page
.. _PBS Development List: https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
.. _reStructuredText: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html
@ -23,6 +22,7 @@
.. _Virtual machine: https://en.wikipedia.org/wiki/Virtual_machine
.. _APT: http://en.wikipedia.org/wiki/Advanced_Packaging_Tool
.. _QEMU: https://www.qemu.org/
.. _LXC: https://linuxcontainers.org/lxc/introduction/
.. _Client-server model: https://en.wikipedia.org/wiki/Client-server_model
.. _AE: https://en.wikipedia.org/wiki/Authenticated_encryption
@ -35,7 +35,7 @@
.. _ZFS: https://en.wikipedia.org/wiki/ZFS
.. _Proxmox VE: https://pve.proxmox.com
.. _RFC3399: https://tools.ietf.org/html/rfc3339
.. _RFC3339: https://tools.ietf.org/html/rfc3339
.. _UTC: https://en.wikipedia.org/wiki/Coordinated_Universal_Time
.. _ISO Week date: https://en.wikipedia.org/wiki/ISO_week_date

View File

@ -29,7 +29,7 @@ How long will my Proxmox Backup Server version be supported?
+=======================+======================+===============+============+====================+
|Proxmox Backup 2.x | Debian 11 (Bullseye) | 2021-07 | tba | tba |
+-----------------------+----------------------+---------------+------------+--------------------+
|Proxmox Backup 1.x | Debian 10 (Buster) | 2020-11 | ~Q2/2022 | Q2-Q3/2022 |
|Proxmox Backup 1.x | Debian 10 (Buster) | 2020-11 | 2022-08 | 2022-07 |
+-----------------------+----------------------+---------------+------------+--------------------+
@ -69,6 +69,6 @@ be able to read the data.
Is the backup incremental/deduplicated?
---------------------------------------
With Proxmox Backup Server, backups are sent incremental and data is
deduplicated on the server.
This minimizes both the storage consumed and the network impact.
With Proxmox Backup Server, backups are sent incrementally to the server, and
data is then deduplicated on the server. This minimizes both the storage
consumed and the impact on the network.

View File

@ -14,7 +14,8 @@ Proxmox File Archive Format (``.pxar``)
Data Blob Format (``.blob``)
----------------------------
The data blob format is used to store small binary data. The magic number decides the exact format:
The data blob format is used to store small binary data. The magic number
decides the exact format:
.. list-table::
:widths: auto
@ -32,7 +33,8 @@ The data blob format is used to store small binary data. The magic number decide
- encrypted
- compressed
Compression algorithm is ``zstd``. Encryption cipher is ``AES_256_GCM``.
The compression algorithm used is ``zstd``. The encryption cipher is
``AES_256_GCM``.
Unencrypted blobs use the following format:
@ -43,9 +45,9 @@ Unencrypted blobs use the following format:
* - ``CRC32: [u8; 4]``
* - ``Data: (max 16MiB)``
Encrypted blobs additionally contains a 16 byte IV, followed by a 16
byte Authenticated Encyryption (AE) tag, followed by the encrypted
data:
Encrypted blobs additionally contain a 16 byte initialization vector (IV),
followed by a 16 byte authenticated encryption (AE) tag, followed by the
encrypted data:
.. list-table::
@ -72,19 +74,19 @@ All numbers are stored as little-endian.
* - ``ctime: i64``,
- Creation Time (epoch)
* - ``index_csum: [u8; 32]``,
- Sha256 over the index (without header) ``SHA256(digest1||digest2||...)``
- SHA-256 over the index (without header) ``SHA256(digest1||digest2||...)``
* - ``size: u64``,
- Image size
* - ``chunk_size: u64``,
- Chunk size
* - ``reserved: [u8; 4016]``,
- overall header size is one page (4096 bytes)
- Overall header size is one page (4096 bytes)
* - ``digest1: [u8; 32]``
- first chunk digest
- First chunk digest
* - ``digest2: [u8; 32]``
- next chunk
- Second chunk digest
* - ...
- next chunk ...
- Next chunk digest ...
.. _dynamic-index-format:
@ -103,16 +105,16 @@ All numbers are stored as little-endian.
* - ``ctime: i64``,
- Creation Time (epoch)
* - ``index_csum: [u8; 32]``,
- Sha256 over the index (without header) ``SHA256(offset1||digest1||offset2||digest2||...)``
- SHA-256 over the index (without header) ``SHA256(offset1||digest1||offset2||digest2||...)``
* - ``reserved: [u8; 4032]``,
- Overall header size is one page (4096 bytes)
* - ``offset1: u64``
- End of first chunk
* - ``digest1: [u8; 32]``
- first chunk digest
- First chunk digest
* - ``offset2: u64``
- End of second chunk
* - ``digest2: [u8; 32]``
- second chunk digest
- Second chunk digest
* - ...
- next chunk offset/digest
- Next chunk offset/digest

View File

@ -11,7 +11,7 @@ Glossary
`Container`_
A container is an isolated user space. Programs run directly on
the host's kernel, but with limited access to the host resources.
the host's kernel, but with limited access to the host's resources.
Datastore
@ -23,19 +23,19 @@ Glossary
Rust is a new, fast and memory-efficient system programming
language. It has no runtime or garbage collector. Rusts rich type
system and ownership model guarantee memory-safety and
thread-safety. I can eliminate many classes of bugs
thread-safety. This can eliminate many classes of bugs
at compile-time.
`Sphinx`_
Is a tool that makes it easy to create intelligent and
beautiful documentation. It was originally created for the
documentation of the Python programming language. It has excellent facilities for the
Is a tool that makes it easy to create intelligent and nicely formatted
documentation. It was originally created for the documentation of the
Python programming language. It has excellent facilities for the
documentation of software projects in a range of languages.
`reStructuredText`_
Is an easy-to-read, what-you-see-is-what-you-get plaintext
Is an easy-to-read, what-you-see-is-what-you-get, plaintext
markup syntax and parser system.
`FUSE`

View File

@ -8,8 +8,9 @@ tools. The web interface also provides a built-in console, so if you prefer the
command line or need some extra control, you have this option.
The web interface can be accessed via https://youripaddress:8007. The default
login is `root`, and the password is the one specified during the installation
process.
login is `root`, and the password is either the one specified during the
installation process or the password of the root user, in case of installation
on top of Debian.
Features
@ -48,12 +49,13 @@ GUI Overview
The Proxmox Backup Server web interface consists of 3 main sections:
* **Header**: At the top. This shows version information, and contains buttons to view
documentation, monitor running tasks, set the language and logout.
* **Sidebar**: On the left. This contains the configuration options for
* **Header**: At the top. This shows version information and contains buttons to
view documentation, monitor running tasks, set the language, configure various
display settings, and logout.
* **Sidebar**: On the left. This contains the administration options for
the server.
* **Configuration Panel**: In the center. This contains the control interface for the
configuration options in the *Sidebar*.
* **Configuration Panel**: In the center. This contains the respective control
interfaces for the administration options in the *Sidebar*.
Sidebar
@ -74,12 +76,14 @@ previous and currently running tasks, and subscription information.
Configuration
^^^^^^^^^^^^^
The Configuration section contains some system configuration options, such as
time and network configuration. It also contains the following subsections:
The Configuration section contains some system options, such as time, network,
WebAuthn, and HTTP proxy configuration. It also contains the following
subsections:
* **Access Control**: Add and manage users, API tokens, and the permissions
associated with these items
* **Remotes**: Add, edit and remove remotes (see :term:`Remote`)
* **Certificates**: Manage ACME accounts and create SSL certificates.
* **Subscription**: Upload a subscription key, view subscription status and
access a text-based system report.
@ -98,6 +102,7 @@ tasks and information. These are:
resource usage statistics
* **Services**: Manage and monitor system services
* **Updates**: An interface for upgrading packages
* **Repositories**: An interface for configuring APT repositories
* **Syslog**: View log messages from the server
* **Tasks**: Task history with multiple filter options
@ -119,11 +124,20 @@ Tape Backup
:align: right
:alt: Tape Backup: Tape changer overview
The `Tape Backup`_ section contains a top panel, managing tape media sets,
inventories, drives, changers and the tape backup jobs itself.
The `Tape Backup`_ section contains a top panel, with options for managing tape
media sets, inventories, drives, changers, encryption keys, and the tape backup
jobs itself. The tabs are as follows:
It also contains a subsection per standalone drive and per changer, with a
status and management view for those devices.
* **Content**: Information on the contents of the tape backup
* **Inventory**: Manage the tapes attached to the system
* **Changers**: Manage tape loading devices
* **Drives**: Manage drives used for reading and writing to tapes
* **Media Pools**: Manage logical pools of tapes
* **Encryption Keys**: Manage tape backup encryption keys
* **Backup Jobs**: Manage tape backup jobs
The section also contains a subsection per standalone drive and per changer,
with a status and management view for those devices.
Datastore
^^^^^^^^^
@ -133,9 +147,9 @@ Datastore
:alt: Datastore Configuration
The Datastore section contains interfaces for creating and managing
datastores. It contains a button to create a new datastore on the server, as
well as a subsection for each datastore on the system, in which you can use the
top panel to view:
datastores. It also contains a button for creating a new datastore on the
server, as well as a subsection for each datastore on the system, in which you
can use the top panel to view:
* **Summary**: Access a range of datastore usage statistics
* **Content**: Information on the datastore's backup groups and their respective
@ -144,5 +158,7 @@ top panel to view:
collection <client_garbage-collection>` operations, and run garbage collection
manually
* **Sync Jobs**: Create, manage and run :ref:`syncjobs` from remote servers
* **Verify Jobs**: Create, manage and run :ref:`maintenance_verification` jobs on the
datastore
* **Verify Jobs**: Create, manage and run :ref:`maintenance_verification` jobs
on the datastore
* **Options**: Configure notification and verification settings
* **Permissions**: Manage permissions on the datastore

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 132 KiB

View File

@ -50,6 +50,7 @@ in the section entitled "GNU Free Documentation License".
file-formats.rst
backup-protocol.rst
calendarevents.rst
markdown-primer.rst
glossary.rst
GFDL.rst

View File

@ -19,24 +19,24 @@ for various management tasks such as disk management.
`Proxmox Backup`_ without the server part.
The disk image (ISO file) provided by Proxmox includes a complete Debian system
as well as all necessary packages for the `Proxmox Backup`_ server.
as well as all necessary packages for the `Proxmox Backup`_ Server.
The installer will guide you through the setup process and allow
you to partition the local disk(s), apply basic system configurations
(e.g. timezone, language, network), and install all required packages.
you to partition the local disk(s), apply basic system configuration
(for example timezone, language, network), and install all required packages.
The provided ISO will get you started in just a few minutes, and is the
recommended method for new and existing users.
Alternatively, `Proxmox Backup`_ server can be installed on top of an
Alternatively, `Proxmox Backup`_ Server can be installed on top of an
existing Debian system.
Install `Proxmox Backup`_ with the Installer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Install `Proxmox Backup`_ Server using the Installer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Download the ISO from |DOWNLOADS|.
It includes the following:
* The `Proxmox Backup`_ server installer, which partitions the local
* The `Proxmox Backup`_ Server installer, which partitions the local
disk(s) with ext4, xfs or ZFS, and installs the operating system
* Complete operating system (Debian Linux, 64-bit)
@ -63,7 +63,7 @@ standard Debian installation. After configuring the
# apt-get update
# apt-get install proxmox-backup-server
The commands above keep the current (Debian) kernel and install a minimal
The above commands keep the current (Debian) kernel and install a minimal
set of required packages.
If you want to install the same set of packages as the installer

View File

@ -4,15 +4,16 @@ Introduction
What is Proxmox Backup Server?
------------------------------
Proxmox Backup Server is an enterprise-class, client-server backup software
package that backs up :term:`virtual machine`\ s, :term:`container`\ s, and
physical hosts. It is specially optimized for the `Proxmox Virtual Environment`_
platform and allows you to back up your data securely, even between remote
sites, providing easy management with a web-based user interface.
Proxmox Backup Server is an enterprise-class, client-server backup solution that
is capable of backing up :term:`virtual machine<Virtual machine>`\ s,
:term:`container<Container>`\ s, and physical hosts. It is specially optimized
for the `Proxmox Virtual Environment`_ platform and allows you to back up your
data securely, even between remote sites, providing easy management through a
web-based user interface.
It supports deduplication, compression, and authenticated
encryption (AE_). Using :term:`Rust` as the implementation language guarantees high
performance, low resource usage, and a safe, high-quality codebase.
encryption (AE_). Using :term:`Rust` as the implementation language guarantees
high performance, low resource usage, and a safe, high-quality codebase.
Proxmox Backup uses state of the art cryptography for both client-server
communication and backup content :ref:`encryption <client_encryption>`. All
@ -28,23 +29,24 @@ Proxmox Backup Server uses a `client-server model`_. The server stores the
backup data and provides an API to create and manage datastores. With the
API, it's also possible to manage disks and other server-side resources.
The backup client uses this API to access the backed up data. With the command
line tool ``proxmox-backup-client`` you can create backups and restore data.
For QEMU_ with `Proxmox Virtual Environment`_ we deliver an integrated client.
The backup client uses this API to access the backed up data. You can use the
``proxmox-backup-client`` command line tool to create and restore file backups.
For QEMU_ and LXC_ within `Proxmox Virtual Environment`_, we deliver an
integrated client.
A single backup is allowed to contain several archives. For example, when you
backup a :term:`virtual machine`, each disk is stored as a separate archive
inside that backup. The VM configuration itself is stored as an extra file.
This way, it's easy to access and restore only important parts of the backup,
without the need to scan the whole backup.
backup a :term:`virtual machine<Virtual machine>`, each disk is stored as a
separate archive inside that backup. The VM configuration itself is stored as
an extra file. This way, it's easy to access and restore only the important
parts of the backup, without the need to scan the whole backup.
Main Features
-------------
:Support for Proxmox VE: The `Proxmox Virtual Environment`_ is fully
supported and you can easily backup :term:`virtual machine`\ s and
:term:`container`\ s.
supported, and you can easily backup :term:`virtual machine<Virtual machine>`\ s and
:term:`container<Container>`\ s.
:Performance: The whole software stack is written in :term:`Rust`,
in order to provide high speed and memory efficiency.
@ -70,6 +72,10 @@ Main Features
modern hardware. In addition to client-side encryption, all data is
transferred via a secure TLS connection.
:Tape backup: For long-term archiving of data, Proxmox Backup Server also
provides extensive support for backing up to tape and managing tape
libraries.
:Web interface: Manage the Proxmox Backup Server with the integrated, web-based
user interface.
@ -80,7 +86,7 @@ Main Features
backup-clients.
:Enterprise Support: Proxmox Server Solutions GmbH offers enterprise support in
form of `Proxmox Backup Server Subscription Plans
the form of `Proxmox Backup Server Subscription Plans
<https://www.proxmox.com/en/proxmox-backup-server/pricing>`_. Users at every
subscription level get access to the Proxmox Backup :ref:`Enterprise
Repository <sysadmin_package_repos_enterprise>`. In addition, with a Basic,
@ -173,7 +179,7 @@ Bug Tracker
~~~~~~~~~~~
Proxmox runs a public bug tracker at `<https://bugzilla.proxmox.com>`_. If an
issue appears, file your report there. An issue can be a bug as well as a
issue appears, file your report there. An issue can be a bug, as well as a
request for a new feature or enhancement. The bug tracker helps to keep track
of the issue and will send a notification once it has been solved.
@ -224,5 +230,6 @@ requirements.
In July 2020, we released the first beta version of Proxmox Backup
Server, followed by the first stable version in November 2020. With support for
incremental, fully deduplicated backups, Proxmox Backup significantly reduces
network load and saves valuable storage space.
encryption and incremental, fully deduplicated backups, Proxmox Backup offers a
secure environment, which significantly reduces network load and saves valuable
storage space.

View File

@ -4,17 +4,17 @@
ZFS on Linux
------------
ZFS is a combined file system and logical volume manager designed by
ZFS is a combined file system and logical volume manager, designed by
Sun Microsystems. There is no need to manually compile ZFS modules - all
packages are included.
By using ZFS, it's possible to achieve maximum enterprise features with
low budget hardware, but also high performance systems by leveraging
SSD caching or even SSD only setups. ZFS can replace cost intense
hardware raid cards by moderate CPU and memory load combined with easy
low budget hardware, and also high performance systems by leveraging
SSD caching or even SSD only setups. ZFS can replace expensive
hardware raid cards with moderate CPU and memory load, combined with easy
management.
General ZFS advantages
General advantages of ZFS:
* Easy configuration and management with GUI and CLI.
* Reliable
@ -34,18 +34,18 @@ General ZFS advantages
Hardware
~~~~~~~~~
ZFS depends heavily on memory, so you need at least 8GB to start. In
practice, use as much you can get for your hardware/budget. To prevent
ZFS depends heavily on memory, so it's recommended to have at least 8GB to
start. In practice, use as much you can get for your hardware/budget. To prevent
data corruption, we recommend the use of high quality ECC RAM.
If you use a dedicated cache and/or log disk, you should use an
enterprise class SSD (e.g. Intel SSD DC S3700 Series). This can
enterprise class SSD (for example, Intel SSD DC S3700 Series). This can
increase the overall performance significantly.
IMPORTANT: Do not use ZFS on top of hardware controller which has its
IMPORTANT: Do not use ZFS on top of a hardware controller which has its
own cache management. ZFS needs to directly communicate with disks. An
HBA adapter is the way to go, or something like LSI controller flashed
in ``IT`` mode.
HBA adapter or something like an LSI controller flashed in ``IT`` mode is
recommended.
ZFS Administration
@ -53,7 +53,7 @@ ZFS Administration
This section gives you some usage examples for common tasks. ZFS
itself is really powerful and provides many options. The main commands
to manage ZFS are `zfs` and `zpool`. Both commands come with great
to manage ZFS are `zfs` and `zpool`. Both commands come with extensive
manual pages, which can be read with:
.. code-block:: console
@ -123,7 +123,7 @@ Create a new pool with cache (L2ARC)
It is possible to use a dedicated cache drive partition to increase
the performance (use SSD).
As `<device>` it is possible to use more devices, like it's shown in
For `<device>`, you can use multiple devices, as is shown in
"Create a new pool with RAID*".
.. code-block:: console
@ -136,7 +136,7 @@ Create a new pool with log (ZIL)
It is possible to use a dedicated cache drive partition to increase
the performance (SSD).
As `<device>` it is possible to use more devices, like it's shown in
For `<device>`, you can use multiple devices, as is shown in
"Create a new pool with RAID*".
.. code-block:: console
@ -146,8 +146,9 @@ As `<device>` it is possible to use more devices, like it's shown in
Add cache and log to an existing pool
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have a pool without cache and log. First partition the SSD in
2 partition with `parted` or `gdisk`
You can add cache and log devices to a pool after its creation. In this example,
we will use a single drive for both cache and log. First, you need to create
2 partitions on the SSD with `parted` or `gdisk`
.. important:: Always use GPT partition tables.
@ -171,12 +172,12 @@ Changing a failed device
Changing a failed bootable device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Depending on how Proxmox Backup was installed it is either using `grub` or `systemd-boot`
as bootloader.
Depending on how Proxmox Backup was installed, it is either using `grub` or
`systemd-boot` as a bootloader.
The first steps of copying the partition table, reissuing GUIDs and replacing
the ZFS partition are the same. To make the system bootable from the new disk,
different steps are needed which depend on the bootloader in use.
In either case, the first steps of copying the partition table, reissuing GUIDs
and replacing the ZFS partition are the same. To make the system bootable from
the new disk, different steps are needed which depend on the bootloader in use.
.. code-block:: console
@ -190,12 +191,12 @@ With `systemd-boot`:
.. code-block:: console
# pve-efiboot-tool format <new disk's ESP>
# pve-efiboot-tool init <new disk's ESP>
# proxmox-boot-tool format <new ESP>
# proxmox-boot-tool init <new ESP>
.. NOTE:: `ESP` stands for EFI System Partition, which is setup as partition #2 on
bootable disks setup by the {pve} installer since version 5.4. For details, see
xref:sysboot_systemd_boot_setup[Setting up a new partition for use as synced ESP].
bootable disks setup by the `Proxmox Backup`_ installer. For details, see
:ref:`Setting up a new partition for use as synced ESP <systembooting-proxmox-boot-setup>`.
With `grub`:
@ -207,36 +208,31 @@ Usually `grub.cfg` is located in `/boot/grub/grub.cfg`
# grub-mkconfig -o /path/to/grub.cfg
Activate E-Mail Notification
Activate e-mail notification
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ZFS comes with an event daemon, which monitors events generated by the
ZFS kernel module. The daemon can also send emails on ZFS events like
pool errors. Newer ZFS packages ship the daemon in a separate package,
and you can install it using `apt-get`:
ZFS comes with an event daemon ``ZED``, which monitors events generated by the
ZFS kernel module. The daemon can also send emails on ZFS events like pool
errors. Newer ZFS packages ship the daemon in a separate package ``zfs-zed``,
which should already be installed by default in `Proxmox Backup`_.
.. code-block:: console
# apt-get install zfs-zed
To activate the daemon it is necessary to edit `/etc/zfs/zed.d/zed.rc` with your
favorite editor, and uncomment the `ZED_EMAIL_ADDR` setting:
You can configure the daemon via the file ``/etc/zfs/zed.d/zed.rc`` with your
favorite editor. The required setting for email notification is
``ZED_EMAIL_ADDR``, which is set to ``root`` by default.
.. code-block:: console
ZED_EMAIL_ADDR="root"
Please note Proxmox Backup forwards mails to `root` to the email address
Please note that `Proxmox Backup`_ forwards mails to `root` to the email address
configured for the root user.
IMPORTANT: The only setting that is required is `ZED_EMAIL_ADDR`. All
other settings are optional.
Limit ZFS Memory Usage
Limit ZFS memory usage
^^^^^^^^^^^^^^^^^^^^^^
It is good to use at most 50 percent (which is the default) of the
system memory for ZFS ARC to prevent performance shortage of the
system memory for ZFS ARC, to prevent performance degradation of the
host. Use your preferred editor to change the configuration in
`/etc/modprobe.d/zfs.conf` and insert:
@ -244,25 +240,40 @@ host. Use your preferred editor to change the configuration in
options zfs zfs_arc_max=8589934592
This example setting limits the usage to 8GB.
The above example limits the usage to 8 GiB ('8 * 2^30^').
.. IMPORTANT:: If your root file system is ZFS you must update your initramfs every time this value changes:
.. IMPORTANT:: In case your desired `zfs_arc_max` value is lower than or equal
to `zfs_arc_min` (which defaults to 1/32 of the system memory), `zfs_arc_max`
will be ignored. Thus, for it to work in this case, you must set
`zfs_arc_min` to at most `zfs_arc_max - 1`. This would require updating the
configuration in `/etc/modprobe.d/zfs.conf`, with:
.. code-block:: console
options zfs zfs_arc_min=8589934591
options zfs zfs_arc_max=8589934592
This example setting limits the usage to 8 GiB ('8 * 2^30^') on
systems with more than 256 GiB of total memory, where simply setting
`zfs_arc_max` alone would not work.
.. IMPORTANT:: If your root file system is ZFS, you must update your initramfs
every time this value changes.
.. code-block:: console
# update-initramfs -u
SWAP on ZFS
Swap on ZFS
^^^^^^^^^^^
Swap-space created on a zvol may generate some troubles, like blocking the
server or generating a high IO load, often seen when starting a Backup
to an external Storage.
Swap-space created on a zvol may cause some issues, such as blocking the
server or generating a high IO load.
We strongly recommend to use enough memory, so that you normally do not
We strongly recommend using enough memory, so that you normally do not
run into low memory situations. Should you need or want to add swap, it is
preferred to create a partition on a physical disk and use it as swap device.
preferred to create a partition on a physical disk and use it as a swap device.
You can leave some space free for this purpose in the advanced options of the
installer. Additionally, you can lower the `swappiness` value.
A good value for servers is 10:
@ -291,21 +302,24 @@ an editor of your choice and add the following line:
vm.swappiness = 100 The kernel will swap aggressively.
==================== ===============================================================
ZFS Compression
ZFS compression
^^^^^^^^^^^^^^^
To activate compression:
.. code-block:: console
# zpool set compression=lz4 <pool>
We recommend using the `lz4` algorithm, since it adds very little CPU overhead.
Other algorithms such as `lzjb` and `gzip-N` (where `N` is an integer `1-9` representing
the compression ratio, 1 is fastest and 9 is best compression) are also available.
Depending on the algorithm and how compressible the data is, having compression enabled can even increase
I/O performance.
Other algorithms such as `lzjb`, `zstd` and `gzip-N` (where `N` is an integer from `1-9`
representing the compression ratio, where 1 is fastest and 9 is best
compression) are also available. Depending on the algorithm and how
compressible the data is, having compression enabled can even increase I/O
performance.
You can disable compression at any time with:
.. code-block:: console
# zfs set compression=off <dataset>
@ -314,26 +328,26 @@ Only new blocks will be affected by this change.
.. _local_zfs_special_device:
ZFS Special Device
ZFS special device
^^^^^^^^^^^^^^^^^^
Since version 0.8.0 ZFS supports `special` devices. A `special` device in a
Since version 0.8.0, ZFS supports `special` devices. A `special` device in a
pool is used to store metadata, deduplication tables, and optionally small
file blocks.
A `special` device can improve the speed of a pool consisting of slow spinning
hard disks with a lot of metadata changes. For example workloads that involve
hard disks with a lot of metadata changes. For example, workloads that involve
creating, updating or deleting a large number of files will benefit from the
presence of a `special` device. ZFS datasets can also be configured to store
whole small files on the `special` device which can further improve the
small files on the `special` device, which can further improve the
performance. Use fast SSDs for the `special` device.
.. IMPORTANT:: The redundancy of the `special` device should match the one of the
pool, since the `special` device is a point of failure for the whole pool.
pool, since the `special` device is a point of failure for the entire pool.
.. WARNING:: Adding a `special` device to a pool cannot be undone!
Create a pool with `special` device and RAID-1:
To create a pool with `special` device and RAID-1:
.. code-block:: console
@ -346,8 +360,8 @@ Adding a `special` device to an existing pool with RAID-1:
# zpool add <pool> special mirror <device1> <device2>
ZFS datasets expose the `special_small_blocks=<size>` property. `size` can be
`0` to disable storing small file blocks on the `special` device or a power of
two in the range between `512B` to `128K`. After setting the property new file
`0` to disable storing small file blocks on the `special` device, or a power of
two in the range between `512B` to `128K`. After setting this property, new file
blocks smaller than `size` will be allocated on the `special` device.
.. IMPORTANT:: If the value for `special_small_blocks` is greater than or equal to
@ -355,10 +369,10 @@ blocks smaller than `size` will be allocated on the `special` device.
the `special` device, so be careful!
Setting the `special_small_blocks` property on a pool will change the default
value of that property for all child ZFS datasets (for example all containers
value of that property for all child ZFS datasets (for example, all containers
in the pool will opt in for small file blocks).
Opt in for all file smaller than 4K-blocks pool-wide:
Opt in for all files smaller than 4K-blocks pool-wide:
.. code-block:: console
@ -379,10 +393,15 @@ Opt out from small file blocks for a single dataset:
Troubleshooting
^^^^^^^^^^^^^^^
Corrupted cachefile
Corrupt cache file
""""""""""""""""""
In case of a corrupted ZFS cachefile, some volumes may not be mounted during
boot until mounted manually later.
`zfs-import-cache.service` imports ZFS pools using the ZFS cache file. If this
file becomes corrupted, the service won't be able to import the pools that it's
unable to read from it.
As a result, in case of a corrupted ZFS cache file, some volumes may not be
mounted during boot and must be mounted manually later.
For each pool, run:
@ -390,16 +409,13 @@ For each pool, run:
# zpool set cachefile=/etc/zfs/zpool.cache POOLNAME
and afterwards update the `initramfs` by running:
then, update the `initramfs` by running:
.. code-block:: console
# update-initramfs -u -k all
and finally reboot your node.
Sometimes the ZFS cachefile can get corrupted, and `zfs-import-cache.service`
doesn't import the pools that aren't present in the cachefile.
and finally, reboot the node.
Another workaround to this problem is enabling the `zfs-import-scan.service`,
which searches and imports pools via device scanning (usually slower).

View File

@ -14,15 +14,15 @@ following retention options are available:
``keep-hourly <N>``
Keep backups for the last ``<N>`` hours. If there is more than one
backup for a single hour, only the latest is kept.
backup for a single hour, only the latest is retained.
``keep-daily <N>``
Keep backups for the last ``<N>`` days. If there is more than one
backup for a single day, only the latest is kept.
backup for a single day, only the latest is retained.
``keep-weekly <N>``
Keep backups for the last ``<N>`` weeks. If there is more than one
backup for a single week, only the latest is kept.
backup for a single week, only the latest is retained.
.. note:: Weeks start on Monday and end on Sunday. The software
uses the `ISO week date`_ system and handles weeks at
@ -30,17 +30,17 @@ following retention options are available:
``keep-monthly <N>``
Keep backups for the last ``<N>`` months. If there is more than one
backup for a single month, only the latest is kept.
backup for a single month, only the latest is retained.
``keep-yearly <N>``
Keep backups for the last ``<N>`` years. If there is more than one
backup for a single year, only the latest is kept.
backup for a single year, only the latest is retained.
The retention options are processed in the order given above. Each option
only covers backups within its time period. The next option does not take care
of already covered backups. It will only consider older backups.
Unfinished and incomplete backups will be removed by the prune command unless
Unfinished and incomplete backups will be removed by the prune command, unless
they are newer than the last successful backup. In this case, the last failed
backup is retained.
@ -48,7 +48,7 @@ Prune Simulator
^^^^^^^^^^^^^^^
You can use the built-in `prune simulator <prune-simulator/index.html>`_
to explore the effect of different retetion options with various backup
to explore the effect of different retention options with various backup
schedules.
Manual Pruning
@ -59,10 +59,10 @@ Manual Pruning
:align: right
:alt: Prune and garbage collection options
To access pruning functionality for a specific backup group, you can use the
prune command line option discussed in :ref:`backup-pruning`, or navigate to
the **Content** tab of the datastore and click the scissors icon in the
**Actions** column of the relevant backup group.
To manually prune a specific backup group, you can use
``proxmox-backup-client``'s ``prune`` subcommand, discussed in
:ref:`backup-pruning`, or navigate to the **Content** tab of the datastore and
click the scissors icon in the **Actions** column of the relevant backup group.
Prune Schedules
^^^^^^^^^^^^^^^
@ -81,7 +81,7 @@ Retention Settings Example
^^^^^^^^^^^^^^^^^^^^^^^^^^
The backup frequency and retention of old backups may depend on how often data
changes, and how important an older state may be, in a specific work load.
changes and how important an older state may be in a specific workload.
When backups act as a company's document archive, there may also be legal
requirements for how long backup snapshots must be kept.
@ -125,8 +125,8 @@ start garbage collection on an entire datastore and the ``status`` subcommand to
see attributes relating to the :ref:`garbage collection <client_garbage-collection>`.
This functionality can also be accessed in the GUI, by navigating to **Prune &
GC** from the top panel. From here, you can edit the schedule at which garbage
collection runs and manually start the operation.
GC** from the top panel of a datastore. From here, you can edit the schedule at
which garbage collection runs and manually start the operation.
.. _maintenance_verification:
@ -139,13 +139,13 @@ Verification
:align: right
:alt: Adding a verify job
Proxmox Backup offers various verification options to ensure that backup data is
intact. Verification is generally carried out through the creation of verify
jobs. These are scheduled tasks that run verification at a given interval (see
:ref:`calendar-event-scheduling`). With these, you can set whether already verified
snapshots are ignored, as well as set a time period, after which verified jobs
are checked again. The interface for creating verify jobs can be found under the
**Verify Jobs** tab of the datastore.
Proxmox Backup Server offers various verification options to ensure that backup
data is intact. Verification is generally carried out through the creation of
verify jobs. These are scheduled tasks that run verification at a given interval
(see :ref:`calendar-event-scheduling`). With these, you can also set whether
already verified snapshots are ignored, as well as set a time period, after
which snapshots are checked again. The interface for creating verify jobs can be
found under the **Verify Jobs** tab of the datastore.
.. Note:: It is recommended that you reverify all backups at least monthly, even
if a previous verification was successful. This is because physical drives
@ -158,9 +158,9 @@ are checked again. The interface for creating verify jobs can be found under the
data.
Aside from using verify jobs, you can also run verification manually on entire
datastores, backup groups, or snapshots. To do this, navigate to the **Content**
tab of the datastore and either click *Verify All*, or select the *V.* icon from
the *Actions* column in the table.
datastores, backup groups or snapshots. To do this, navigate to the **Content**
tab of the datastore and either click *Verify All* or select the *V.* icon from
the **Actions** column in the table.
.. _maintenance_notification:
@ -170,8 +170,12 @@ Notifications
Proxmox Backup Server can send you notification emails about automatically
scheduled verification, garbage-collection and synchronization tasks results.
By default, notifications are send to the email address configured for the
`root@pam` user. You can set that user for each datastore.
By default, notifications are sent to the email address configured for the
`root@pam` user. You can instead set this user for each datastore.
.. image:: images/screenshots/pbs-gui-datastore-options.png
:align: right
:alt: Datastore Options
You can also change the level of notification received per task type, the
following options are available:
@ -179,6 +183,23 @@ following options are available:
* Always: send a notification for any scheduled task, independent of the
outcome
* Errors: send a notification for any scheduled task resulting in an error
* Errors: send a notification for any scheduled task that results in an error
* Never: do not send any notification at all
.. _maintenance_mode:
Maintenance Mode
----------------
Proxmox Backup Server implements setting the `read-only` and `offline`
maintenance modes for a datastore.
Once enabled, depending on the mode, new reads and/or writes to the datastore
are blocked, allowing an administrator to safely execute maintenance tasks, for
example, on the underlying storage.
Internally Proxmox Backup Server tracks whether each datastore access is a
write or read operation, so that it can gracefully enter the respective mode,
by allowing conflicting operations that started before enabling the maintenance
mode to finish.

View File

@ -1,5 +1,5 @@
Managing Remotes
================
Managing Remotes & Sync
=======================
.. _backup_remote:
@ -17,8 +17,8 @@ configuration information for remotes is stored in the file
:align: right
:alt: Add a remote
To add a remote, you need its hostname or IP, a userid and password on the
remote, and its certificate fingerprint. To get the fingerprint, use the
To add a remote, you need its hostname or IP address, a userid and password on
the remote, and its certificate fingerprint. To get the fingerprint, use the
``proxmox-backup-manager cert info`` command on the remote, or navigate to
**Dashboard** in the remote's web interface and select **Show Fingerprint**.
@ -60,12 +60,13 @@ Sync Jobs
Sync jobs are configured to pull the contents of a datastore on a **Remote** to
a local datastore. You can manage sync jobs in the web interface, from the
**Sync Jobs** tab of the datastore which you'd like to set one up for, or using
the ``proxmox-backup-manager sync-job`` command. The configuration information
for sync jobs is stored at ``/etc/proxmox-backup/sync.cfg``. To create a new
sync job, click the add button in the GUI, or use the ``create`` subcommand.
After creating a sync job, you can either start it manually from the GUI or
provide it with a schedule (see :ref:`calendar-event-scheduling`) to run regularly.
**Sync Jobs** tab of the **Datastore** panel or from that of the Datastore
itself. Alternatively, you can manage them with the ``proxmox-backup-manager
sync-job`` command. The configuration information for sync jobs is stored at
``/etc/proxmox-backup/sync.cfg``. To create a new sync job, click the add button
in the GUI, or use the ``create`` subcommand. After creating a sync job, you can
either start it manually from the GUI or provide it with a schedule (see
:ref:`calendar-event-scheduling`) to run regularly.
.. code-block:: console
@ -79,17 +80,130 @@ provide it with a schedule (see :ref:`calendar-event-scheduling`) to run regular
└────────────┴───────┴────────┴──────────────┴───────────┴─────────┘
# proxmox-backup-manager sync-job remove pbs2-local
For setting up sync jobs, the configuring user needs the following permissions:
To set up sync jobs, the configuring user needs the following permissions:
#. ``Remote.Read`` on the ``/remote/{remote}/{remote-store}`` path
#. at least ``Datastore.Backup`` on the local target datastore (``/datastore/{store}``)
If the ``remove-vanished`` option is set, ``Datastore.Prune`` is required on
the local datastore as well. If the ``owner`` option is not set (defaulting to
``root@pam``) or set to something other than the configuring user,
``Datastore.Modify`` is required as well.
#. At least ``Datastore.Backup`` on the local target datastore (``/datastore/{store}``)
.. note:: A sync job can only sync backup groups that the configured remote's
user/API token can read. If a remote is configured with a user/API token that
only has ``Datastore.Backup`` privileges, only the limited set of accessible
snapshots owned by that user/API token can be synced.
If the ``remove-vanished`` option is set, ``Datastore.Prune`` is required on
the local datastore as well. If the ``owner`` option is not set (defaulting to
``root@pam``) or is set to something other than the configuring user,
``Datastore.Modify`` is required as well.
If the ``group-filter`` option is set, only backup groups matching at least one
of the specified criteria are synced. The available criteria are:
* backup type, for example to only sync groups of the `ct` (Container) type:
.. code-block:: console
# proxmox-backup-manager sync-job update ID --group-filter type:ct
* full group identifier
.. code-block:: console
# proxmox-backup-manager sync-job update ID --group-filter group:vm/100
* regular expression matched against the full group identifier
.. todo:: add example for regex
The same filter is applied to local groups for handling of the
``remove-vanished`` option.
.. note:: The ``protected`` flag of remote backup snapshots will not be synced.
Namespace Support
^^^^^^^^^^^^^^^^^
Sync jobs can be configured to not only sync datastores, but also sub-sets of
datastores in the form of namespaces or namespace sub-trees. The following
parameters influence how namespaces are treated as part of a sync job
execution:
- ``remote-ns``: the remote namespace anchor (default: the root namespace)
- ``ns``: the local namespace anchor (default: the root namespace)
- ``max-depth``: whether to recursively iterate over sub-namespaces of the remote
namespace anchor (default: `None`)
If ``max-depth`` is set to `0`, groups are synced from ``remote-ns`` into
``ns``, without any recursion. If it is set to `None` (left empty), recursion
depth will depend on the value of ``remote-ns`` and the remote side's
availability of namespace support:
- ``remote-ns`` set to something other than the root namespace: remote *must*
support namespaces, full recursion starting at ``remote-ns``.
- ``remote-ns`` set to root namespace and remote *supports* namespaces: full
recursion starting at root namespace.
- ``remote-ns`` set to root namespace and remote *does not support* namespaces:
backwards-compat mode, only root namespace will be synced into ``ns``, no
recursion.
Any other value of ``max-depth`` will limit recursion to at most ``max-depth``
levels, for example: ``remote-ns`` set to `location_a/department_b` and
``max-depth`` set to `1` will result in `location_a/department_b` and at most
one more level of sub-namespaces being synced.
The namespace tree starting at ``remote-ns`` will be mapped into ``ns`` up to a
depth of ``max-depth``.
For example, with the following namespaces at the remote side:
- `location_a`
- `location_a/department_x`
- `location_a/department_x/team_one`
- `location_a/department_x/team_two`
- `location_a/department_y`
- `location_a/department_y/team_one`
- `location_a/department_y/team_two`
- `location_b`
and ``remote-ns`` being set to `location_a/department_x` and ``ns`` set to
`location_a_dep_x` resulting in the following namespace tree on the sync
target:
- `location_a_dep_x` (containing the remote's `location_a/department_x`)
- `location_a_dep_x/team_one` (containing the remote's `location_a/department_x/team_one`)
- `location_a_dep_x/team_two` (containing the remote's `location_a/department_x/team_two`)
with the rest of the remote namespaces and groups not being synced (by this
sync job).
If a remote namespace is included in the sync job scope, but does not exist
locally, it will be created (provided the sync job owner has sufficient
privileges).
If the ``remove-vanished`` option is set, namespaces that are included in the
sync job scope but only exist locally are treated as vanished and removed
(provided the sync job owner has sufficient privileges).
.. note:: All other limitations on sync scope (such as remote user/API token
privileges, group filters) also apply for sync jobs involving one or
multiple namespaces.
Bandwidth Limit
^^^^^^^^^^^^^^^
Syncing a datastore to an archive can produce lots of traffic and impact other
users of the network. So, to avoid network or storage congestion you can limit
the bandwidth of the sync job by setting the ``rate-in`` option either in the
web interface or using the ``proxmox-backup-manager`` command-line tool:
.. code-block:: console
# proxmox-backup-manager sync-job update ID --rate-in 20MiB

178
docs/markdown-primer.rst Normal file
View File

@ -0,0 +1,178 @@
.. _markdown-primer:
Markdown Primer
===============
"Markdown is a text-to-HTML conversion tool for web writers. Markdown allows
you to write using an easy-to-read, easy-to-write plain text format, then
convertit to structurally valid XHTML (or HTML)."
-- John Gruber, https://daringfireball.net/projects/markdown/
The Proxmox Backup Server (PBS) web-interface has support for using Markdown to
rendering rich text formatting in node and virtual guest notes.
PBS supports CommonMark with most extensions of GFM (GitHub Flavoured Markdown),
like tables or task-lists.
.. _markdown_basics:
Markdown Basics
---------------
Note that we only describe the basics here, please search the web for more
extensive resources, for example on https://www.markdownguide.org/
Headings
~~~~~~~~
.. code-block:: md
# This is a Heading h1
## This is a Heading h2
##### This is a Heading h5
Emphasis
~~~~~~~~
Use ``*text*`` or ``_text_`` for emphasis.
Use ``**text**`` or ``__text__`` for bold, heavy-weight text.
Combinations are also possible, for example:
.. code-block:: md
_You **can** combine them_
Links
~~~~~
You can use automatic detection of links, for example,
``https://forum.proxmox.com/`` would transform it into a clickable link.
You can also control the link text, for example:
.. code-block:: md
Now, [the part in brackets will be the link text](https://forum.proxmox.com/).
Lists
~~~~~
Unordered Lists
^^^^^^^^^^^^^^^
Use ``*`` or ``-`` for unordered lists, for example:
.. code-block:: md
* Item 1
* Item 2
* Item 2a
* Item 2b
Adding an indentation can be used to created nested lists.
Ordered Lists
^^^^^^^^^^^^^
.. code-block:: md
1. Item 1
1. Item 2
1. Item 3
1. Item 3a
1. Item 3b
NOTE: The integer of ordered lists does not need to be correct, they will be numbered automatically.
Task Lists
^^^^^^^^^^
Task list use a empty box ``[ ]`` for unfinished tasks and a box with an `X` for finished tasks.
For example:
.. code-block:: md
- [X] First task already done!
- [X] Second one too
- [ ] This one is still to-do
- [ ] So is this one
Tables
~~~~~~
Tables use the pipe symbol ``|`` to separate columns, and ``-`` to separate the
table header from the table body, in that separation one can also set the text
alignment, making one column left-, center-, or right-aligned.
.. code-block:: md
| Left columns | Right columns | Some | More | Cols.| Centering Works Too
| ------------- |--------------:|--------|------|------|:------------------:|
| left foo | right foo | First | Row | Here | >center< |
| left bar | right bar | Second | Row | Here | 12345 |
| left baz | right baz | Third | Row | Here | Test |
| left zab | right zab | Fourth | Row | Here | ☁️☁️☁️ |
| left rab | right rab | And | Last | Here | The End |
Note that you do not need to align the columns nicely with white space, but that makes
editing tables easier.
Block Quotes
~~~~~~~~~~~~
You can enter block quotes by prefixing a line with ``>``, similar as in plain-text emails.
.. code-block:: md
> Markdown is a lightweight markup language with plain-text-formatting syntax,
> created in 2004 by John Gruber with Aaron Swartz.
>
>> Markdown is often used to format readme files, for writing messages in online discussion forums,
>> and to create rich text using a plain text editor.
Code and Snippets
~~~~~~~~~~~~~~~~~
You can use backticks to avoid processing for a few word or paragraphs. That is useful for
avoiding that a code or configuration hunk gets mistakenly interpreted as markdown.
Inline code
^^^^^^^^^^^
Surrounding part of a line with single backticks allows to write code inline,
for examples:
.. code-block:: md
This hosts IP address is `10.0.0.1`.
Whole blocks of code
^^^^^^^^^^^^^^^^^^^^
For code blocks spanning several lines you can use triple-backticks to start
and end such a block, for example:
.. code-block:: md
```
# This is the network config I want to remember here
auto vmbr2
iface vmbr2 inet static
address 10.0.0.1/24
bridge-ports ens20
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
```

View File

@ -3,6 +3,10 @@
Network Management
==================
.. image:: images/screenshots/pbs-gui-system-config.png
:align: right
:alt: System and Network Configuration Overview
Proxmox Backup Server provides both a web interface and a command line tool for
network configuration. You can find the configuration options in the web
interface under the **Network Interfaces** section of the **Configuration** menu
@ -31,10 +35,6 @@ To get a list of available interfaces, use the following command:
│ ens19 │ eth │ 1 │ manual │ │ │ │
└───────┴────────┴───────────┴────────┴─────────────┴──────────────┴──────────────┘
.. image:: images/screenshots/pbs-gui-network-create-bond.png
:align: right
:alt: Add a network interface
To add a new network interface, use the ``create`` subcommand with the relevant
parameters. For example, you may want to set up a bond, for the purpose of
network redundancy. The following command shows a template for creating the bond shown
@ -44,6 +44,10 @@ in the list above:
# proxmox-backup-manager network create bond0 --type bond --bond_mode active-backup --slaves ens18,ens19 --autostart true --cidr x.x.x.x/x --gateway x.x.x.x
.. image:: images/screenshots/pbs-gui-network-create-bond.png
:align: right
:alt: Add a network interface
You can make changes to the configuration of a network interface with the
``update`` subcommand:
@ -82,9 +86,12 @@ is:
.. note:: This command and corresponding GUI button rely on the ``ifreload``
command, from the package ``ifupdown2``. This package is included within the
Proxmox Backup Server installation, however, you may have to install it yourself,
if you have installed Proxmox Backup Server on top of Debian or Proxmox VE.
if you have installed Proxmox Backup Server on top of Debian or a Proxmox VE
version prior to version 7.
You can also configure DNS settings, from the **DNS** section
of **Configuration** or by using the ``dns`` subcommand of
``proxmox-backup-manager``.
.. include:: traffic-control.rst

View File

@ -1,5 +1,5 @@
Most commands producing output supports the ``--output-format``
parameter. It accepts the following values:
Most commands that produce output support the ``--output-format``
parameter. This accepts the following values:
:``text``: Text format (default). Structured data is rendered as a table.

View File

@ -27,6 +27,10 @@ update``.
In addition, you need a package repository from Proxmox to get Proxmox Backup
updates.
.. image:: images/screenshots/pbs-gui-administration-apt-repos.png
:align: right
:alt: APT Repository Management in the Web Interface
.. _package_repos_secure_apt:
SecureApt

View File

@ -51,7 +51,7 @@ ENVIRONMENT
:CHANGER: If set, replaces the `--device` option
:PROXMOX_TAPE_DRIVE: If set, use the Proxmox Backup Server
configuration to find the associcated changer device.
configuration to find the associated changer device.
.. include:: ../pbs-copyright.rst

View File

@ -1,5 +1,5 @@
This daemon exposes the whole Proxmox Backup Server API on TCP port
8007 using HTTPS. It runs as user ``backup`` and has very limited
permissions. Operation requiring more permissions are forwarded to
permissions. Operations requiring more permissions are forwarded to
the local ``proxmox-backup`` service.

View File

@ -3,8 +3,8 @@
`Proxmox VE`_ Integration
-------------------------
A Proxmox Backup Server can be integrated into a Proxmox VE setup by adding the
former as a storage in a Proxmox VE standalone or cluster setup.
Proxmox Backup Server can be integrated into a Proxmox VE standalone or cluster
setup, by adding it as a storage in Proxmox VE.
See also the `Proxmox VE Storage - Proxmox Backup Server
<https://pve.proxmox.com/pve-docs/pve-admin-guide.html#storage_pbs>`_ section
@ -14,8 +14,8 @@ of the Proxmox VE Administration Guide for Proxmox VE specific documentation.
Using the Proxmox VE Web-Interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Proxmox VE has native API and web-interface integration of Proxmox Backup
Server since the `Proxmox VE 6.3 release
Proxmox VE has native API and web interface integration of Proxmox Backup
Server as of `Proxmox VE 6.3
<https://pve.proxmox.com/wiki/Roadmap#Proxmox_VE_6.3>`_.
A Proxmox Backup Server can be added under ``Datacenter -> Storage``.
@ -24,8 +24,8 @@ Using the Proxmox VE Command-Line
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You need to define a new storage with type 'pbs' on your `Proxmox VE`_
node. The following example uses ``store2`` as storage name, and
assumes the server address is ``localhost``, and you want to connect
node. The following example uses ``store2`` as the storage's name, and
assumes the server address is ``localhost`` and you want to connect
as ``user1@pbs``.
.. code-block:: console
@ -33,7 +33,7 @@ as ``user1@pbs``.
# pvesm add pbs store2 --server localhost --datastore store2
# pvesm set store2 --username user1@pbs --password <secret>
.. note:: If you would rather not pass your password as plain text, you can pass
.. note:: If you would rather not enter your password as plain text, you can pass
the ``--password`` parameter, without any arguments. This will cause the
program to prompt you for a password upon entering the command.
@ -53,7 +53,7 @@ relationship:
# pvesm set store2 --fingerprint 64:d3:ff:3a:50:38:53:5a:9b:f7:50:...:ab:fe
After that you should be able to see storage status with:
After that, you should be able to view storage status with:
.. code-block:: console

View File

@ -1,12 +1,12 @@
``pxar`` is a command line utility to create and manipulate archives in the
``pxar`` is a command line utility for creating and manipulating archives in the
:ref:`pxar-format`.
It is inspired by `casync file archive format
<http://0pointer.net/blog/casync-a-tool-for-distributing-file-system-images.html>`_,
which caters to a similar use-case.
The ``.pxar`` format is adapted to fulfill the specific needs of the Proxmox
Backup Server, for example, efficient storage of hardlinks.
The format is designed to reduce storage space needed on the server by achieving
a high level of deduplication.
Backup Server, for example, efficient storage of hard links.
The format is designed to reduce the required storage on the server by
achieving a high level of deduplication.
Creating an Archive
^^^^^^^^^^^^^^^^^^^
@ -24,10 +24,10 @@ This will create a new archive called ``archive.pxar`` with the contents of the
the same name is already present in the target folder, the creation will
fail.
By default, ``pxar`` will skip certain mountpoints and will not follow device
By default, ``pxar`` will skip certain mount points and will not follow device
boundaries. This design decision is based on the primary use case of creating
archives for backups. It makes sense to not back up the contents of certain
temporary or system specific files.
archives for backups. It makes sense to ignore the contents of certain
temporary or system specific files in a backup.
To alter this behavior and follow device boundaries, use the
``--all-file-systems`` flag.
@ -41,40 +41,38 @@ by running:
# pxar create archive.pxar /path/to/source --exclude '**/*.txt'
Be aware that the shell itself will try to expand all of the glob patterns before
invoking ``pxar``.
In order to avoid this, all globs have to be quoted correctly.
Be aware that the shell itself will try to expand glob patterns before invoking
``pxar``. In order to avoid this, all globs have to be quoted correctly.
It is possible to pass the ``--exclude`` parameter multiple times, in order to
match more than one pattern. This allows you to use more complex
file exclusion/inclusion behavior. However, it is recommended to use
file inclusion/exclusion behavior. However, it is recommended to use
``.pxarexclude`` files instead for such cases.
For example you might want to exclude all ``.txt`` files except for a specific
one from the archive. This is achieved via the negated match pattern, prefixed
by ``!``.
All the glob patterns are relative to the ``source`` directory.
For example you might want to exclude all ``.txt`` files except a specific
one from the archive. This would be achieved via the negated match pattern,
prefixed by ``!``. All the glob patterns are relative to the ``source``
directory.
.. code-block:: console
# pxar create archive.pxar /path/to/source --exclude '**/*.txt' --exclude '!/folder/file.txt'
.. NOTE:: The order of the glob match patterns matters as later ones override
previous ones. Permutations of the same patterns lead to different results.
.. NOTE:: The order of the glob match patterns matters, as later ones override
earlier ones. Permutations of the same patterns lead to different results.
``pxar`` will store the list of glob match patterns passed as parameters via the
command line, in a file called ``.pxarexclude-cli`` at the root of
the archive.
command line, in a file called ``.pxarexclude-cli``, at the root of the archive.
If a file with this name is already present in the source folder during archive
creation, this file is not included in the archive and the file containing the
new patterns is added to the archive instead, the original file is not altered.
creation, this file is not included in the archive, and the file containing the
new patterns is added to the archive instead. The original file is not altered.
A more convenient and persistent way to exclude files from the archive is by
placing the glob match patterns in ``.pxarexclude`` files.
It is possible to create and place these files in any directory of the filesystem
tree.
These files must contain one pattern per line, again later patterns win over
previous ones.
These files must contain one pattern per line, and later patterns override
earlier ones.
The patterns control file exclusions of files present within the given directory
or further below it in the tree.
The behavior is the same as described in :ref:`client_creating_backups`.
@ -89,7 +87,7 @@ with the following command:
# pxar extract archive.pxar /path/to/target
If no target is provided, the content of the archive is extracted to the current
If no target is provided, the contents of the archive is extracted to the current
working directory.
In order to restore only parts of an archive, single files, and/or folders,
@ -116,13 +114,13 @@ run the following command:
# pxar list archive.pxar
This displays the full path of each file or directory with respect to the
archives root.
archive's root.
Mounting an Archive
^^^^^^^^^^^^^^^^^^^
``pxar`` allows you to mount and inspect the contents of an archive via _`FUSE`.
In order to mount an archive named ``archive.pxar`` to the mountpoint ``/mnt``,
In order to mount an archive named ``archive.pxar`` to the mount point ``/mnt``,
run the command:
.. code-block:: console
@ -130,7 +128,7 @@ run the command:
# pxar mount archive.pxar /mnt
Once the archive is mounted, you can access its content under the given
mountpoint.
mount point.
.. code-block:: console

View File

@ -11,11 +11,16 @@ Disk Management
:alt: List of disks
Proxmox Backup Server comes with a set of disk utilities, which are
accessed using the ``disk`` subcommand. This subcommand allows you to initialize
disks, create various filesystems, and get information about the disks.
accessed using the ``disk`` subcommand or the web interface. This subcommand
allows you to initialize disks, create various filesystems, and get information
about the disks.
.. image:: images/screenshots/pbs-gui-disks.png
:align: right
:alt: Web Interface Administration: Disks
To view the disks connected to the system, navigate to **Administration ->
Disks** in the web interface or use the ``list`` subcommand of
Storage/Disks** in the web interface or use the ``list`` subcommand of
``disk``:
.. code-block:: console
@ -42,9 +47,9 @@ To initialize a disk with a new GPT, use the ``initialize`` subcommand:
:alt: Create a directory
You can create an ``ext4`` or ``xfs`` filesystem on a disk using ``fs
create``, or by navigating to **Administration -> Disks -> Directory** in the
web interface and creating one from there. The following command creates an
``ext4`` filesystem and passes the ``--add-datastore`` parameter, in order to
create``, or by navigating to **Administration -> Storage/Disks -> Directory**
in the web interface and creating one from there. The following command creates
an ``ext4`` filesystem and passes the ``--add-datastore`` parameter, in order to
automatically create a datastore on the disk (in this case ``sdd``). This will
create a datastore at the location ``/mnt/datastore/store1``:
@ -57,7 +62,7 @@ create a datastore at the location ``/mnt/datastore/store1``:
:alt: Create ZFS
You can also create a ``zpool`` with various raid levels from **Administration
-> Disks -> Zpool** in the web interface, or by using ``zpool create``. The command
-> Storage/Disks -> ZFS** in the web interface, or by using ``zpool create``. The command
below creates a mirrored ``zpool`` using two disks (``sdb`` & ``sdc``) and
mounts it under ``/mnt/datastore/zpool1``:
@ -90,6 +95,10 @@ display S.M.A.R.T. attributes from the web interface or by using the command:
:term:`Datastore`
-----------------
.. image:: images/screenshots/pbs-gui-datastore-summary.png
:align: right
:alt: Datastore Usage Overview
A datastore refers to a location at which backups are stored. The current
implementation uses a directory inside a standard Unix file system (``ext4``,
``xfs`` or ``zfs``) to store the backup data.
@ -102,7 +111,7 @@ is stored in the file ``/etc/proxmox-backup/datastore.cfg``.
subdirectories per directory. That number comes from the 2\ :sup:`16`
pre-created chunk namespace directories, and the ``.`` and ``..`` default
directory entries. This requirement excludes certain filesystems and
filesystem configuration from being supported for a datastore. For example,
filesystem configurations from being supported for a datastore. For example,
``ext3`` as a whole or ``ext4`` with the ``dir_nlink`` feature manually disabled.
@ -111,23 +120,24 @@ Datastore Configuration
.. image:: images/screenshots/pbs-gui-datastore-content.png
:align: right
:alt: Datastore Overview
:alt: Datastore Content Overview
You can configure multiple datastores. Minimum one datastore needs to be
You can configure multiple datastores. A minimum of one datastore needs to be
configured. The datastore is identified by a simple *name* and points to a
directory on the filesystem. Each datastore also has associated retention
settings of how many backup snapshots for each interval of ``hourly``,
``daily``, ``weekly``, ``monthly``, ``yearly`` as well as a time-independent
number of backups to keep in that store. :ref:`backup-pruning` and
:ref:`garbage collection <client_garbage-collection>` can also be configured to run
periodically based on a configured schedule (see :ref:`calendar-event-scheduling`) per datastore.
:ref:`garbage collection <client_garbage-collection>` can also be configured to
run periodically, based on a configured schedule (see
:ref:`calendar-event-scheduling`) per datastore.
.. _storage_datastore_create:
Creating a Datastore
^^^^^^^^^^^^^^^^^^^^
.. image:: images/screenshots/pbs-gui-datastore-create-general.png
.. image:: images/screenshots/pbs-gui-datastore-create.png
:align: right
:alt: Create a datastore
@ -146,7 +156,8 @@ window:
* *Comment* can be used to add some contextual information to the datastore.
Alternatively you can create a new datastore from the command line. The
following command creates a new datastore called ``store1`` on :file:`/backup/disk1/store1`
following command creates a new datastore called ``store1`` on
:file:`/backup/disk1/store1`
.. code-block:: console
@ -156,7 +167,7 @@ following command creates a new datastore called ``store1`` on :file:`/backup/di
Managing Datastores
^^^^^^^^^^^^^^^^^^^
To list existing datastores from the command line run:
To list existing datastores from the command line, run:
.. code-block:: console
@ -216,8 +227,9 @@ After creating a datastore, the following default layout will appear:
`.lock` is an empty file used for process locking.
The `.chunks` directory contains folders, starting from `0000` and taking hexadecimal values until `ffff`. These
directories will store the chunked data after a backup operation has been executed.
The `.chunks` directory contains folders, starting from `0000` and increasing in
hexadecimal values until `ffff`. These directories will store the chunked data,
categorized by checksum, after a backup operation has been executed.
.. code-block:: console
@ -249,3 +261,57 @@ directories will store the chunked data after a backup operation has been execut
276490 drwxr-x--- 1 backup backup 1.1M Jul 8 12:35 .
Once you uploaded some backups, or created namespaces, you may see the Backup
Type (`ct`, `vm`, `host`) and the start of the namespace hierarchy (`ns`).
.. _storage_namespaces:
Backup Namespaces
~~~~~~~~~~~~~~~~~
A datastore can host many backups as long as the underlying storage is big
enough and provides the performance required for one's use case.
But, without any hierarchy or separation its easy to run into naming conflicts,
especially when using the same datastore for multiple Proxmox VE instances or
multiple users.
The backup namespace hierarchy allows you to clearly separate different users
or backup sources in general, avoiding naming conflicts and providing
well-organized backup content view.
Each namespace level can host any backup type, CT, VM or Host but also other
namespaces, up to a depth of 8 level, where the root namespace is the first
level.
Namespace Permissions
^^^^^^^^^^^^^^^^^^^^^
You can make the permission configuration of a datastore more fine-grained by
setting permissions only on a specific namespace.
To see a datastore you need permission that has at least one of `AUDIT`,
`MODIFY`, `READ` or `BACKUP` privilege on any namespace it contains.
To create or delete a namespace you require the modify privilege on the parent
namespace. So, to initially create namespaces you need to have a permission
with a access role that includes the `MODIFY` privilege on the datastore itself.
For backup groups the existing privilege rules still apply, you either need a
powerful permission or be the owner of the backup group, nothing changed here.
.. todo:: continue
Options
~~~~~~~
.. image:: images/screenshots/pbs-gui-datastore-options.png
:align: right
:alt: Datastore Options
There are a few per-datastore options:
* :ref:`Notifications <maintenance_notification>`
* :ref:`Maintenance Mode <maintenance_mode>`
* Verification of incoming backups

View File

@ -4,8 +4,8 @@ Host System Administration
==========================
`Proxmox Backup`_ is based on the famous Debian_ Linux
distribution. That means that you have access to the whole world of
Debian packages, and the base system is well documented. The `Debian
distribution. This means that you have access to the entire range of
Debian packages, and that the base system is well documented. The `Debian
Administrator's Handbook`_ is available online, and provides a
comprehensive introduction to the Debian operating system.
@ -15,17 +15,21 @@ through that channel. In addition, we provide our own package
repository to roll out all Proxmox related packages. This includes
updates to some Debian packages when necessary.
We also deliver a specially optimized Linux kernel, where we enable
all required virtualization and container features. That kernel
includes drivers for ZFS_, and several hardware drivers. For example,
we ship Intel network card drivers to support their newest hardware.
We also deliver a specially optimized Linux kernel, based on the Ubuntu
kernel. That kernel includes drivers for ZFS_.
The following sections will concentrate on backup related topics. They
either explain things which are different on `Proxmox Backup`_, or
will explain things which are different on `Proxmox Backup`_, or
tasks which are commonly used on `Proxmox Backup`_. For other topics,
please refer to the standard Debian documentation.
.. include:: local-zfs.rst
.. include:: system-booting.rst
.. include:: certificate-management.rst
.. include:: services.rst
.. include:: command-line-tools.rst

379
docs/system-booting.rst Normal file
View File

@ -0,0 +1,379 @@
.. _chapter-systembooting:
Host Bootloader
---------------
`Proxmox Backup`_ currently uses one of two bootloaders depending on the disk setup
selected in the installer.
For EFI Systems installed with ZFS as the root filesystem ``systemd-boot`` is
used. All other deployments use the standard ``grub`` bootloader (this usually
also applies to systems which are installed on top of Debian).
.. _systembooting-installer-part-scheme:
Partitioning Scheme Used by the Installer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The `Proxmox Backup`_ installer creates 3 partitions on all disks selected for
installation.
The created partitions are:
* a 1 MB BIOS Boot Partition (gdisk type EF02)
* a 512 MB EFI System Partition (ESP, gdisk type EF00)
* a third partition spanning the set ``hdsize`` parameter or the remaining space
used for the chosen storage type
Systems using ZFS as root filesystem are booted with a kernel and initrd image
stored on the 512 MB EFI System Partition. For legacy BIOS systems, ``grub`` is
used, for EFI systems ``systemd-boot`` is used. Both are installed and configured
to point to the ESPs.
``grub`` in BIOS mode (``--target i386-pc``) is installed onto the BIOS Boot
Partition of all selected disks on all systems booted with ``grub`` (These are
all installs with root on ``ext4`` or ``xfs`` and installs with root on ZFS on
non-EFI systems).
.. _systembooting-proxmox-boot-tool:
Synchronizing the content of the ESP with ``proxmox-boot-tool``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``proxmox-boot-tool`` is a utility used to keep the contents of the EFI System
Partitions properly configured and synchronized. It copies certain kernel
versions to all ESPs and configures the respective bootloader to boot from
the ``vfat`` formatted ESPs. In the context of ZFS as root filesystem this means
that you can use all optional features on your root pool instead of the subset
which is also present in the ZFS implementation in ``grub`` or having to create a
separate small boot-pool (see: `Booting ZFS on root with grub
<https://github.com/zfsonlinux/zfs/wiki/Debian-Stretch-Root-on-ZFS>`_).
In setups with redundancy all disks are partitioned with an ESP, by the
installer. This ensures the system boots even if the first boot device fails
or if the BIOS can only boot from a particular disk.
The ESPs are not kept mounted during regular operation. This helps to prevent
filesystem corruption to the ``vfat`` formatted ESPs in case of a system crash,
and removes the need to manually adapt ``/etc/fstab`` in case the primary boot
device fails.
``proxmox-boot-tool`` handles the following tasks:
* formatting and setting up a new partition
* copying and configuring new kernel images and initrd images to all listed ESPs
* synchronizing the configuration on kernel upgrades and other maintenance tasks
* managing the list of kernel versions which are synchronized
* configuring the boot-loader to boot a particular kernel version (pinning)
You can view the currently configured ESPs and their state by running:
.. code-block:: console
# proxmox-boot-tool status
.. _systembooting-proxmox-boot-setup:
Setting up a new partition for use as synced ESP
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To format and initialize a partition as synced ESP, e.g., after replacing a
failed vdev in an rpool, ``proxmox-boot-tool`` from ``pve-kernel-helper`` can be used.
WARNING: the ``format`` command will format the ``<partition>``, make sure to pass
in the right device/partition!
For example, to format an empty partition ``/dev/sda2`` as ESP, run the following:
.. code-block:: console
# proxmox-boot-tool format /dev/sda2
To setup an existing, unmounted ESP located on ``/dev/sda2`` for inclusion in
`Proxmox Backup`_'s kernel update synchronization mechanism, use the following:
.. code-block:: console
# proxmox-boot-tool init /dev/sda2
Afterwards `/etc/kernel/proxmox-boot-uuids`` should contain a new line with the
UUID of the newly added partition. The ``init`` command will also automatically
trigger a refresh of all configured ESPs.
.. _systembooting-proxmox-boot-refresh:
Updating the configuration on all ESPs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To copy and configure all bootable kernels and keep all ESPs listed in
``/etc/kernel/proxmox-boot-uuids`` in sync you just need to run:
.. code-block:: console
# proxmox-boot-tool refresh
(The equivalent to running ``update-grub`` systems with ``ext4`` or ``xfs`` on root).
This is necessary should you make changes to the kernel commandline, or want to
sync all kernels and initrds.
.. NOTE:: Both ``update-initramfs`` and ``apt`` (when necessary) will automatically
trigger a refresh.
Kernel Versions considered by ``proxmox-boot-tool``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The following kernel versions are configured by default:
* the currently running kernel
* the version being newly installed on package updates
* the two latest already installed kernels
* the latest version of the second-to-last kernel series (e.g. 5.0, 5.3), if applicable
* any manually selected kernels
Manually keeping a kernel bootable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Should you wish to add a certain kernel and initrd image to the list of
bootable kernels use ``proxmox-boot-tool kernel add``.
For example run the following to add the kernel with ABI version ``5.0.15-1-pve``
to the list of kernels to keep installed and synced to all ESPs:
.. code-block:: console
# proxmox-boot-tool kernel add 5.0.15-1-pve
``proxmox-boot-tool kernel list`` will list all kernel versions currently selected
for booting:
.. code-block:: console
# proxmox-boot-tool kernel list
Manually selected kernels:
5.0.15-1-pve
Automatically selected kernels:
5.0.12-1-pve
4.15.18-18-pve
Run ``proxmox-boot-tool kernel remove`` to remove a kernel from the list of
manually selected kernels, for example:
.. code-block:: console
# proxmox-boot-tool kernel remove 5.0.15-1-pve
.. NOTE:: It's required to run ``proxmox-boot-tool refresh`` to update all EFI System
Partitions (ESPs) after a manual kernel addition or removal from above.
.. _systembooting-determine-bootloader:
Determine which Bootloader is Used
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: images/screenshots/boot-grub.png
:target: _images/boot-grub.png
:align: left
:alt: Grub boot screen
The simplest and most reliable way to determine which bootloader is used, is to
watch the boot process of the `Proxmox Backup`_ node.
You will either see the blue box of ``grub`` or the simple black on white
``systemd-boot``.
.. image:: images/screenshots/boot-systemdboot.png
:target: _images/boot-systemdboot.png
:align: right
:alt: systemd-boot screen
Determining the bootloader from a running system might not be 100% accurate. The
safest way is to run the following command:
.. code-block:: console
# efibootmgr -v
If it returns a message that EFI variables are not supported, ``grub`` is used in
BIOS/Legacy mode.
If the output contains a line that looks similar to the following, ``grub`` is
used in UEFI mode.
.. code-block:: console
Boot0005* proxmox [...] File(\EFI\proxmox\grubx64.efi)
If the output contains a line similar to the following, ``systemd-boot`` is used.
.. code-block:: console
Boot0006* Linux Boot Manager [...] File(\EFI\systemd\systemd-bootx64.efi)
By running:
.. code-block:: console
# proxmox-boot-tool status
you can find out if ``proxmox-boot-tool`` is configured, which is a good
indication of how the system is booted.
.. _systembooting-grub:
Grub
~~~~
``grub`` has been the de-facto standard for booting Linux systems for many years
and is quite well documented
(see the `Grub Manual
<https://www.gnu.org/software/grub/manual/grub/grub.html>`_).
Configuration
^^^^^^^^^^^^^
Changes to the ``grub`` configuration are done via the defaults file
``/etc/default/grub`` or config snippets in ``/etc/default/grub.d``. To regenerate
the configuration file after a change to the configuration run:
.. code-block:: console
# update-grub
.. NOTE:: Systems using ``proxmox-boot-tool`` will call
``proxmox-boot-tool refresh`` upon ``update-grub``
.. _systembooting-systemdboot:
Systemd-boot
~~~~~~~~~~~~
``systemd-boot`` is a lightweight EFI bootloader. It reads the kernel and initrd
images directly from the EFI Service Partition (ESP) where it is installed.
The main advantage of directly loading the kernel from the ESP is that it does
not need to reimplement the drivers for accessing the storage. In `Proxmox
Backup`_ :ref:`proxmox-boot-tool <systembooting-proxmox-boot-tool>` is used to
keep the configuration on the ESPs synchronized.
.. _systembooting-systemd-boot-config:
Configuration
^^^^^^^^^^^^^
``systemd-boot`` is configured via the file ``loader/loader.conf`` in the root
directory of an EFI System Partition (ESP). See the ``loader.conf(5)`` manpage
for details.
Each bootloader entry is placed in a file of its own in the directory
``loader/entries/``
An example entry.conf looks like this (``/`` refers to the root of the ESP):
.. code-block:: console
title Proxmox
version 5.0.15-1-pve
options root=ZFS=rpool/ROOT/pve-1 boot=zfs
linux /EFI/proxmox/5.0.15-1-pve/vmlinuz-5.0.15-1-pve
initrd /EFI/proxmox/5.0.15-1-pve/initrd.img-5.0.15-1-pve
.. _systembooting-edit-kernel-cmdline:
Editing the Kernel Commandline
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You can modify the kernel commandline in the following places, depending on the
bootloader used:
Grub
^^^^
The kernel commandline needs to be placed in the variable
``GRUB_CMDLINE_LINUX_DEFAULT`` in the file ``/etc/default/grub``. Running
``update-grub`` appends its content to all ``linux`` entries in
``/boot/grub/grub.cfg``.
Systemd-boot
^^^^^^^^^^^^
The kernel commandline needs to be placed as one line in ``/etc/kernel/cmdline``.
To apply your changes, run ``proxmox-boot-tool refresh``, which sets it as the
``option`` line for all config files in ``loader/entries/proxmox-*.conf``.
.. _systembooting-kernel-pin:
Override the Kernel-Version for next Boot
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To select a kernel that is not currently the default kernel, you can either:
* use the boot loader menu that is displayed at the beginning of the boot
process
* use the ``proxmox-boot-tool`` to ``pin`` the system to a kernel version either
once or permanently (until pin is reset).
This should help you work around incompatibilities between a newer kernel
version and the hardware.
.. NOTE:: Such a pin should be removed as soon as possible so that all current
security patches of the latest kernel are also applied to the system.
For example: To permanently select the version ``5.15.30-1-pve`` for booting you
would run:
.. code-block:: console
# proxmox-boot-tool kernel pin 5.15.30-1-pve
.. TIP:: The pinning functionality works for all `Proxmox Backup`_ systems, not only those using
``proxmox-boot-tool`` to synchronize the contents of the ESPs, if your system
does not use ``proxmox-boot-tool`` for synchronizing you can also skip the
``proxmox-boot-tool refresh`` call in the end.
You can also set a kernel version to be booted on the next system boot only.
This is for example useful to test if an updated kernel has resolved an issue,
which caused you to ``pin`` a version in the first place:
.. code-block:: console
# proxmox-boot-tool kernel pin 5.15.30-1-pve --next-boot
To remove any pinned version configuration use the ``unpin`` subcommand:
.. code-block:: console
# proxmox-boot-tool kernel unpin
While ``unpin`` has a ``--next-boot`` option as well, it is used to clear a pinned
version set with ``--next-boot``. As that happens already automatically on boot,
invonking it manually is of little use.
After setting, or clearing pinned versions you also need to synchronize the
content and configuration on the ESPs by running the ``refresh`` subcommand.
.. TIP:: You will be prompted to automatically do for ``proxmox-boot-tool`` managed
systems if you call the tool interactively.
.. code-block:: console
# proxmox-boot-tool refresh

View File

@ -500,7 +500,7 @@ a single media pool, so a job only uses tapes from that pool.
is less space efficient, because the media from the last set
may not be fully written, leaving the remaining space unused.
The advantage is that this procudes media sets of minimal
The advantage is that this produces media sets of minimal
size. Small sets are easier to handle, can be moved more conveniently
to an off-site vault, and can be restored much faster.
@ -519,8 +519,9 @@ a single media pool, so a job only uses tapes from that pool.
This balances between space efficiency and media count.
.. NOTE:: Retention period starts when the calendar event
triggers.
.. NOTE:: Retention period starts on the creation time of the next
media-set or, if that does not exist, when the calendar event
triggers the next time after the current media-set start time.
Additionally, the following events may allocate a new media set:
@ -564,13 +565,6 @@ a single media pool, so a job only uses tapes from that pool.
the password. Please make sure to remember the password, in case
you need to restore the key.
.. NOTE:: We use global content namespace, meaning we do not store the
source datastore name. Because of this, it is impossible to distinguish
store1:/vm/100 from store2:/vm/100. Please use different media pools
if the sources are from different namespaces with conflicting names
(for example, if the sources are from different Proxmox VE clusters).
.. image:: images/screenshots/pbs-gui-tape-pools-add.png
:align: right
:alt: Tape Backup: Add a media pool
@ -687,6 +681,16 @@ To remove a job, please use:
# proxmox-tape backup-job remove job2
By default, all (recursive) namespaces of the datastore are included in a tape
backup. You can specify a single namespace with ``ns`` and a depth with
``max-depth``. For example:
.. code-block:: console
# proxmox-tape backup-job update job2 --ns mynamespace --max-depth 3
If no `max-depth` is given, it will include all recursive namespaces.
.. image:: images/screenshots/pbs-gui-tape-backup-jobs-add.png
:align: right
:alt: Tape Backup: Add a backup job
@ -803,6 +807,16 @@ The following options are available:
media set into import-export slots. The operator can then pick up
those tapes and move them to a media vault.
--ns The namespace to backup.
If you only want to backup a specific namespace. If omitted, the root
namespaces is assumed.
--max-depth The depth to recurse namespaces.
``0`` means no recursion at all (only the given namespace). If omitted,
all namespaces are recursed (below the the given one).
Restore from Tape
~~~~~~~~~~~~~~~~~
@ -837,6 +851,53 @@ data disk (datastore):
# proxmox-tape restore 9da37a55-aac7-4deb-91c6-482b3b675f30 mystore
Single Snapshot Restore
^^^^^^^^^^^^^^^^^^^^^^^
Sometimes it is not necessary to restore a whole media-set, but only some
specific snapshots from the tape. This can be achieved with the ``snapshots``
parameter:
.. code-block:: console
// proxmox-tape restore <media-set-uuid> <datastore> [<snapshot>]
# proxmox-tape restore 9da37a55-aac7-4deb-91c6-482b3b675f30 mystore sourcestore:host/hostname/2022-01-01T00:01:00Z
This first restores the snapshot to a temporary location, then restores the relevant
chunk archives, and finally restores the snapshot data to the target datastore.
The ``snapshot`` parameter can be given multiple times, so one can restore
multiple snapshots with one restore action.
.. NOTE:: When using the single snapshot restore, the tape must be traversed
more than once, which, if you restore many snapshots at once, can take longer
than restoring the whole datastore.
Namespaces
^^^^^^^^^^
It is also possible to select and map specific namespaces from a media-set
during a restore. This is possible with the ``namespaces`` parameter.
The format of the parameter is
.. code-block:: console
store=<source-datastore>[,source=<source-ns>][,target=<target-ns>][,max-depth=<depth>]
If ``source`` or ``target`` is not given, the root namespace is assumed.
When no ``max-depth`` is given, the source namespace will be fully recursed.
An example restore command:
.. code-block:: console
# proxmox-tape restore 9da37a55-aac7-4deb-91c6-482b3b675f30 mystore --namespaces store=sourcedatastore,source=ns1,target=ns2,max-depth=2
The parameter can be given multiple times. It can also be combined with the
``snapshots`` parameter to only restore those snapshots and map them to different
namespaces.
Update Inventory
~~~~~~~~~~~~~~~~
@ -978,3 +1039,76 @@ This command does the following:
- run drive cleaning operation
- unload the cleaning tape (to slot 3)
Example Setups
--------------
Here are a few example setups for how to manage media pools and schedules.
This is not an exhaustive list, and there are many more possible combinations
of useful settings.
Single Continued Media Set
~~~~~~~~~~~~~~~~~~~~~~~~~~
The most simple setup: always continue the media-set and never expire.
Allocation policy:
continue
Retention policy:
keep
This setup has the advantage of being easy to manage and is re-using the benefits
from deduplication as much as possible. But, it's also prone to a failure of
any single tape, which would render all backups referring to chunks from that
tape unusable.
If you want to start a new media-set manually, you can set the currently
writable media of the set either to 'full', or set the location to an
offsite vault.
Weekday Scheme
~~~~~~~~~~~~~~
A slightly more complex scheme, where the goal is to have an independent
tape or media set for each weekday, for example from Monday to Friday.
This can be solved by having a separate media pool for each day, so 'Monday',
'Tuesday', etc.
Allocation policy:
should be 'mon' for the 'Monday' pool, 'tue' for the Tuesday pool and so on.
Retention policy:
overwrite
There should be a (or more) tape-backup jobs for each pool on the corresponding
weekday. This scheme is still very manageable with one media set per weekday,
and could be easily moved off-site.
Multiple Pools with Different Policies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Complex setups are also possible with multiple media pools configured with
different allocation and retention policies.
An example would be to have two media pools. The first configured with weekly
allocation and a few weeks of retention:
Allocation policy:
mon
Retention policy:
3 weeks
The second pool configured yearly allocation that does not expire:
Allocation policy:
yearly
Retention policy:
keep
In combination with suited prune settings and tape backup schedules, this
achieves long-term storage of some backups, while keeping the current
backups on smaller media sets that get expired every three plus the current
week (~ 4 weeks).

View File

@ -8,7 +8,7 @@ Datastores
A Datastore is the logical place where :ref:`Backup Snapshots
<term_backup_snapshot>` and their chunks are stored. Snapshots consist of a
manifest, blobs, dynamic- and fixed-indexes (see :ref:`terms`), and are
manifest, blobs, and dynamic- and fixed-indexes (see :ref:`terms`), and are
stored in the following directory structure:
<datastore-root>/<type>/<id>/<time>/
@ -32,8 +32,8 @@ The chunks of a datastore are found in
<datastore-root>/.chunks/
This chunk directory is further subdivided by the first four byte of the chunks
checksum, so the chunk with the checksum
This chunk directory is further subdivided by the first four bytes of the
chunk's checksum, so a chunk with the checksum
a342e8151cbf439ce65f3df696b54c67a114982cc0aa751f2852c2f7acc19a8b
@ -47,7 +47,7 @@ per directory can be bad for file system performance.
These chunk directories ('0000'-'ffff') will be preallocated when a datastore
is created.
Fixed-sized Chunks
Fixed-Sized Chunks
^^^^^^^^^^^^^^^^^^
For block based backups (like VMs), fixed-sized chunks are used. The content
@ -58,10 +58,10 @@ often tries to allocate files in contiguous pieces, so new files get new
blocks, and changing existing files changes only their own blocks.
As an optimization, VMs in `Proxmox VE`_ can make use of 'dirty bitmaps', which
can track the changed blocks of an image. Since these bitmap are also a
can track the changed blocks of an image. Since these bitmaps are also a
representation of the image split into chunks, there is a direct relation
between dirty blocks of the image and chunks which need to get uploaded, so
only modified chunks of the disk have to be uploaded for a backup.
between the dirty blocks of the image and chunks which need to be uploaded.
Thus, only modified chunks of the disk need to be uploaded to a backup.
Since the image is always split into chunks of the same size, unchanged blocks
will result in identical checksums for those chunks, so such chunks do not need
@ -71,13 +71,13 @@ changed blocks.
For consistency, `Proxmox VE`_ uses a QEMU internal snapshot mechanism, that
does not rely on storage snapshots either.
Dynamically sized Chunks
Dynamically Sized Chunks
^^^^^^^^^^^^^^^^^^^^^^^^
If one does not want to backup block-based systems but rather file-based
systems, using fixed-sized chunks is not a good idea, since every time a file
would change in size, the remaining data gets shifted around and this would
result in many chunks changing, reducing the amount of deduplication.
When working with file-based systems rather than block-based systems,
using fixed-sized chunks is not a good idea, since every time a file
would change in size, the remaining data would be shifted around,
resulting in many chunks changing and the amount of deduplication being reduced.
To improve this, `Proxmox Backup`_ Server uses dynamically sized chunks
instead. Instead of splitting an image into fixed sizes, it first generates a
@ -86,9 +86,9 @@ over this on-the-fly generated archive to calculate chunk boundaries.
We use a variant of Buzhash which is a cyclic polynomial algorithm. It works
by continuously calculating a checksum while iterating over the data, and on
certain conditions it triggers a hash boundary.
certain conditions, it triggers a hash boundary.
Assuming that most files of the system that is to be backed up have not
Assuming that most files on the system that is to be backed up have not
changed, eventually the algorithm triggers the boundary on the same data as a
previous backup, resulting in chunks that can be reused.
@ -100,8 +100,8 @@ can be encrypted, and they are handled in a slightly different manner than
normal chunks.
The hashes of encrypted chunks are calculated not with the actual (encrypted)
chunk content, but with the plain-text content concatenated with the encryption
key. This way, two chunks of the same data encrypted with different keys
chunk content, but with the plain-text content, concatenated with the encryption
key. This way, two chunks with the same data but encrypted with different keys
generate two different checksums and no collisions occur for multiple
encryption keys.
@ -112,14 +112,14 @@ the previous backup, do not need to be encrypted and uploaded.
Caveats and Limitations
-----------------------
Notes on hash collisions
Notes on Hash Collisions
^^^^^^^^^^^^^^^^^^^^^^^^
Every hashing algorithm has a chance to produce collisions, meaning two (or
more) inputs generate the same checksum. For SHA-256, this chance is
negligible. To calculate such a collision, one can use the ideas of the
'birthday problem' from probability theory. For big numbers, this is actually
infeasible to calculate with regular computers, but there is a good
negligible. To calculate the chances of such a collision, one can use the ideas
of the 'birthday problem' from probability theory. For big numbers, this is
actually unfeasible to calculate with regular computers, but there is a good
approximation:
.. math::
@ -127,7 +127,7 @@ approximation:
p(n, d) = 1 - e^{-n^2/(2d)}
Where `n` is the number of tries, and `d` is the number of possibilities.
For a concrete example lets assume a large datastore of 1 PiB, and an average
For a concrete example, lets assume a large datastore of 1 PiB and an average
chunk size of 4 MiB. That means :math:`n = 268435456` tries, and :math:`d =
2^{256}` possibilities. Inserting those values in the formula from earlier you
will see that the probability of a collision in that scenario is:
@ -136,94 +136,96 @@ will see that the probability of a collision in that scenario is:
3.1115 * 10^{-61}
For context, in a lottery game of guessing 6 out of 45, the chance to correctly
guess all 6 numbers is only :math:`1.2277 * 10^{-7}`, that means the chance of
a collision is about the same as winning 13 such lotto games *in a row*.
For context, in a lottery game of guessing 6 numbers out of 45, the chance to
correctly guess all 6 numbers is only :math:`1.2277 * 10^{-7}`. This means the
chance of a collision is about the same as winning 13 such lottery games *in a
row*.
In conclusion, it is extremely unlikely that such a collision would occur by
accident in a normal datastore.
Additionally, SHA-256 is prone to length extension attacks, but since there is
an upper limit for how big the chunk are, this is not a problem, since a
an upper limit for how big the chunks are, this is not a problem, because a
potential attacker cannot arbitrarily add content to the data beyond that
limit.
File-based Backup
File-Based Backup
^^^^^^^^^^^^^^^^^
Since dynamically sized chunks (for file-based backups) are created on a custom
archive format (pxar) and not over the files directly, there is no relation
between files and the chunks. This means that the Proxmox Backup client has to
between the files and chunks. This means that the Proxmox Backup Client has to
read all files again for every backup, otherwise it would not be possible to
generate a consistent independent pxar archive where the original chunks can be
reused. Note that there will be still only new or change chunks be uploaded.
generate a consistent, independent pxar archive where the original chunks can be
reused. Note that in spite of this, only new or changed chunks will be uploaded.
Verification of encrypted chunks
Verification of Encrypted Chunks
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For encrypted chunks, only the checksum of the original (plaintext) data is
available, making it impossible for the server (without the encryption key), to
available, making it impossible for the server (without the encryption key) to
verify its content against it. Instead only the CRC-32 checksum gets checked.
Troubleshooting
---------------
Index files(.fidx, .didx) contain information about how to rebuild a file, more
precisely, they contain an ordered list of references to the chunks the original
file was split up in. If there is something wrong with a snapshot it might be
useful to find out which chunks are referenced in this specific snapshot, and
check wheather all of them are present and intact. The command for getting the
list of referenced chunks could look something like this:
Index files(*.fidx*, *.didx*) contain information about how to rebuild a file.
More precisely, they contain an ordered list of references to the chunks that
the original file was split into. If there is something wrong with a snapshot,
it might be useful to find out which chunks are referenced in it, and check
whether they are present and intact. The ``proxmox-backup-debug`` command line
tool can be used to inspect such files and recover their contents. For example,
to get a list of the referenced chunks of a *.fidx* index:
.. code-block:: console
# proxmox-backup-debug inspect file drive-scsi0.img.fidx
The same command can be used to look at .blob file, without ``--decode`` just
the size and the encryption type, if any, is printed. If ``--decode`` is set the
blob file is decoded into the specified file('-' will decode it directly into
stdout).
The same command can be used to inspect *.blob* files. Without the ``--decode``
parameter, just the size and the encryption type, if any, are printed. If
``--decode`` is set, the blob file is decoded into the specified file ('-' will
decode it directly to stdout).
The following example would print the decoded contents of
`qemu-server.conf.blob`. If the file you're trying to inspect is encrypted, a
path to the key file must be provided using ``--keyfile``.
.. code-block:: console
# proxmox-backup-debug inspect file qemu-server.conf.blob --decode -
would print the decoded contents of `qemu-server.conf.blob`. If the file you're
trying to inspect is encrypted, a path to the keyfile has to be provided using
``--keyfile``.
Checking in which index files a specific chunk file is referenced can be done
You can also check in which index files a specific chunk file is referenced
with:
.. code-block:: console
# proxmox-backup-debug inspect chunk b531d3ffc9bd7c65748a61198c060678326a431db7eded874c327b7986e595e0 --reference-filter /path/in/a/datastore/directory
Here ``--reference-filter`` specifies where index files should be searched, this
Here ``--reference-filter`` specifies where index files should be searched. This
can be an arbitrary path. If, for some reason, the filename of the chunk was
changed you can explicitly specify the digest using ``--digest``, by default the
chunk filename is used as the digest to look for. Specifying no
``--reference-filter`` will just print the CRC and encryption status of the
chunk. You can also decode chunks, to do so ``--decode`` has to be set. If the
chunk is encrypted a ``--keyfile`` has to be provided for decoding.
changed, you can explicitly specify the digest using ``--digest``. By default, the
chunk filename is used as the digest to look for. If no ``--reference-filter``
is specified, it will only print the CRC and encryption status of the chunk. You
can also decode chunks, by setting the ``--decode`` flag. If the chunk is
encrypted, a ``--keyfile`` must be provided, in order to decode it.
Restore without a running PBS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Restore without a Running Proxmox Backup Server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
It is possible to restore spefiic files of snapshots without a running PBS using
the `recover` sub-command, provided you have access to the intact index and
chunk files. Note that you also need the corresponding key file if the backup
was encrypted.
It's possible to restore specific files from a snapshot, without a running
Proxmox Backup Server instance, using the ``recover`` subcommand, provided you
have access to the intact index and chunk files. Note that you also need the
corresponding key file if the backup was encrypted.
.. code-block:: console
# proxmox-backup-debug recover index drive-scsi0.img.fidx /path/to/.chunks
In above example the `/path/to/.chunks` argument is the path to the directory
that contains contains the chunks, and `drive-scsi0.img.fidx` is the index-file
of the file you'd lile to restore. Both paths can be absolute or relative. With
``--skip-crc`` it is possible to disable the crc checks of the chunks, this will
speed up the process slightly and allows for trying to restore (partially)
In the above example, the `/path/to/.chunks` argument is the path to the
directory that contains the chunks, and `drive-scsi0.img.fidx` is the index file
of the file you'd like to restore. Both paths can be absolute or relative. With
``--skip-crc``, it's possible to disable the CRC checks of the chunks. This
will speed up the process slightly and allow for trying to restore (partially)
corrupt chunks. It's recommended to always try without the skip-CRC option
first.

View File

@ -41,26 +41,35 @@ Binary Data (BLOBs)
~~~~~~~~~~~~~~~~~~~
This type is used to store smaller (< 16MB) binary data such as
configuration files. Larger files should be stored as image archive.
configuration files. Larger files should be stored as image archives.
.. caution:: Please do not store all files as BLOBs. Instead, use the
file archive to store whole directory trees.
file archive to store entire directory trees.
Catalog File: ``catalog.pcat1``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The catalog file is an index for file archives. It contains
the list of files and is used to speed up search operations.
the list of included files and is used to speed up search operations.
The Manifest: ``index.json``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The manifest contains the list of all backup files, their
The manifest contains a list of all backed up files, and their
sizes and checksums. It is used to verify the consistency of a
backup.
Backup Namespace
----------------
Namespaces allow for the reuse of a single chunk store deduplication domain for
multiple sources, while avoiding naming conflicts and getting more fine-grained
access control.
Essentially they're implemented as simple directory structure and need no
separate configuration.
Backup Type
-----------
@ -68,38 +77,40 @@ Backup Type
The backup server groups backups by *type*, where *type* is one of:
``vm``
This type is used for :term:`virtual machine`\ s. Typically
consists of the virtual machine's configuration file and an image archive
for each disk.
This type is used for :term:`virtual machine<Virtual machine>`\ s. It
typically consists of the virtual machine's configuration file and an image
archive for each disk.
``ct``
This type is used for :term:`container`\ s. Consists of the container's
configuration and a single file archive for the filesystem content.
This type is used for :term:`container<Container>`\ s. It consists of the
container's configuration and a single file archive for the filesystem's
contents.
``host``
This type is used for backups created from within the backed up machine.
Typically this would be a physical host but could also be a virtual machine
or container. Such backups may contain file and image archives, there are no restrictions in this regard.
This type is used for file/directory backups created from within a machine.
Typically this would be a physical host, but could also be a virtual machine
or container. Such backups may contain file and image archives; there are no
restrictions in this regard.
Backup ID
---------
A unique ID. Usually the virtual machine or container ID. ``host``
type backups normally use the hostname.
A unique ID for a specific Backup Type and Backup Namespace. Usually the
virtual machine or container ID. ``host`` type backups normally use the
hostname.
Backup Time
-----------
The time when the backup was made.
The time when the backup was made with second resolution.
Backup Group
------------
The tuple ``<type>/<ID>`` is called a backup group. Such a group
may contain one or more backup snapshots.
The tuple ``<type>/<id>`` is called a backup group. Such a group may contain
one or more backup snapshots.
.. _term_backup_snapshot:
@ -115,7 +126,7 @@ uniquely identifies a specific backup within a datastore.
vm/104/2019-10-09T08:01:06Z
host/elsa/2019-11-08T09:48:14Z
As you can see, the time format is RFC3399_ with Coordinated
As you can see, the time format is RFC3339_ with Coordinated
Universal Time (UTC_, identified by the trailing *Z*).

101
docs/traffic-control.rst Normal file
View File

@ -0,0 +1,101 @@
.. _sysadmin_traffic_control:
Traffic Control
---------------
.. image:: images/screenshots/pbs-gui-traffic-control-add.png
:align: right
:alt: Add a traffic control limit
Creating and restoring backups can produce lots of traffic and impact other
users of the network or shared storages.
Proxmox Backup Server allows to limit network traffic for clients within
specified networks using a token bucket filter (TBF).
This allows you to avoid network congestion or to prioritize traffic from
certain hosts.
You can manage the traffic controls either over the web-interface or using the
``traffic-control`` commandos of the ``proxmox-backup-manager`` command-line
tool.
.. note:: Sync jobs on the server are not affected by its rate-in limits. If
you want to limit the incoming traffic that a pull-based sync job
generates, you need to setup a job-specific rate-in limit. See
:ref:`syncjobs`.
The following command adds a traffic control rule to limit all IPv4 clients
(network ``0.0.0.0/0``) to 100 MB/s:
.. code-block:: console
# proxmox-backup-manager traffic-control create rule0 --network 0.0.0.0/0 \
--rate-in 100MB --rate-out 100MB \
--comment "Default rate limit (100MB/s) for all clients"
.. note:: To limit both IPv4 and IPv6 network spaces you need to pass two
network parameters ``::/0`` and ``0.0.0.0/0``.
It is possible to restrict rules to certain time frames, for example the
company office hours:
.. tip:: You can use SI (base 10: KB, MB, ...) or IEC (base 2: KiB, MiB, ...)
units.
.. code-block:: console
# proxmox-backup-manager traffic-control update rule0 \
--timeframe "mon..fri 8-12" \
--timeframe "mon..fri 14:30-18"
If there are more rules, the server uses the rule with the smaller network. For
example, we can overwrite the setting for our private network (and the server
itself) with:
.. code-block:: console
# proxmox-backup-manager traffic-control create rule1 \
--network 192.168.2.0/24 \
--network 127.0.0.0/8 \
--rate-in 20GB --rate-out 20GB \
--comment "Use 20GB/s for the local network"
.. note:: The behavior is undefined if there are several rules for the same network.
If there are multiple rules that match the same network all of them will be
applied, which means that the smallest one wins, as it's bucket fills up the
fastest.
To list the current rules use:
.. code-block:: console
# proxmox-backup-manager traffic-control list
┌───────┬─────────────┬─────────────┬─────────────────────────┬────────────...─┐
│ name │ rate-in │ rate-out │ network │ timeframe ... │
╞═══════╪═════════════╪═════════════╪═════════════════════════╪════════════...═╡
│ rule0 │ 100 MB │ 100 MB │ ["0.0.0.0/0"] │ ["mon..fri ... │
├───────┼─────────────┼─────────────┼─────────────────────────┼────────────...─┤
│ rule1 │ 20 GB │ 20 GB │ ["192.168.2.0/24", ...] │ ... │
└───────┴─────────────┴─────────────┴─────────────────────────┴────────────...─┘
Rules can also be removed:
.. code-block:: console
# proxmox-backup-manager traffic-control remove rule1
To show the state (current data rate) of all configured rules use:
.. code-block:: console
# proxmox-backup-manager traffic-control traffic
┌───────┬─────────────┬──────────────┐
│ name │ cur-rate-in │ cur-rate-out │
╞═══════╪═════════════╪══════════════╡
│ rule0 │ 0 B │ 0 B │
├───────┼─────────────┼──────────────┤
│ rule1 │ 1.161 GiB │ 19.146 KiB │
└───────┴─────────────┴──────────────┘

View File

@ -15,17 +15,19 @@ Proxmox Backup Server supports several authentication realms, and you need to
choose the realm when you add a new user. Possible realms are:
:pam: Linux PAM standard authentication. Use this if you want to
authenticate as Linux system user (Users need to exist on the
authenticate as a Linux system user (users need to exist on the
system).
:pbs: Proxmox Backup Server realm. This type stores hashed passwords in
``/etc/proxmox-backup/shadow.json``.
After installation, there is a single user ``root@pam``, which
corresponds to the Unix superuser. User configuration information is stored in the file
``/etc/proxmox-backup/user.cfg``. You can use the
``proxmox-backup-manager`` command line tool to list or manipulate
users:
:openid: OpenID Connect server. Users can authenticate against an external
OpenID Connect server.
After installation, there is a single user, ``root@pam``, which corresponds to
the Unix superuser. User configuration information is stored in the file
``/etc/proxmox-backup/user.cfg``. You can use the ``proxmox-backup-manager``
command line tool to list or manipulate users:
.. code-block:: console
@ -40,13 +42,13 @@ users:
:align: right
:alt: Add a new user
The superuser has full administration rights on everything, so you
normally want to add other users with less privileges. You can add a new
The superuser has full administration rights on everything, so it's recommended
to add other users with less privileges. You can add a new
user with the ``user create`` subcommand or through the web
interface, under the **User Management** tab of **Configuration -> Access
Control**. The ``create`` subcommand lets you specify many options like
``--email`` or ``--password``. You can update or change any user properties
using the ``update`` subcommand later (**Edit** in the GUI):
using the ``user update`` subcommand later (**Edit** in the GUI):
.. code-block:: console
@ -71,16 +73,16 @@ The resulting user list looks like this:
│ root@pam │ 1 │ │ │ │ │ Superuser │
└──────────┴────────┴────────┴───────────┴──────────┴──────────────────┴──────────────────┘
Newly created users do not have any permissions. Please read the Access Control
Newly created users do not have any permissions. Please read the :ref:`user_acl`
section to learn how to set access permissions.
If you want to disable a user account, you can do that by setting ``--enable`` to ``0``
You can disable a user account by setting ``--enable`` to ``0``:
.. code-block:: console
# proxmox-backup-manager user update john@pbs --enable 0
Or completely remove the user with:
Or completely remove a user with:
.. code-block:: console
@ -95,7 +97,7 @@ API Tokens
:align: right
:alt: API Token Overview
Any authenticated user can generate API tokens which can in turn be used to
Any authenticated user can generate API tokens, which can in turn be used to
configure various clients, instead of directly providing the username and
password.
@ -117,7 +119,7 @@ The API token is passed from the client to the server by setting the
``Authorization`` HTTP header with method ``PBSAPIToken`` to the value
``TOKENID:TOKENSECRET``.
Generating new tokens can done using ``proxmox-backup-manager`` or the GUI:
You can generate tokens from the GUI or by using ``proxmox-backup-manager``:
.. code-block:: console
@ -154,35 +156,134 @@ section to learn how to set access permissions.
Access Control
--------------
By default new users and API tokens do not have any permission. Instead you
need to specify what is allowed and what is not. You can do this by assigning
roles to users/tokens on specific objects like datastores or remotes. The
following roles exist:
By default, new users and API tokens do not have any permissions. Instead you
need to specify what is allowed and what is not.
Proxmox Backup Server uses a role and path based permission management system.
An entry in the permissions table allows a user, group or token to take on a
specific role when accessing an 'object' or 'path'. This means that such an
access rule can be represented as a triple of '(path, user, role)', '(path,
group, role)' or '(path, token, role)', with the role containing a set of
allowed actions, and the path representing the target of these actions.
Privileges
~~~~~~~~~~
Privileges are the atoms that access roles are made off. They are internally
used to enforce the actual permission checks in the API.
We currently support the following privileges:
**Sys.Audit**
Sys.Audit allows one to know about the system and its status.
**Sys.Modify**
Sys.Modify allows one to modify system-level configuration and apply updates.
**Sys.PowerManagement**
Sys.Modify allows one to to poweroff or reboot the system.
**Datastore.Audit**
Datastore.Audit allows one to know about a datastore, including reading the
configuration entry and listing its contents.
**Datastore.Allocate**
Datastore.Allocate allows one to create or deleting datastores.
**Datastore.Modify**
Datastore.Modify allows one to modify a datastore and its contents, and to
create or delete namespaces inside a datastore.
**Datastore.Read**
Datastore.Read allows one to read arbitrary backup contents, independent of
the backup group owner.
**Datastore.Verify**
Allows verifying the backup snapshots in a datastore.
**Datastore.Backup**
Datastore.Backup allows one create new backup snapshot and gives one also the
privileges of Datastore.Read and Datastore.Verify, but only if the backup
group is owned by the user or one of its tokens.
**Datastore.Prune**
Datastore.Prune allows one to delete snapshots, but additionally requires
backup ownership
**Permissions.Modify**
Permissions.Modify allows one to modifying ACLs
.. note:: One can always configure privileges for their own API tokens, as
they will clamped by the users privileges anyway.
**Remote.Audit**
Remote.Audit allows one to read the remote and the sync configuration entries
**Remote.Modify**
Remote.Modify allows one to modify the remote configuration
**Remote.Read**
Remote.Read allows one to read data from a configured `Remote`
**Sys.Console**
Sys.Console allows one to access to the system's console, note that for all
but `root@pam` a valid system login is still required.
**Tape.Audit**
Tape.Audit allows one to read the configuration and status of tape drives,
changers and backups
**Tape.Modify**
Tape.Modify allows one to modify the configuration of tape drives, changers
and backups
**Tape.Write**
Tape.Write allows one to write to a tape media
**Tape.Read**
Tape.Read allows one to read tape backup configuration and contents from a
tape media
**Realm.Allocate**
Realm.Allocate allows one to view, create, modify and delete authentication
realms for users
Access Roles
~~~~~~~~~~~~
An access role combines one or more privileges into something that can be
assigned to an user or API token on an object path.
Currently there are only built-in roles, that means, you cannot create your
own, custom role.
The following roles exist:
**NoAccess**
Disable Access - nothing is allowed.
**Admin**
Can do anything.
Can do anything, on the object path assigned.
**Audit**
Can view things, but is not allowed to change settings.
Can view the status and configuration of things, but is not allowed to change
settings.
**DatastoreAdmin**
Can do anything on datastores.
Can do anything on *existing* datastores.
**DatastoreAudit**
Can view datastore settings and list content. But
is not allowed to read the actual data.
Can view datastore metrics, settings and list content. But is not allowed to
read the actual data.
**DatastoreReader**
Can Inspect datastore content and can do restores.
Can inspect a datastore's or namespaces content and do restores.
**DatastoreBackup**
Can backup and restore owned backups.
**DatastorePowerUser**
Can backup, restore, and prune owned backups.
Can backup, restore, and prune *owned* backups.
**RemoteAdmin**
Can do anything on remotes.
@ -193,7 +294,62 @@ following roles exist:
**RemoteSyncOperator**
Is allowed to read data from a remote.
.. image:: images/screenshots/pbs-gui-user-management-add-user.png
**TapeAdmin**
Can do anything related to tape backup
**TapeAudit**
Can view tape related metrics, configuration and status
**TapeOperator**
Can do tape backup and restore, but cannot change any configuration
**TapeReader**
Can read and inspect tape configuration and media content
Objects and Paths
~~~~~~~~~~~~~~~~~
Access permissions are assigned to objects, such as a datastore, a namespace or
some system resources.
We use file system like paths to address these objects. These paths form a
natural tree, and permissions of higher levels (shorter paths) can optionally
be propagated down within this hierarchy.
Paths can be templated, that means they can refer to the actual id of an
configuration entry. When an API call requires permissions on a templated
path, the path may contain references to parameters of the API call. These
references are specified in curly braces.
Some examples are:
* `/datastore`: Access to *all* datastores on a Proxmox Backup server
* `/datastore/{store}`: Access to a specific datastore on a Proxmox Backup
server
* `/datastore/{store}/{ns}`: Access to a specific namespace on a specific
datastore
* `/remote`: Access to all remote entries
* `/system/network`: Access to configuring the host network
* `/tape/`: Access to tape devices, pools and jobs
* `/access/users`: User administration
* `/access/openid/{id}`: Administrative access to a specific OpenID Connect realm
Inheritance
^^^^^^^^^^^
As mentioned earlier, object paths form a file system like tree, and
permissions can be inherited by objects down that tree through the propagate
flag, which is set by default. We use the following inheritance rules:
* Permissions for API tokens are always clamped to the one of the user.
* Permissions on deeper, more specific levels replace those inherited from an
upper level.
Configuration & Management
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: images/screenshots/pbs-gui-permissions-add.png
:align: right
:alt: Add permissions for user
@ -236,7 +392,8 @@ You can list the ACLs of each user/token using the following command:
│ john@pbs │ /datastore/store1 │ 1 │ DatastoreAdmin │
└──────────┴───────────────────┴───────────┴────────────────┘
A single user/token can be assigned multiple permission sets for different datastores.
A single user/token can be assigned multiple permission sets for different
datastores.
.. Note::
Naming convention is important here. For datastores on the host,
@ -247,11 +404,11 @@ A single user/token can be assigned multiple permission sets for different datas
remote (see `Remote` below) and ``{storename}`` is the name of the datastore on
the remote.
API Token permissions
API Token Permissions
~~~~~~~~~~~~~~~~~~~~~
API token permissions are calculated based on ACLs containing their ID
independent of those of their corresponding user. The resulting permission set
API token permissions are calculated based on ACLs containing their ID,
independently of those of their corresponding user. The resulting permission set
on a given path is then intersected with that of the corresponding user.
In practice this means:
@ -259,10 +416,10 @@ In practice this means:
#. API tokens require their own ACL entries
#. API tokens can never do more than their corresponding user
Effective permissions
Effective Permissions
~~~~~~~~~~~~~~~~~~~~~
To calculate and display the effective permission set of a user or API token
To calculate and display the effective permission set of a user or API token,
you can use the ``proxmox-backup-manager user permission`` command:
.. code-block:: console
@ -287,7 +444,7 @@ you can use the ``proxmox-backup-manager user permission`` command:
.. _user_tfa:
Two-factor authentication
Two-Factor Authentication
-------------------------
Introduction
@ -296,7 +453,7 @@ Introduction
With simple authentication, only a password (single factor) is required to
successfully claim an identity (authenticate), for example, to be able to log in
as `root@pam` on a specific instance of Proxmox Backup Server. In this case, if
the password gets stolen or leaked, anybody can use it to log in - even if they
the password gets leaked or stolen, anybody can use it to log in - even if they
should not be allowed to do so.
With two-factor authentication (TFA), a user is asked for an additional factor
@ -359,16 +516,18 @@ WebAuthn
For WebAuthn to work, you need to have two things:
* a trusted HTTPS certificate (for example, by using `Let's Encrypt
* A trusted HTTPS certificate (for example, by using `Let's Encrypt
<https://pbs.proxmox.com/wiki/index.php/HTTPS_Certificate_Configuration>`_).
While it probably works with an untrusted certificate, some browsers may warn
or refuse WebAuthn operations if it is not trusted.
* setup the WebAuthn configuration (see *Configuration -> Authentication* in the
Proxmox Backup Server web-interface). This can be auto-filled in most setups.
* Setup the WebAuthn configuration (see **Configuration -> Authentication** in
the Proxmox Backup Server web interface). This can be auto-filled in most
setups.
Once you have fulfilled both of these requirements, you can add a WebAuthn
configuration in the *Access Control* panel.
configuration in the **Two Factor Authentication** tab of the **Access Control**
panel.
.. _user_tfa_setup_recovery_keys:
@ -380,7 +539,8 @@ Recovery Keys
:alt: Add a new user
Recovery key codes do not need any preparation; you can simply create a set of
recovery keys in the *Access Control* panel.
recovery keys in the **Two Factor Authentication** tab of the **Access Control**
panel.
.. note:: There can only be one set of single-use recovery keys per user at any
time.

View File

@ -1,9 +1,8 @@
use anyhow::{Error};
use anyhow::Error;
// chacha20-poly1305
fn rate_test(name: &str, bench: &dyn Fn() -> usize) {
print!("{:<20} ", name);
let start = std::time::SystemTime::now();
@ -14,20 +13,19 @@ fn rate_test(name: &str, bench: &dyn Fn() -> usize) {
loop {
bytes += bench();
let elapsed = start.elapsed().unwrap();
if elapsed > duration { break; }
if elapsed > duration {
break;
}
}
let elapsed = start.elapsed().unwrap();
let elapsed = (elapsed.as_secs() as f64) +
(elapsed.subsec_millis() as f64)/1000.0;
let elapsed = (elapsed.as_secs() as f64) + (elapsed.subsec_millis() as f64) / 1000.0;
println!("{:>8.1} MB/s", (bytes as f64)/(elapsed*1024.0*1024.0));
println!("{:>8.1} MB/s", (bytes as f64) / (elapsed * 1024.0 * 1024.0));
}
fn main() -> Result<(), Error> {
let input = proxmox::sys::linux::random_data(1024*1024)?;
let input = proxmox_sys::linux::random_data(1024 * 1024)?;
rate_test("crc32", &|| {
let mut crchasher = crc32fast::Hasher::new();
@ -46,35 +44,23 @@ fn main() -> Result<(), Error> {
input.len()
});
let key = proxmox::sys::linux::random_data(32)?;
let key = proxmox_sys::linux::random_data(32)?;
let iv = proxmox::sys::linux::random_data(16)?;
let iv = proxmox_sys::linux::random_data(16)?;
let cipher = openssl::symm::Cipher::aes_256_gcm();
rate_test("aes-256-gcm", &|| {
let mut tag = [0u8;16];
openssl::symm::encrypt_aead(
cipher,
&key,
Some(&iv),
b"",
&input,
&mut tag).unwrap();
let mut tag = [0u8; 16];
openssl::symm::encrypt_aead(cipher, &key, Some(&iv), b"", &input, &mut tag).unwrap();
input.len()
});
let cipher = openssl::symm::Cipher::chacha20_poly1305();
rate_test("chacha20-poly1305", &|| {
let mut tag = [0u8;16];
openssl::symm::encrypt_aead(
cipher,
&key,
Some(&iv[..12]),
b"",
&input,
&mut tag).unwrap();
let mut tag = [0u8; 16];
openssl::symm::encrypt_aead(cipher, &key, Some(&iv[..12]), b"", &input, &mut tag).unwrap();
input.len()
});

View File

@ -1,6 +1,7 @@
use anyhow::{Error};
use anyhow::Error;
use proxmox::api::{*, cli::*};
use proxmox_router::cli::*;
use proxmox_schema::*;
#[api(
input: {
@ -15,9 +16,7 @@ use proxmox::api::{*, cli::*};
/// Echo command. Print the passed text.
///
/// Returns: nothing
fn echo_command(
text: String,
) -> Result<(), Error> {
fn echo_command(text: String) -> Result<(), Error> {
println!("{}", text);
Ok(())
}
@ -36,9 +35,7 @@ fn echo_command(
/// Hello command.
///
/// Returns: nothing
fn hello_command(
verbose: Option<bool>,
) -> Result<(), Error> {
fn hello_command(verbose: Option<bool>) -> Result<(), Error> {
if verbose.unwrap_or(false) {
println!("Hello, how are you!");
} else {
@ -53,7 +50,6 @@ fn hello_command(
///
/// Returns: nothing
fn quit_command() -> Result<(), Error> {
println!("Goodbye.");
std::process::exit(0);
@ -63,8 +59,9 @@ fn cli_definition() -> CommandLineInterface {
let cmd_def = CliCommandMap::new()
.insert("quit", CliCommand::new(&API_METHOD_QUIT_COMMAND))
.insert("hello", CliCommand::new(&API_METHOD_HELLO_COMMAND))
.insert("echo", CliCommand::new(&API_METHOD_ECHO_COMMAND)
.arg_param(&["text"])
.insert(
"echo",
CliCommand::new(&API_METHOD_ECHO_COMMAND).arg_param(&["text"]),
)
.insert_help();
@ -72,7 +69,6 @@ fn cli_definition() -> CommandLineInterface {
}
fn main() -> Result<(), Error> {
let helper = CliHelper::new(cli_definition());
let mut rl = rustyline::Editor::<CliHelper>::new();

View File

@ -1,16 +1,15 @@
use std::io::Write;
use anyhow::{Error};
use anyhow::Error;
use pbs_api_types::Authid;
use pbs_client::{HttpClient, HttpClientOptions, BackupReader};
use pbs_api_types::{Authid, BackupNamespace, BackupType};
use pbs_client::{BackupReader, HttpClient, HttpClientOptions};
pub struct DummyWriter {
bytes: usize,
}
impl Write for DummyWriter {
fn write(&mut self, data: &[u8]) -> Result<usize, std::io::Error> {
self.bytes += data.len();
Ok(data.len())
@ -21,9 +20,7 @@ impl Write for DummyWriter {
}
}
async fn run() -> Result<(), Error> {
let host = "localhost";
let auth_id = Authid::root_auth_id();
@ -34,9 +31,16 @@ async fn run() -> Result<(), Error> {
let client = HttpClient::new(host, 8007, auth_id, options)?;
let backup_time = proxmox::tools::time::parse_rfc3339("2019-06-28T10:49:48Z")?;
let backup_time = proxmox_time::parse_rfc3339("2019-06-28T10:49:48Z")?;
let client = BackupReader::start(client, None, "store2", "host", "elsa", backup_time, true)
let client = BackupReader::start(
client,
None,
"store2",
&BackupNamespace::root(),
&(BackupType::Host, "elsa".to_string(), backup_time).into(),
true,
)
.await?;
let start = std::time::SystemTime::now();
@ -50,16 +54,19 @@ async fn run() -> Result<(), Error> {
}
let elapsed = start.elapsed().unwrap();
let elapsed = (elapsed.as_secs() as f64) +
(elapsed.subsec_millis() as f64)/1000.0;
let elapsed = (elapsed.as_secs() as f64) + (elapsed.subsec_millis() as f64) / 1000.0;
println!("Downloaded {} bytes, {} MB/s", bytes, (bytes as f64)/(elapsed*1024.0*1024.0));
println!(
"Downloaded {} bytes, {} MB/s",
bytes,
(bytes as f64) / (elapsed * 1024.0 * 1024.0)
);
Ok(())
}
fn main() {
if let Err(err) = pbs_runtime::main(run()) {
if let Err(err) = proxmox_async::runtime::main(run()) {
eprintln!("ERROR: {}", err);
}
println!("DONE");

View File

@ -1,8 +1,8 @@
use anyhow::{bail, Error};
use std::thread;
use std::path::PathBuf;
use std::io::Write;
use std::path::PathBuf;
use std::thread;
use anyhow::{bail, Error};
// tar handle files that shrink during backup, by simply padding with zeros.
//
@ -19,15 +19,15 @@ use std::io::Write;
// Error: detected shrunk file "./dyntest1/testfile0.dat" (22020096 < 12679380992)
fn create_large_file(path: PathBuf) {
println!("TEST {:?}", path);
let mut file = std::fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(&path).unwrap();
.open(&path)
.unwrap();
let buffer = vec![0u8; 64*1024];
let buffer = vec![0u8; 64 * 1024];
loop {
for _ in 0..64 {
@ -40,7 +40,6 @@ fn create_large_file(path: PathBuf) {
}
fn main() -> Result<(), Error> {
let base = PathBuf::from("dyntest1");
let _ = std::fs::create_dir(&base);

View File

@ -69,7 +69,7 @@ fn send_request(
}
fn main() -> Result<(), Error> {
pbs_runtime::main(run())
proxmox_async::runtime::main(run())
}
async fn run() -> Result<(), Error> {

View File

@ -69,7 +69,7 @@ fn send_request(
}
fn main() -> Result<(), Error> {
pbs_runtime::main(run())
proxmox_async::runtime::main(run())
}
async fn run() -> Result<(), Error> {

View File

@ -9,7 +9,7 @@ use tokio::net::{TcpListener, TcpStream};
use pbs_buildcfg::configdir;
fn main() -> Result<(), Error> {
pbs_runtime::main(run())
proxmox_async::runtime::main(run())
}
async fn run() -> Result<(), Error> {

View File

@ -5,7 +5,7 @@ use hyper::{Body, Request, Response};
use tokio::net::{TcpListener, TcpStream};
fn main() -> Result<(), Error> {
pbs_runtime::main(run())
proxmox_async::runtime::main(run())
}
async fn run() -> Result<(), Error> {

View File

@ -2,7 +2,7 @@ extern crate proxmox_backup;
// also see https://www.johndcook.com/blog/standard_deviation/
use anyhow::{Error};
use anyhow::Error;
use std::io::{Read, Write};
use pbs_datastore::Chunker;
@ -21,7 +21,6 @@ struct ChunkWriter {
}
impl ChunkWriter {
fn new(chunk_size: usize) -> Self {
ChunkWriter {
chunker: Chunker::new(chunk_size),
@ -37,7 +36,6 @@ impl ChunkWriter {
}
fn record_stat(&mut self, chunk_size: f64) {
self.chunk_count += 1;
if self.chunk_count == 1 {
@ -45,28 +43,30 @@ impl ChunkWriter {
self.m_new = chunk_size;
self.s_old = 0.0;
} else {
self.m_new = self.m_old + (chunk_size - self.m_old)/(self.chunk_count as f64);
self.s_new = self.s_old +
(chunk_size - self.m_old)*(chunk_size - self.m_new);
self.m_new = self.m_old + (chunk_size - self.m_old) / (self.chunk_count as f64);
self.s_new = self.s_old + (chunk_size - self.m_old) * (chunk_size - self.m_new);
// set up for next iteration
self.m_old = self.m_new;
self.s_old = self.s_new;
}
let variance = if self.chunk_count > 1 {
self.s_new/((self.chunk_count -1)as f64)
} else { 0.0 };
self.s_new / ((self.chunk_count - 1) as f64)
} else {
0.0
};
let std_deviation = variance.sqrt();
let deviation_per = (std_deviation*100.0)/self.m_new;
println!("COUNT {:10} SIZE {:10} MEAN {:10} DEVIATION {:3}%", self.chunk_count, chunk_size, self.m_new as usize, deviation_per as usize);
let deviation_per = (std_deviation * 100.0) / self.m_new;
println!(
"COUNT {:10} SIZE {:10} MEAN {:10} DEVIATION {:3}%",
self.chunk_count, chunk_size, self.m_new as usize, deviation_per as usize
);
}
}
impl Write for ChunkWriter {
fn write(&mut self, data: &[u8]) -> std::result::Result<usize, std::io::Error> {
let chunker = &mut self.chunker;
let pos = chunker.scan(data);
@ -80,7 +80,6 @@ impl Write for ChunkWriter {
self.last_chunk = self.chunk_offset;
Ok(pos)
} else {
self.chunk_offset += data.len();
Ok(data.len())
@ -93,23 +92,23 @@ impl Write for ChunkWriter {
}
fn main() -> Result<(), Error> {
let mut file = std::fs::File::open("/dev/urandom")?;
let mut bytes = 0;
let mut buffer = [0u8; 64*1024];
let mut buffer = [0u8; 64 * 1024];
let mut writer = ChunkWriter::new(4096*1024);
let mut writer = ChunkWriter::new(4096 * 1024);
loop {
file.read_exact(&mut buffer)?;
bytes += buffer.len();
writer.write_all(&buffer)?;
if bytes > 1024*1024*1024 { break; }
if bytes > 1024 * 1024 * 1024 {
break;
}
}
Ok(())

View File

@ -3,17 +3,16 @@ extern crate proxmox_backup;
use pbs_datastore::Chunker;
fn main() {
let mut buffer = Vec::new();
for i in 0..20*1024*1024 {
for i in 0..20 * 1024 * 1024 {
for j in 0..4 {
let byte = ((i >> (j<<3))&0xff) as u8;
let byte = ((i >> (j << 3)) & 0xff) as u8;
//println!("BYTE {}", byte);
buffer.push(byte);
}
}
let mut chunker = Chunker::new(64*1024);
let mut chunker = Chunker::new(64 * 1024);
let count = 5;
@ -39,11 +38,14 @@ fn main() {
}
let elapsed = start.elapsed().unwrap();
let elapsed = (elapsed.as_secs() as f64) +
(elapsed.subsec_millis() as f64)/1000.0;
let elapsed = (elapsed.as_secs() as f64) + (elapsed.subsec_millis() as f64) / 1000.0;
let mbytecount = ((count*buffer.len()) as f64) / (1024.0*1024.0);
let avg_chunk_size = mbytecount/(chunk_count as f64);
let mbytes_per_sec = mbytecount/elapsed;
println!("SPEED = {} MB/s, avg chunk size = {} KB", mbytes_per_sec, avg_chunk_size*1024.0);
let mbytecount = ((count * buffer.len()) as f64) / (1024.0 * 1024.0);
let avg_chunk_size = mbytecount / (chunk_count as f64);
let mbytes_per_sec = mbytecount / elapsed;
println!(
"SPEED = {} MB/s, avg chunk size = {} KB",
mbytes_per_sec,
avg_chunk_size * 1024.0
);
}

View File

@ -1,4 +1,4 @@
use anyhow::{Error};
use anyhow::Error;
use futures::*;
extern crate proxmox_backup;
@ -13,13 +13,12 @@ use pbs_client::ChunkStream;
// Note: I can currently get about 830MB/s
fn main() {
if let Err(err) = pbs_runtime::main(run()) {
if let Err(err) = proxmox_async::runtime::main(run()) {
panic!("ERROR: {}", err);
}
}
async fn run() -> Result<(), Error> {
let file = tokio::fs::File::open("random-test.dat").await?;
let stream = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
@ -34,7 +33,7 @@ async fn run() -> Result<(), Error> {
let mut repeat = 0;
let mut stream_len = 0;
while let Some(chunk) = chunk_stream.try_next().await? {
if chunk.len() > 16*1024*1024 {
if chunk.len() > 16 * 1024 * 1024 {
panic!("Chunk too large {}", chunk.len());
}
@ -44,10 +43,19 @@ async fn run() -> Result<(), Error> {
println!("Got chunk {}", chunk.len());
}
let speed = ((stream_len*1_000_000)/(1024*1024))/(start_time.elapsed().as_micros() as usize);
println!("Uploaded {} chunks in {} seconds ({} MB/s).", repeat, start_time.elapsed().as_secs(), speed);
println!("Average chunk size was {} bytes.", stream_len/repeat);
println!("time per request: {} microseconds.", (start_time.elapsed().as_micros())/(repeat as u128));
let speed =
((stream_len * 1_000_000) / (1024 * 1024)) / (start_time.elapsed().as_micros() as usize);
println!(
"Uploaded {} chunks in {} seconds ({} MB/s).",
repeat,
start_time.elapsed().as_secs(),
speed
);
println!("Average chunk size was {} bytes.", stream_len / repeat);
println!(
"time per request: {} microseconds.",
(start_time.elapsed().as_micros()) / (repeat as u128)
);
Ok(())
}

View File

@ -1,10 +1,9 @@
use anyhow::{Error};
use anyhow::Error;
use pbs_client::{HttpClient, HttpClientOptions, BackupWriter};
use pbs_api_types::Authid;
use pbs_api_types::{Authid, BackupNamespace, BackupType};
use pbs_client::{BackupWriter, HttpClient, HttpClientOptions};
async fn upload_speed() -> Result<f64, Error> {
let host = "localhost";
let datastore = "store2";
@ -16,9 +15,18 @@ async fn upload_speed() -> Result<f64, Error> {
let client = HttpClient::new(host, 8007, auth_id, options)?;
let backup_time = proxmox::tools::time::epoch_i64();
let backup_time = proxmox_time::epoch_i64();
let client = BackupWriter::start(client, None, datastore, "host", "speedtest", backup_time, false, true).await?;
let client = BackupWriter::start(
client,
None,
datastore,
&BackupNamespace::root(),
&(BackupType::Host, "speedtest".to_string(), backup_time).into(),
false,
true,
)
.await?;
println!("start upload speed test");
let res = client.upload_speedtest(true).await?;
@ -27,7 +35,7 @@ async fn upload_speed() -> Result<f64, Error> {
}
fn main() {
match pbs_runtime::main(upload_speed()) {
match proxmox_async::runtime::main(upload_speed()) {
Ok(mbs) => {
println!("average upload speed: {} MB/s", mbs);
}

View File

@ -7,14 +7,15 @@ description = "general API type helpers for PBS"
[dependencies]
anyhow = "1.0"
hex = "0.4.3"
lazy_static = "1.4"
libc = "0.2"
nix = "0.19.1"
openssl = "0.10"
regex = "1.2"
percent-encoding = "2.1"
regex = "1.5.5"
serde = { version = "1.0", features = ["derive"] }
serde_plain = "1"
proxmox = { version = "0.13.3", default-features = false, features = [ "api-macro" ] }
proxmox-systemd = { path = "../proxmox-systemd" }
pbs-tools = { path = "../pbs-tools" }
proxmox-lang = "1.0.0"
proxmox-schema = { version = "1.2.1", features = [ "api-macro" ] }
proxmox-serde = "0.1"
proxmox-time = "1.1.1"
proxmox-uuid = { version = "1.0.0", features = [ "serde" ] }

View File

@ -1,13 +1,12 @@
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use serde::de::{value, IntoDeserializer};
use serde::{Deserialize, Serialize};
use proxmox::api::api;
use proxmox::api::schema::{
ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
use proxmox_lang::constnamedbitmap;
use proxmox_schema::{
api, const_regex, ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
};
use proxmox::{constnamedbitmap, const_regex};
const_regex! {
pub ACL_PATH_REGEX = concat!(r"^(?:/|", r"(?:/", PROXMOX_SAFE_ID_REGEX_STR!(), ")+", r")$");
@ -74,9 +73,20 @@ constnamedbitmap! {
}
}
pub fn privs_to_priv_names(privs: u64) -> Vec<&'static str> {
PRIVILEGES
.iter()
.fold(Vec::new(), |mut priv_names, (name, value)| {
if value & privs != 0 {
priv_names.push(name);
}
priv_names
})
}
/// Admin always has all privileges. It can do everything except a few actions
/// which are limited to the 'root@pam` superuser
pub const ROLE_ADMIN: u64 = std::u64::MAX;
pub const ROLE_ADMIN: u64 = u64::MAX;
/// NoAccess can be used to remove privileges from specific (sub-)paths
pub const ROLE_NO_ACCESS: u64 = 0;
@ -222,7 +232,6 @@ pub enum Role {
TapeReader = ROLE_TAPE_READER,
}
impl FromStr for Role {
type Err = value::Error;
@ -231,26 +240,24 @@ impl FromStr for Role {
}
}
pub const ACL_PATH_FORMAT: ApiStringFormat =
ApiStringFormat::Pattern(&ACL_PATH_REGEX);
pub const ACL_PATH_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&ACL_PATH_REGEX);
pub const ACL_PATH_SCHEMA: Schema = StringSchema::new(
"Access control path.")
pub const ACL_PATH_SCHEMA: Schema = StringSchema::new("Access control path.")
.format(&ACL_PATH_FORMAT)
.min_length(1)
.max_length(128)
.schema();
pub const ACL_PROPAGATE_SCHEMA: Schema = BooleanSchema::new(
"Allow to propagate (inherit) permissions.")
pub const ACL_PROPAGATE_SCHEMA: Schema =
BooleanSchema::new("Allow to propagate (inherit) permissions.")
.default(true)
.schema();
pub const ACL_UGID_TYPE_SCHEMA: Schema = StringSchema::new(
"Type of 'ugid' property.")
pub const ACL_UGID_TYPE_SCHEMA: Schema = StringSchema::new("Type of 'ugid' property.")
.format(&ApiStringFormat::Enum(&[
EnumEntry::new("user", "User"),
EnumEntry::new("group", "Group")]))
EnumEntry::new("group", "Group"),
]))
.schema();
#[api(

View File

@ -0,0 +1,78 @@
//! Predefined Regular Expressions
//!
//! This is a collection of useful regular expressions
use lazy_static::lazy_static;
use regex::Regex;
#[rustfmt::skip]
#[macro_export]
macro_rules! IPV4OCTET { () => (r"(?:25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])") }
#[rustfmt::skip]
#[macro_export]
macro_rules! IPV6H16 { () => (r"(?:[0-9a-fA-F]{1,4})") }
#[rustfmt::skip]
#[macro_export]
macro_rules! IPV6LS32 { () => (concat!(r"(?:(?:", IPV4RE!(), "|", IPV6H16!(), ":", IPV6H16!(), "))" )) }
/// Returns the regular expression string to match IPv4 addresses
#[rustfmt::skip]
#[macro_export]
macro_rules! IPV4RE { () => (concat!(r"(?:(?:", IPV4OCTET!(), r"\.){3}", IPV4OCTET!(), ")")) }
/// Returns the regular expression string to match IPv6 addresses
#[rustfmt::skip]
#[macro_export]
macro_rules! IPV6RE { () => (concat!(r"(?:",
r"(?:(?:", r"(?:", IPV6H16!(), r":){6})", IPV6LS32!(), r")|",
r"(?:(?:", r"::(?:", IPV6H16!(), r":){5})", IPV6LS32!(), r")|",
r"(?:(?:(?:", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){4})", IPV6LS32!(), r")|",
r"(?:(?:(?:(?:", IPV6H16!(), r":){0,1}", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){3})", IPV6LS32!(), r")|",
r"(?:(?:(?:(?:", IPV6H16!(), r":){0,2}", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){2})", IPV6LS32!(), r")|",
r"(?:(?:(?:(?:", IPV6H16!(), r":){0,3}", IPV6H16!(), r")?::(?:", IPV6H16!(), r":){1})", IPV6LS32!(), r")|",
r"(?:(?:(?:(?:", IPV6H16!(), r":){0,4}", IPV6H16!(), r")?::", ")", IPV6LS32!(), r")|",
r"(?:(?:(?:(?:", IPV6H16!(), r":){0,5}", IPV6H16!(), r")?::", ")", IPV6H16!(), r")|",
r"(?:(?:(?:(?:", IPV6H16!(), r":){0,6}", IPV6H16!(), r")?::", ")))"))
}
/// Returns the regular expression string to match IP addresses (v4 or v6)
#[rustfmt::skip]
#[macro_export]
macro_rules! IPRE { () => (concat!(r"(?:", IPV4RE!(), "|", IPV6RE!(), ")")) }
/// Regular expression string to match IP addresses where IPv6 addresses require brackets around
/// them, while for IPv4 they are forbidden.
#[rustfmt::skip]
#[macro_export]
macro_rules! IPRE_BRACKET { () => (
concat!(r"(?:",
IPV4RE!(),
r"|\[(?:",
IPV6RE!(),
r")\]",
r")"))
}
lazy_static! {
pub static ref IP_REGEX: Regex = Regex::new(concat!(r"^", IPRE!(), r"$")).unwrap();
pub static ref IP_BRACKET_REGEX: Regex =
Regex::new(concat!(r"^", IPRE_BRACKET!(), r"$")).unwrap();
pub static ref SHA256_HEX_REGEX: Regex = Regex::new(r"^[a-f0-9]{64}$").unwrap();
pub static ref SYSTEMD_DATETIME_REGEX: Regex =
Regex::new(r"^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$").unwrap();
}
#[test]
fn test_regexes() {
assert!(IP_REGEX.is_match("127.0.0.1"));
assert!(IP_REGEX.is_match("::1"));
assert!(IP_REGEX.is_match("2014:b3a::27"));
assert!(IP_REGEX.is_match("2014:b3a::192.168.0.1"));
assert!(IP_REGEX.is_match("2014:b3a:0102:adf1:1234:4321:4afA:BCDF"));
assert!(IP_BRACKET_REGEX.is_match("127.0.0.1"));
assert!(IP_BRACKET_REGEX.is_match("[::1]"));
assert!(IP_BRACKET_REGEX.is_match("[2014:b3a::27]"));
assert!(IP_BRACKET_REGEX.is_match("[2014:b3a::192.168.0.1]"));
assert!(IP_BRACKET_REGEX.is_match("[2014:b3a:0102:adf1:1234:4321:4afA:BCDF]"));
}

View File

@ -3,9 +3,7 @@ use std::fmt::{self, Display};
use anyhow::Error;
use serde::{Deserialize, Serialize};
use proxmox::api::api;
use pbs_tools::format::{as_fingerprint, bytes_as_fingerprint};
use proxmox_schema::api;
#[api(default: "encrypt")]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
@ -35,6 +33,9 @@ impl Fingerprint {
pub fn bytes(&self) -> &[u8; 32] {
&self.bytes
}
pub fn signature(&self) -> String {
as_fingerprint(&self.bytes)
}
}
/// Display as short key ID
@ -50,8 +51,45 @@ impl std::str::FromStr for Fingerprint {
fn from_str(s: &str) -> Result<Self, Error> {
let mut tmp = s.to_string();
tmp.retain(|c| c != ':');
let bytes = proxmox::tools::hex_to_digest(&tmp)?;
let mut bytes = [0u8; 32];
hex::decode_to_slice(&tmp, &mut bytes)?;
Ok(Fingerprint::new(bytes))
}
}
fn as_fingerprint(bytes: &[u8]) -> String {
hex::encode(bytes)
.as_bytes()
.chunks(2)
.map(|v| unsafe { std::str::from_utf8_unchecked(v) }) // it's a hex string
.collect::<Vec<&str>>()
.join(":")
}
pub mod bytes_as_fingerprint {
use std::mem::MaybeUninit;
use serde::{Deserialize, Deserializer, Serializer};
pub fn serialize<S>(bytes: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = super::as_fingerprint(bytes);
serializer.serialize_str(&s)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
where
D: Deserializer<'de>,
{
// TODO: more efficiently implement with a Visitor implementing visit_str using split() and
// hex::decode by-byte
let mut s = String::deserialize(deserializer)?;
s.retain(|c| c != ':');
let mut out = MaybeUninit::<[u8; 32]>::uninit();
hex::decode_to_slice(s.as_bytes(), unsafe { &mut (*out.as_mut_ptr())[..] })
.map_err(serde::de::Error::custom)?;
Ok(unsafe { out.assume_init() })
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};
use proxmox::api::api;
use proxmox_schema::api;
#[api]
#[derive(Serialize, Deserialize)]

View File

@ -0,0 +1,358 @@
use anyhow::{bail, Error};
use proxmox_schema::{ApiStringFormat, ApiType, Schema, StringSchema, UpdaterType};
/// Size units for byte sizes
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum SizeUnit {
Byte,
// SI (base 10)
KByte,
MByte,
GByte,
TByte,
PByte,
// IEC (base 2)
Kibi,
Mebi,
Gibi,
Tebi,
Pebi,
}
impl SizeUnit {
/// Returns the scaling factor
pub fn factor(&self) -> f64 {
match self {
SizeUnit::Byte => 1.0,
// SI (base 10)
SizeUnit::KByte => 1_000.0,
SizeUnit::MByte => 1_000_000.0,
SizeUnit::GByte => 1_000_000_000.0,
SizeUnit::TByte => 1_000_000_000_000.0,
SizeUnit::PByte => 1_000_000_000_000_000.0,
// IEC (base 2)
SizeUnit::Kibi => 1024.0,
SizeUnit::Mebi => 1024.0 * 1024.0,
SizeUnit::Gibi => 1024.0 * 1024.0 * 1024.0,
SizeUnit::Tebi => 1024.0 * 1024.0 * 1024.0 * 1024.0,
SizeUnit::Pebi => 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0,
}
}
/// gets the biggest possible unit still having a value greater zero before the decimal point
/// 'binary' specifies if IEC (base 2) units should be used or SI (base 10) ones
pub fn auto_scale(size: f64, binary: bool) -> SizeUnit {
if binary {
let bits = 64 - (size as u64).leading_zeros();
match bits {
51.. => SizeUnit::Pebi,
41..=50 => SizeUnit::Tebi,
31..=40 => SizeUnit::Gibi,
21..=30 => SizeUnit::Mebi,
11..=20 => SizeUnit::Kibi,
_ => SizeUnit::Byte,
}
} else if size >= 1_000_000_000_000_000.0 {
SizeUnit::PByte
} else if size >= 1_000_000_000_000.0 {
SizeUnit::TByte
} else if size >= 1_000_000_000.0 {
SizeUnit::GByte
} else if size >= 1_000_000.0 {
SizeUnit::MByte
} else if size >= 1_000.0 {
SizeUnit::KByte
} else {
SizeUnit::Byte
}
}
}
/// Returns the string repesentation
impl std::fmt::Display for SizeUnit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SizeUnit::Byte => write!(f, "B"),
// SI (base 10)
SizeUnit::KByte => write!(f, "KB"),
SizeUnit::MByte => write!(f, "MB"),
SizeUnit::GByte => write!(f, "GB"),
SizeUnit::TByte => write!(f, "TB"),
SizeUnit::PByte => write!(f, "PB"),
// IEC (base 2)
SizeUnit::Kibi => write!(f, "KiB"),
SizeUnit::Mebi => write!(f, "MiB"),
SizeUnit::Gibi => write!(f, "GiB"),
SizeUnit::Tebi => write!(f, "TiB"),
SizeUnit::Pebi => write!(f, "PiB"),
}
}
}
/// Strips a trailing SizeUnit inclusive trailing whitespace
/// Supports both IEC and SI based scales, the B/b byte symbol is optional.
fn strip_unit(v: &str) -> (&str, SizeUnit) {
let v = v.strip_suffix(&['b', 'B'][..]).unwrap_or(v); // byte is implied anyway
let (v, binary) = match v.strip_suffix('i') {
Some(n) => (n, true),
None => (v, false),
};
let mut unit = SizeUnit::Byte;
#[rustfmt::skip]
let value = v.strip_suffix(|c: char| match c {
'k' | 'K' if !binary => { unit = SizeUnit::KByte; true }
'm' | 'M' if !binary => { unit = SizeUnit::MByte; true }
'g' | 'G' if !binary => { unit = SizeUnit::GByte; true }
't' | 'T' if !binary => { unit = SizeUnit::TByte; true }
'p' | 'P' if !binary => { unit = SizeUnit::PByte; true }
// binary (IEC recommended) variants
'k' | 'K' if binary => { unit = SizeUnit::Kibi; true }
'm' | 'M' if binary => { unit = SizeUnit::Mebi; true }
'g' | 'G' if binary => { unit = SizeUnit::Gibi; true }
't' | 'T' if binary => { unit = SizeUnit::Tebi; true }
'p' | 'P' if binary => { unit = SizeUnit::Pebi; true }
_ => false
}).unwrap_or(v).trim_end();
(value, unit)
}
/// Byte size which can be displayed in a human friendly way
#[derive(Debug, Copy, Clone, UpdaterType)]
pub struct HumanByte {
/// The siginficant value, it does not includes any factor of the `unit`
size: f64,
/// The scale/unit of the value
unit: SizeUnit,
}
fn verify_human_byte(s: &str) -> Result<(), Error> {
match s.parse::<HumanByte>() {
Ok(_) => Ok(()),
Err(err) => bail!("byte-size parse error for '{}': {}", s, err),
}
}
impl ApiType for HumanByte {
const API_SCHEMA: Schema = StringSchema::new(
"Byte size with optional unit (B, KB (base 10), MB, GB, ..., KiB (base 2), MiB, Gib, ...).",
)
.format(&ApiStringFormat::VerifyFn(verify_human_byte))
.min_length(1)
.max_length(64)
.schema();
}
impl HumanByte {
/// Create instance with size and unit (size must be positive)
pub fn with_unit(size: f64, unit: SizeUnit) -> Result<Self, Error> {
if size < 0.0 {
bail!("byte size may not be negative");
}
Ok(HumanByte { size, unit })
}
/// Create a new instance with optimal binary unit computed
pub fn new_binary(size: f64) -> Self {
let unit = SizeUnit::auto_scale(size, true);
HumanByte {
size: size / unit.factor(),
unit,
}
}
/// Create a new instance with optimal decimal unit computed
pub fn new_decimal(size: f64) -> Self {
let unit = SizeUnit::auto_scale(size, false);
HumanByte {
size: size / unit.factor(),
unit,
}
}
/// Returns the size as u64 number of bytes
pub fn as_u64(&self) -> u64 {
self.as_f64() as u64
}
/// Returns the size as f64 number of bytes
pub fn as_f64(&self) -> f64 {
self.size * self.unit.factor()
}
/// Returns a copy with optimal binary unit computed
pub fn auto_scale_binary(self) -> Self {
HumanByte::new_binary(self.as_f64())
}
/// Returns a copy with optimal decimal unit computed
pub fn auto_scale_decimal(self) -> Self {
HumanByte::new_decimal(self.as_f64())
}
}
impl From<u64> for HumanByte {
fn from(v: u64) -> Self {
HumanByte::new_binary(v as f64)
}
}
impl From<usize> for HumanByte {
fn from(v: usize) -> Self {
HumanByte::new_binary(v as f64)
}
}
impl std::fmt::Display for HumanByte {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let precision = f.precision().unwrap_or(3) as f64;
let precision_factor = 1.0 * 10.0_f64.powf(precision);
// this could cause loss of information, rust has sadly no shortest-max-X flt2dec fmt yet
let size = ((self.size * precision_factor).round()) / precision_factor;
write!(f, "{} {}", size, self.unit)
}
}
impl std::str::FromStr for HumanByte {
type Err = Error;
fn from_str(v: &str) -> Result<Self, Error> {
let (v, unit) = strip_unit(v);
HumanByte::with_unit(v.parse()?, unit)
}
}
proxmox_serde::forward_deserialize_to_from_str!(HumanByte);
proxmox_serde::forward_serialize_to_display!(HumanByte);
#[test]
fn test_human_byte_parser() -> Result<(), Error> {
assert!("-10".parse::<HumanByte>().is_err()); // negative size
fn do_test(v: &str, size: f64, unit: SizeUnit, as_str: &str) -> Result<(), Error> {
let h: HumanByte = v.parse()?;
if h.size != size {
bail!("got unexpected size for '{}' ({} != {})", v, h.size, size);
}
if h.unit != unit {
bail!(
"got unexpected unit for '{}' ({:?} != {:?})",
v,
h.unit,
unit
);
}
let new = h.to_string();
if &new != as_str {
bail!("to_string failed for '{}' ({:?} != {:?})", v, new, as_str);
}
Ok(())
}
fn test(v: &str, size: f64, unit: SizeUnit, as_str: &str) -> bool {
match do_test(v, size, unit, as_str) {
Ok(_) => true,
Err(err) => {
eprintln!("{}", err); // makes debugging easier
false
}
}
}
assert!(test("14", 14.0, SizeUnit::Byte, "14 B"));
assert!(test("14.4", 14.4, SizeUnit::Byte, "14.4 B"));
assert!(test("14.45", 14.45, SizeUnit::Byte, "14.45 B"));
assert!(test("14.456", 14.456, SizeUnit::Byte, "14.456 B"));
assert!(test("14.4567", 14.4567, SizeUnit::Byte, "14.457 B"));
let h: HumanByte = "1.2345678".parse()?;
assert_eq!(&format!("{:.0}", h), "1 B");
assert_eq!(&format!("{:.0}", h.as_f64()), "1"); // use as_f64 to get raw bytes without unit
assert_eq!(&format!("{:.1}", h), "1.2 B");
assert_eq!(&format!("{:.2}", h), "1.23 B");
assert_eq!(&format!("{:.3}", h), "1.235 B");
assert_eq!(&format!("{:.4}", h), "1.2346 B");
assert_eq!(&format!("{:.5}", h), "1.23457 B");
assert_eq!(&format!("{:.6}", h), "1.234568 B");
assert_eq!(&format!("{:.7}", h), "1.2345678 B");
assert_eq!(&format!("{:.8}", h), "1.2345678 B");
assert!(test(
"987654321",
987654321.0,
SizeUnit::Byte,
"987654321 B"
));
assert!(test("1300b", 1300.0, SizeUnit::Byte, "1300 B"));
assert!(test("1300B", 1300.0, SizeUnit::Byte, "1300 B"));
assert!(test("1300 B", 1300.0, SizeUnit::Byte, "1300 B"));
assert!(test("1300 b", 1300.0, SizeUnit::Byte, "1300 B"));
assert!(test("1.5KB", 1.5, SizeUnit::KByte, "1.5 KB"));
assert!(test("1.5kb", 1.5, SizeUnit::KByte, "1.5 KB"));
assert!(test("1.654321MB", 1.654_321, SizeUnit::MByte, "1.654 MB"));
assert!(test("2.0GB", 2.0, SizeUnit::GByte, "2 GB"));
assert!(test("1.4TB", 1.4, SizeUnit::TByte, "1.4 TB"));
assert!(test("1.4tb", 1.4, SizeUnit::TByte, "1.4 TB"));
assert!(test("2KiB", 2.0, SizeUnit::Kibi, "2 KiB"));
assert!(test("2Ki", 2.0, SizeUnit::Kibi, "2 KiB"));
assert!(test("2kib", 2.0, SizeUnit::Kibi, "2 KiB"));
assert!(test("2.3454MiB", 2.3454, SizeUnit::Mebi, "2.345 MiB"));
assert!(test("2.3456MiB", 2.3456, SizeUnit::Mebi, "2.346 MiB"));
assert!(test("4gib", 4.0, SizeUnit::Gibi, "4 GiB"));
Ok(())
}
#[test]
fn test_human_byte_auto_unit_decimal() {
fn convert(b: u64) -> String {
HumanByte::new_decimal(b as f64).to_string()
}
assert_eq!(convert(987), "987 B");
assert_eq!(convert(1022), "1.022 KB");
assert_eq!(convert(9_000), "9 KB");
assert_eq!(convert(1_000), "1 KB");
assert_eq!(convert(1_000_000), "1 MB");
assert_eq!(convert(1_000_000_000), "1 GB");
assert_eq!(convert(1_000_000_000_000), "1 TB");
assert_eq!(convert(1_000_000_000_000_000), "1 PB");
assert_eq!(convert((1 << 30) + 103 * (1 << 20)), "1.182 GB");
assert_eq!(convert((1 << 30) + 128 * (1 << 20)), "1.208 GB");
assert_eq!(convert((2 << 50) + 500 * (1 << 40)), "2.802 PB");
}
#[test]
fn test_human_byte_auto_unit_binary() {
fn convert(b: u64) -> String {
HumanByte::from(b).to_string()
}
assert_eq!(convert(0), "0 B");
assert_eq!(convert(987), "987 B");
assert_eq!(convert(1022), "1022 B");
assert_eq!(convert(9_000), "8.789 KiB");
assert_eq!(convert(10_000_000), "9.537 MiB");
assert_eq!(convert(10_000_000_000), "9.313 GiB");
assert_eq!(convert(10_000_000_000_000), "9.095 TiB");
assert_eq!(convert(1 << 10), "1 KiB");
assert_eq!(convert((1 << 10) * 10), "10 KiB");
assert_eq!(convert(1 << 20), "1 MiB");
assert_eq!(convert(1 << 30), "1 GiB");
assert_eq!(convert(1 << 40), "1 TiB");
assert_eq!(convert(1 << 50), "1 PiB");
assert_eq!(convert((1 << 30) + 103 * (1 << 20)), "1.101 GiB");
assert_eq!(convert((1 << 30) + 128 * (1 << 20)), "1.125 GiB");
assert_eq!(convert((1 << 40) + 128 * (1 << 30)), "1.125 TiB");
assert_eq!(convert((2 << 50) + 512 * (1 << 40)), "2.5 PiB");
}

View File

@ -1,20 +1,24 @@
use anyhow::format_err;
use std::str::FromStr;
use regex::Regex;
use serde::{Deserialize, Serialize};
use proxmox::const_regex;
use proxmox::api::{api, schema::*};
use proxmox_schema::*;
use crate::{
Userid, Authid, REMOTE_ID_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
SINGLE_LINE_COMMENT_SCHEMA, PROXMOX_SAFE_ID_FORMAT, DATASTORE_SCHEMA,
Authid, BackupNamespace, BackupType, RateLimitConfig, Userid, BACKUP_GROUP_SCHEMA,
BACKUP_NAMESPACE_SCHEMA, DATASTORE_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
NS_MAX_DEPTH_REDUCED_SCHEMA, PROXMOX_SAFE_ID_FORMAT, REMOTE_ID_SCHEMA,
SINGLE_LINE_COMMENT_SCHEMA,
};
const_regex!{
const_regex! {
/// Regex for verification jobs 'DATASTORE:ACTUAL_JOB_ID'
pub VERIFICATION_JOB_WORKER_ID_REGEX = concat!(r"^(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):");
/// Regex for sync jobs 'REMOTE:REMOTE_DATASTORE:LOCAL_DATASTORE:ACTUAL_JOB_ID'
pub SYNC_JOB_WORKER_ID_REGEX = concat!(r"^(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):");
/// Regex for sync jobs 'REMOTE:REMOTE_DATASTORE:LOCAL_DATASTORE:(?:LOCAL_NS_ANCHOR:)ACTUAL_JOB_ID'
pub SYNC_JOB_WORKER_ID_REGEX = concat!(r"^(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):(", PROXMOX_SAFE_ID_REGEX_STR!(), r"):(", PROXMOX_SAFE_ID_REGEX_STR!(), r")(?::(", BACKUP_NS_RE!(), r"))?:");
}
pub const JOB_ID_SCHEMA: Schema = StringSchema::new("Job ID.")
@ -23,34 +27,41 @@ pub const JOB_ID_SCHEMA: Schema = StringSchema::new("Job ID.")
.max_length(32)
.schema();
pub const SYNC_SCHEDULE_SCHEMA: Schema = StringSchema::new(
"Run sync job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(proxmox_systemd::time::verify_calendar_event))
pub const SYNC_SCHEDULE_SCHEMA: Schema = StringSchema::new("Run sync job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(
proxmox_time::verify_calendar_event,
))
.type_text("<calendar-event>")
.schema();
pub const GC_SCHEDULE_SCHEMA: Schema = StringSchema::new(
"Run garbage collection job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(proxmox_systemd::time::verify_calendar_event))
pub const GC_SCHEDULE_SCHEMA: Schema =
StringSchema::new("Run garbage collection job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(
proxmox_time::verify_calendar_event,
))
.type_text("<calendar-event>")
.schema();
pub const PRUNE_SCHEDULE_SCHEMA: Schema = StringSchema::new(
"Run prune job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(proxmox_systemd::time::verify_calendar_event))
pub const PRUNE_SCHEDULE_SCHEMA: Schema = StringSchema::new("Run prune job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(
proxmox_time::verify_calendar_event,
))
.type_text("<calendar-event>")
.schema();
pub const VERIFICATION_SCHEDULE_SCHEMA: Schema = StringSchema::new(
"Run verify job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(proxmox_systemd::time::verify_calendar_event))
pub const VERIFICATION_SCHEDULE_SCHEMA: Schema =
StringSchema::new("Run verify job at specified schedule.")
.format(&ApiStringFormat::VerifyFn(
proxmox_time::verify_calendar_event,
))
.type_text("<calendar-event>")
.schema();
pub const REMOVE_VANISHED_BACKUPS_SCHEMA: Schema = BooleanSchema::new(
"Delete vanished backups. This remove the local copy if the remote backup was deleted.")
.default(true)
.schema();
"Delete vanished backups. This remove the local copy if the remote backup was deleted.",
)
.default(false)
.schema();
#[api(
properties: {
@ -76,17 +87,17 @@ pub const REMOVE_VANISHED_BACKUPS_SCHEMA: Schema = BooleanSchema::new(
},
}
)]
#[derive(Serialize,Deserialize,Default)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize, Default)]
#[serde(rename_all = "kebab-case")]
/// Job Scheduling Status
pub struct JobScheduleStatus {
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_run: Option<i64>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub last_run_state: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub last_run_upid: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub last_run_endtime: Option<i64>,
}
@ -130,19 +141,22 @@ pub struct DatastoreNotify {
pub sync: Option<Notify>,
}
pub const DATASTORE_NOTIFY_STRING_SCHEMA: Schema = StringSchema::new(
"Datastore notification setting")
.format(&ApiStringFormat::PropertyString(&DatastoreNotify::API_SCHEMA))
pub const DATASTORE_NOTIFY_STRING_SCHEMA: Schema =
StringSchema::new("Datastore notification setting")
.format(&ApiStringFormat::PropertyString(
&DatastoreNotify::API_SCHEMA,
))
.schema();
pub const IGNORE_VERIFIED_BACKUPS_SCHEMA: Schema = BooleanSchema::new(
"Do not verify backups that are already verified if their verification is not outdated.")
.default(true)
.schema();
"Do not verify backups that are already verified if their verification is not outdated.",
)
.default(true)
.schema();
pub const VERIFICATION_OUTDATED_AFTER_SCHEMA: Schema = IntegerSchema::new(
"Days after that a verification becomes outdated")
.minimum(1)
pub const VERIFICATION_OUTDATED_AFTER_SCHEMA: Schema =
IntegerSchema::new("Days after that a verification becomes outdated. (0 is deprecated)'")
.minimum(0)
.schema();
#[api(
@ -169,29 +183,53 @@ pub const VERIFICATION_OUTDATED_AFTER_SCHEMA: Schema = IntegerSchema::new(
optional: true,
schema: VERIFICATION_SCHEDULE_SCHEMA,
},
ns: {
optional: true,
schema: BACKUP_NAMESPACE_SCHEMA,
},
"max-depth": {
optional: true,
schema: crate::NS_MAX_DEPTH_SCHEMA,
},
}
)]
#[derive(Serialize,Deserialize,Updater)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize, Updater)]
#[serde(rename_all = "kebab-case")]
/// Verification Job
pub struct VerificationJobConfig {
/// unique ID to address this job
#[updater(skip)]
pub id: String,
/// the datastore ID this verificaiton job affects
/// the datastore ID this verification job affects
pub store: String,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
/// if not set to false, check the age of the last snapshot verification to filter
/// out recent ones, depending on 'outdated_after' configuration.
pub ignore_verified: Option<bool>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
/// Reverify snapshots after X days, never if 0. Ignored if 'ignore_verified' is false.
pub outdated_after: Option<i64>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
/// when to schedule this job in calendar event notation
pub schedule: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
/// on which backup namespace to run the verification recursively
pub ns: Option<BackupNamespace>,
#[serde(skip_serializing_if = "Option::is_none", default)]
/// how deep the verify should go from the `ns` level downwards. Passing 0 verifies only the
/// snapshots on the same level as the passed `ns`, or the datastore root if none.
pub max_depth: Option<usize>,
}
impl VerificationJobConfig {
pub fn acl_path(&self) -> Vec<&str> {
match self.ns.as_ref() {
Some(ns) => ns.acl_path(&self.store),
None => vec!["datastore", &self.store],
}
}
}
#[api(
@ -204,8 +242,8 @@ pub struct VerificationJobConfig {
},
},
)]
#[derive(Serialize,Deserialize)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Status of Verification Job
pub struct VerificationJobStatus {
#[serde(flatten)]
@ -244,24 +282,42 @@ pub struct VerificationJobStatus {
optional: true,
type: Userid,
},
"group-filter": {
schema: GROUP_FILTER_LIST_SCHEMA,
optional: true,
},
ns: {
type: BackupNamespace,
optional: true,
},
"max-depth": {
schema: crate::NS_MAX_DEPTH_SCHEMA,
optional: true,
},
}
)]
#[derive(Serialize,Deserialize,Clone,Updater)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize, Clone, Updater)]
#[serde(rename_all = "kebab-case")]
/// Tape Backup Job Setup
pub struct TapeBackupJobSetup {
pub store: String,
pub pool: String,
pub drive: String,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub eject_media: Option<bool>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub export_media_set: Option<bool>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub latest_only: Option<bool>,
/// Send job email notification to this user
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub notify_user: Option<Userid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group_filter: Option<Vec<GroupFilter>>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub ns: Option<BackupNamespace>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub max_depth: Option<usize>,
}
#[api(
@ -282,17 +338,17 @@ pub struct TapeBackupJobSetup {
},
}
)]
#[derive(Serialize,Deserialize,Clone,Updater)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize, Clone, Updater)]
#[serde(rename_all = "kebab-case")]
/// Tape Backup Job
pub struct TapeBackupJobConfig {
#[updater(skip)]
pub id: String,
#[serde(flatten)]
pub setup: TapeBackupJobSetup,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule: Option<String>,
}
@ -306,8 +362,8 @@ pub struct TapeBackupJobConfig {
},
},
)]
#[derive(Serialize,Deserialize)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Status of Tape Backup Job
pub struct TapeBackupJobStatus {
#[serde(flatten)]
@ -315,10 +371,62 @@ pub struct TapeBackupJobStatus {
#[serde(flatten)]
pub status: JobScheduleStatus,
/// Next tape used (best guess)
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub next_media_label: Option<String>,
}
#[derive(Clone, Debug)]
/// Filter for matching `BackupGroup`s, for use with `BackupGroup::filter`.
pub enum GroupFilter {
/// BackupGroup type - either `vm`, `ct`, or `host`.
BackupType(BackupType),
/// Full identifier of BackupGroup, including type
Group(String),
/// A regular expression matched against the full identifier of the BackupGroup
Regex(Regex),
}
impl std::str::FromStr for GroupFilter {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.split_once(':') {
Some(("group", value)) => BACKUP_GROUP_SCHEMA.parse_simple_value(value).map(|_| GroupFilter::Group(value.to_string())),
Some(("type", value)) => Ok(GroupFilter::BackupType(value.parse()?)),
Some(("regex", value)) => Ok(GroupFilter::Regex(Regex::new(value)?)),
Some((ty, _value)) => Err(format_err!("expected 'group', 'type' or 'regex' prefix, got '{}'", ty)),
None => Err(format_err!("input doesn't match expected format '<group:GROUP||type:<vm|ct|host>|regex:REGEX>'")),
}.map_err(|err| format_err!("'{}' - {}", s, err))
}
}
// used for serializing below, caution!
impl std::fmt::Display for GroupFilter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
GroupFilter::BackupType(backup_type) => write!(f, "type:{}", backup_type),
GroupFilter::Group(backup_group) => write!(f, "group:{}", backup_group),
GroupFilter::Regex(regex) => write!(f, "regex:{}", regex.as_str()),
}
}
}
proxmox_serde::forward_deserialize_to_from_str!(GroupFilter);
proxmox_serde::forward_serialize_to_display!(GroupFilter);
fn verify_group_filter(input: &str) -> Result<(), anyhow::Error> {
GroupFilter::from_str(input).map(|_| ())
}
pub const GROUP_FILTER_SCHEMA: Schema = StringSchema::new(
"Group filter based on group identifier ('group:GROUP'), group type ('type:<vm|ct|host>'), or regex ('regex:RE').")
.format(&ApiStringFormat::VerifyFn(verify_group_filter))
.type_text("<type:<vm|ct|host>|group:GROUP|regex:RE>")
.schema();
pub const GROUP_FILTER_LIST_SCHEMA: Schema =
ArraySchema::new("List of group filters.", &GROUP_FILTER_SCHEMA).schema();
#[api(
properties: {
id: {
@ -327,6 +435,10 @@ pub struct TapeBackupJobStatus {
store: {
schema: DATASTORE_SCHEMA,
},
ns: {
type: BackupNamespace,
optional: true,
},
"owner": {
type: Authid,
optional: true,
@ -337,37 +449,71 @@ pub struct TapeBackupJobStatus {
"remote-store": {
schema: DATASTORE_SCHEMA,
},
"remote-ns": {
type: BackupNamespace,
optional: true,
},
"remove-vanished": {
schema: REMOVE_VANISHED_BACKUPS_SCHEMA,
optional: true,
},
"max-depth": {
schema: NS_MAX_DEPTH_REDUCED_SCHEMA,
optional: true,
},
comment: {
optional: true,
schema: SINGLE_LINE_COMMENT_SCHEMA,
},
limit: {
type: RateLimitConfig,
},
schedule: {
optional: true,
schema: SYNC_SCHEDULE_SCHEMA,
},
"group-filter": {
schema: GROUP_FILTER_LIST_SCHEMA,
optional: true,
},
}
)]
#[derive(Serialize,Deserialize,Clone,Updater)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize, Clone, Updater)]
#[serde(rename_all = "kebab-case")]
/// Sync Job
pub struct SyncJobConfig {
#[updater(skip)]
pub id: String,
pub store: String,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub ns: Option<BackupNamespace>,
#[serde(skip_serializing_if = "Option::is_none")]
pub owner: Option<Authid>,
pub remote: String,
pub remote_store: String,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub remote_ns: Option<BackupNamespace>,
#[serde(skip_serializing_if = "Option::is_none")]
pub remove_vanished: Option<bool>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub max_depth: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(skip_serializing_if="Option::is_none")]
#[serde(skip_serializing_if = "Option::is_none")]
pub schedule: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub group_filter: Option<Vec<GroupFilter>>,
#[serde(flatten)]
pub limit: RateLimitConfig,
}
impl SyncJobConfig {
pub fn acl_path(&self) -> Vec<&str> {
match self.ns.as_ref() {
Some(ns) => ns.acl_path(&self.store),
None => vec!["datastore", &self.store],
}
}
}
#[api(
@ -380,9 +526,8 @@ pub struct SyncJobConfig {
},
},
)]
#[derive(Serialize,Deserialize)]
#[serde(rename_all="kebab-case")]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Status of Sync Job
pub struct SyncJobStatus {
#[serde(flatten)]
@ -390,3 +535,186 @@ pub struct SyncJobStatus {
#[serde(flatten)]
pub status: JobScheduleStatus,
}
/// These are used separately without `ns`/`max-depth` sometimes in the API, specifically in the API
/// call to prune a specific group, where `max-depth` makes no sense.
#[api(
properties: {
"keep-last": {
schema: crate::PRUNE_SCHEMA_KEEP_LAST,
optional: true,
},
"keep-hourly": {
schema: crate::PRUNE_SCHEMA_KEEP_HOURLY,
optional: true,
},
"keep-daily": {
schema: crate::PRUNE_SCHEMA_KEEP_DAILY,
optional: true,
},
"keep-weekly": {
schema: crate::PRUNE_SCHEMA_KEEP_WEEKLY,
optional: true,
},
"keep-monthly": {
schema: crate::PRUNE_SCHEMA_KEEP_MONTHLY,
optional: true,
},
"keep-yearly": {
schema: crate::PRUNE_SCHEMA_KEEP_YEARLY,
optional: true,
},
}
)]
#[derive(Serialize, Deserialize, Default, Updater)]
#[serde(rename_all = "kebab-case")]
/// Common pruning options
pub struct KeepOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_last: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_hourly: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_daily: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_weekly: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_monthly: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keep_yearly: Option<u64>,
}
impl KeepOptions {
pub fn keeps_something(&self) -> bool {
self.keep_last.unwrap_or(0)
+ self.keep_hourly.unwrap_or(0)
+ self.keep_daily.unwrap_or(0)
+ self.keep_weekly.unwrap_or(0)
+ self.keep_monthly.unwrap_or(0)
+ self.keep_yearly.unwrap_or(0)
> 0
}
}
#[api(
properties: {
keep: {
type: KeepOptions,
},
ns: {
type: BackupNamespace,
optional: true,
},
"max-depth": {
schema: NS_MAX_DEPTH_REDUCED_SCHEMA,
optional: true,
},
}
)]
#[derive(Serialize, Deserialize, Default, Updater)]
#[serde(rename_all = "kebab-case")]
/// Common pruning options
pub struct PruneJobOptions {
#[serde(flatten)]
pub keep: KeepOptions,
/// The (optional) recursion depth
#[serde(skip_serializing_if = "Option::is_none")]
pub max_depth: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ns: Option<BackupNamespace>,
}
impl PruneJobOptions {
pub fn keeps_something(&self) -> bool {
self.keep.keeps_something()
}
pub fn acl_path<'a>(&'a self, store: &'a str) -> Vec<&'a str> {
match &self.ns {
Some(ns) => ns.acl_path(store),
None => vec!["datastore", store],
}
}
}
#[api(
properties: {
disable: {
type: Boolean,
optional: true,
default: false,
},
id: {
schema: JOB_ID_SCHEMA,
},
store: {
schema: DATASTORE_SCHEMA,
},
schedule: {
schema: PRUNE_SCHEDULE_SCHEMA,
optional: true,
},
comment: {
optional: true,
schema: SINGLE_LINE_COMMENT_SCHEMA,
},
options: {
type: PruneJobOptions,
},
},
)]
#[derive(Deserialize, Serialize, Updater)]
#[serde(rename_all = "kebab-case")]
/// Prune configuration.
pub struct PruneJobConfig {
/// unique ID to address this job
#[updater(skip)]
pub id: String,
pub store: String,
/// Disable this job.
#[serde(default, skip_serializing_if = "is_false")]
#[updater(serde(skip_serializing_if = "Option::is_none"))]
pub disable: bool,
pub schedule: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(flatten)]
pub options: PruneJobOptions,
}
impl PruneJobConfig {
pub fn acl_path(&self) -> Vec<&str> {
self.options.acl_path(&self.store)
}
}
fn is_false(b: &bool) -> bool {
!b
}
#[api(
properties: {
config: {
type: PruneJobConfig,
},
status: {
type: JobScheduleStatus,
},
},
)]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Status of prune job
pub struct PruneJobStatus {
#[serde(flatten)]
pub config: PruneJobConfig,
#[serde(flatten)]
pub status: JobScheduleStatus,
}

Some files were not shown because too many files have changed in this diff Show More