Commit Graph

269 Commits

Author SHA1 Message Date
Christian Ebner
83e7b9de88 client: http: Use custom resolver for statically linked binary
The dependency on the `getaddrinfo` based `GaiResolver` used by
default for the `HttpClient` is not suitable for the statically
linked binary of the `proxmox-backup-client`, because of the
dependency on glibc NSS libraries, as described in glibc's FAQs [0].

As a workaround, conditionally compile the binary using the `hickory-dns`
resolver.

[0] https://sourceware.org/glibc/wiki/FAQ#Even_statically_linked_programs_need_some_shared_libraries_which_is_not_acceptable_for_me.__What_can_I_do.3F

Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
FG: bump proxmox-http dependency
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2025-04-09 15:23:14 +02:00
Maximiliano Sandoval
d4a2730b1b pbs-client: allow reading fingerprint from system credential
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-04-03 17:53:25 +02:00
Maximiliano Sandoval
b0cd9e84f5 pbs-client: allow reading default repository from system credential
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-04-03 17:53:25 +02:00
Maximiliano Sandoval
912c8c4027 pbs-client: make get_encryption_password return a String
As per the note in the documentation [1], passwords are valid UTF-8.
This allows us to se the shared helper.

[1] https://pbs.proxmox.com/docs/backup-client.html#environment-variables

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-04-03 17:53:25 +02:00
Maximiliano Sandoval
263651912e pbs-client: use helper for getting UTF-8 password
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-04-03 17:53:25 +02:00
Maximiliano Sandoval
4b26fb2bd7 pbs-client: add helper for getting UTF-8 secrets
We are going to add more credentials so it makes sense to have a common
helper to get the secrets.

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-04-03 17:53:25 +02:00
Maximiliano Sandoval
70e1ad0efb pbs-client: use a const for the PBS_REPOSITORY env variable
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-04-03 17:53:25 +02:00
Maximiliano Sandoval
27ba2c0318 pbs-client: make get_secret_from_env private
Since we are exposing functions now to get the password and encryption
password this should be private.

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-03-26 12:46:56 +01:00
Maximiliano Sandoval
b510184e72 pbs-client: read credentials from $CREDENTIALS_DIRECTORY
Allows to load credentials passed down by systemd. A possible use-case
is safely storing the server's password in a file encrypted by the
systems TPM, e.g. via

```
systemd-ask-password -n | systemd-creds encrypt --name=proxmox-backup-client.password - my-api-token.cred
```

which then can be used via

```
systemd-run --pipe --wait --property=LoadCredentialEncrypted=proxmox-backup-client.password:my-api-token.cred \
proxmox-backup-client ...
```

or from inside a service.

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-03-26 12:46:51 +01:00
Christian Ebner
24a6d4fd82 client: align description for backup specification to docs
Adapt the description for the backup specification to use
`archive-name` and `type` over `label` and `ext`, to be in line with
the terminology used in the documentation.

Further, explicitley describe the `path` as `source-path` to be less
ambigouos.

In order to avoid formatting issues in the man pages because of line
breaks after a hyphen, show the backup specification description in
multiple lines.

Suggested-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2025-03-20 18:47:44 +01:00
Fabian Grünbichler
6565199af4 hyper: start preparing upgrade to 1.x
by switching on deprecations and using some backported types already
available on 0.14:

- use body::HttpBody::collect() instead of to_bytes() directly on Body
- use server::conn::http2::Builder instead of server::conn::Http with
  http2_only

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2025-03-13 13:23:48 +01:00
Fabian Grünbichler
168ed37026 h2: switch to legacy feature
to avoid upgrading to hyper 1 / http 1 right now. this is a Debian/Proxmox
specific workaround.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2025-03-13 13:23:42 +01:00
Maximiliano Sandoval
22285d0d01 add too_many_arguments clippy exception
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-03-06 14:57:23 +01:00
Christian Ebner
abad8e25c4 fix #6185: client/docs: explicitly mention archive name restrictions
Mention in the docs and the api parameter description the limitations
for archive name labels. They must contain alphanumerics, hyphens and
underscores only to match the regex pattern.

By setting this in the api parameter description, it will be included
in the man page for proxmox-backup-client.

Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=6185
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2025-02-21 16:00:17 +01:00
Christian Ebner
64cfb13193 client: style cleanup: inline variable names in format string
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2025-02-20 16:13:54 +01:00
Christian Ebner
c9cd520a1a client: pxar: fix race in pxar backup stream
Fixes a race condition where the backup upload stream can miss an
error returned by pxar::create_archive, because the error state is
only set after the backup stream was already polled.

On instantiation, `PxarBackupStream` spawns a future handling the
pxar archive creation, which sends the encoded pxar archive stream
(or streams in case of split archives) through a channel, received
by the pxar backup stream on polling.

In case this channel is closed as signaled by returning an error, the
poll logic will propagate an eventual error occurred during pxar
creation by taking it from the `PxarBackupStream`.

As this error might not have been set just yet, this can lead to
incorrectly terminating a backup snapshot with success, eventhough an
error occurred.

To fix this, introduce a dedicated notifier for each stream instance
and wait for the archiver to signal it has finished via this
notification channel. In addition, extend the `PxarBackupStream` by a
`finished` flag to allow early return on subsequent polls, which
would otherwise block, waiting for a new notification.

In case of premature termination of the pxar backup stream, no
additional measures have to been taken, as the abort handle already
terminates the archive creation.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2025-02-11 11:18:29 +01:00
Maximiliano Sandoval
d4468ba6f8 pxar: extract: Follow overwrite_flags when opening file
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-01-27 13:22:34 +01:00
Christian Ebner
d93d782d37 cargo: drop direct http crate dependency, tree-wide namespace fix
Instead of using and depending on the `http` crate directly, use and
depend on the re-exported `hyper::http`. Adapt namespace prefixes
accordingly.

This makes sure the `hyper::http` types are version compatible and
allows to possibly depend on incompatible versions of `http` in the
workspace in the future.

No functional changes intended.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2025-01-24 09:43:35 +01:00
Maximiliano Sandoval
fd6cdeebea elide lifetimes when possible
Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2025-01-14 08:56:42 +01:00
Christian Ebner
c57ac02879 pxar: client: fix missing file size check for metadata comparison
Change detection mode set to metadata compares regular file entries
metadata to the reference metadata archive of the previous run. The
`pxar::format::Stat` as stored in `pxar::Metadata` however does not
include the actual file size, it only partially stores information
gathered from stating the file.

This means however that the actual file size is never compared and
therefore, that if the file size did change, but the other metadata
information did not (including the mtime which might have been
restored), that file will be incorrectly reused.
A subsequent restore will however fail, because the expected file size
as encoded in the metadata archive does not match the file size as
stored in the payload archive.

Fix this by adding the missing file size check, comparing the size
for the given file against the one stored in the metadata archive.

Link to issue reported in community forum:
https://forum.proxmox.com/threads/158722/

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-12-09 09:43:49 +01:00
Gabriel Goller
c69d18626a pbs-client: remove log dependency and migrate to tracing
Remove the `log` dependency in pbs-client and change all the invocations
to tracing logs.
No functional change intended.

Signed-off-by: Gabriel Goller <g.goller@proxmox.com>
2024-12-05 08:31:52 +01:00
Maximiliano Sandoval
f55a08891e pxar: extract: docs: remove redundant explicit link
Also fix `Entries` link.

Fixes the cargo doc lint:

```
warning: redundant explicit link target
   --> pbs-client/src/pxar/extract.rs:212:27
    |
212 |     ///   * The [`Entry`][E]'s filename is invalid (contains nul bytes or a slash)
    |                  -------  ^ explicit target is redundant
    |                  |
    |                  because label contains path that resolves to same destination
    |
note: referenced explicit link target defined here
   --> pbs-client/src/pxar/extract.rs:221:14
    |
221 |     /// [E]: pxar::Entry
    |              ^^^^^^^^^^^
    = note: when a link's destination is not specified,
            the label is used to resolve intra-doc links
    = note: `#[warn(rustdoc::redundant_explicit_links)]` on by default
help: remove explicit link target
    |
212 |     ///   * The [`Entry`]'s filename is invalid (contains nul bytes or a slash)
    |                 ~~~~~~~~~

warning: redundant explicit link target
   --> pbs-client/src/pxar/extract.rs:215:37
    |
215 |     /// fetching the next [`Entry`][E]), the error may be handled by the
    |                            -------  ^ explicit target is redundant
    |                            |
    |                            because label contains path that resolves to same destination
    |
note: referenced explicit link target defined here
   --> pbs-client/src/pxar/extract.rs:221:14
    |
221 |     /// [E]: pxar::Entry
    |              ^^^^^^^^^^^
    = note: when a link's destination is not specified,
            the label is used to resolve intra-doc links
help: remove explicit link target
    |
215 |     /// fetching the next [`Entry`]), the error may be handled by the
```

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-12-04 14:40:42 +01:00
Dominik Csapak
8eaeedf31e tree-wide: add missing O_CLOEXEC flags to openat calls
Since we don't want to have lingering file descriptors on any fork +
exec, like the reload code from the proxmox-daemon crate we're using
for the rest-server(s) does, as that can have serious side effects and
even cause hangs.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
 [ TL: Reword commit message ]}
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-12-03 16:48:23 +01:00
Maximiliano Sandoval
47a29b1896 docs: remove empty lines in doc strings
Fixes the clippy lint:

```
warning: empty line after doc comment
   --> src/tape/pool_writer/mod.rs:441:5
    |
441 | /     /// updated.
442 | |
    | |_
...
448 | /     pub fn append_snapshot_archive(
449 | |         &mut self,
450 | |         snapshot_reader: &SnapshotReader,
451 | |     ) -> Result<(bool, usize), Error> {
    | |_____________________________________- the comment documents this method
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments
    = help: if the empty line is unintentional remove it
help: if the documentation should include the empty line include it in the comment
    |
442 |     ///
    |
```

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-12-03 11:24:37 +01:00
Fabian Grünbichler
a50e0014df clippy: elide more lifetimes
these were detected with 1.83.0

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-12-02 11:34:05 +01:00
Maximiliano Sandoval
23e91fdd98 docs: use sublist indentation
Fixes the doc_lazy_continuation clippy lint, e.g.:

```
warning: doc list item without indentation
   --> src/server/pull.rs:764:5
    |
764 | /// -- attempt to pull each NS in turn
    |     ^
    |
    = help: if this is supposed to be its own paragraph, add a blank line
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation
help: indent this line
    |
764 | ///   -- attempt to pull each NS in turn
    |     ++
```

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-12-02 11:15:18 +01:00
Maximiliano Sandoval
f36e8fea91 remove needless borrows
Fixes the needless_borrow lint.

Signed-off-by: Maximiliano Sandoval <m.sandoval@proxmox.com>
2024-12-02 11:15:18 +01:00
Thomas Lamprecht
269b7bffc7 tree-wide: fix various typos
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2024-11-27 20:52:48 +01:00
Christian Ebner
63da9f8397 client: backup writer: fix regression in progress output
Fixes a regression introduced when switching from the plain string
to be used for archive names to the BackupArchiveName api type in
commit addfae26 ("api types: introduce `BackupArchiveName` type").

The archive name now always is stored including the server archive
name extension. Adapt the check for which archive types to display
the progress log output to reflect this change.

Fixes: addfae26 ("api types: introduce `BackupArchiveName` type")
Reported-by: Max Carrara <m.carrara@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-26 17:16:14 +01:00
Christian Ebner
70545af183 client: catalog shell: use dedicated api type for patterns
Use the common api type with schema based input validation for all
match pattern parameters exposed via the api macro.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-25 11:57:07 +01:00
Christian Ebner
6771869cc1 client/server: use dedicated api type for all archive names
Instead of using the plain String or slices of it for archive names,
use the dedicated api type and its methods to parse and check for
archive type based on archive filename extension.

Thereby, keeping the checks and mappings in the api type and
resticting function parameters by the narrower wrapper type to reduce
potential misuse.

Further, instead of declaring and using the archive name constants
throughout the codebase, use the `BackupArchiveName` helpers to
generate the archive names for manifest, client logs and encryption
keys.

This allows for easy archive name comparisons using the same
`BackupArchiveName` type, at the cost of some extra allocations and
avoids the currently present double constant declaration of
`CATALOG_NAME`.

A positive ergonomic side effect of this is that commands now also
accept the archive type extension optionally, when passing the archive
name.

E.g.
```
proxmox-backup-client restore <snapshot> <name>.pxar.didx <target>
```
is equal to
```
proxmox-backup-client restore <snapshot> <name>.pxar <target>
```

The previously default mapping of any archive name extension to a blob
has been dropped in favor of consistent mapping by the api type
helpers.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>

FG: use LazyLock for constant archive names
FG: add missing import

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-11-22 13:47:05 +01:00
Christian Ebner
e932ec101e datastore: move ArchiveType to api types
Moving the `ArchiveType` to avoid crate dependencies on
`pbs-datastore`.

In preparation for introducing a dedicated `BackupArchiveName` api
type, allowing to set the corresponding archive type variant when
parsing the archive name based on it's filename.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-22 11:45:43 +01:00
Fabian Grünbichler
cbf7bbefb7 pxar: extract: make invalid ACLs non-fatal
these can occur in practice, and neither setting nor getting them throws an
error. if "invalid" ACLs are non-restorable, this means that creating a pxar
archive with such an ACL is possible, but restoring it isn't.

reported in our community forum:
https://forum.proxmox.com/threads/155477

Tested-by: Gabriel Goller <g.goller@proxmox.com>
Acked-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-11-22 10:38:49 +01:00
Fabian Grünbichler
4e37c678dc pxar: add file name to path_info when applying metadata
else, error messages using this path_info refer to the parent directory instead
of the actual file entry causing the problem. since this is just for
informational purposes, lossy conversion is acceptable.

Acked-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-11-22 10:38:42 +01:00
Christian Ebner
e3f2756cbb fix #5853: client: pxar: exclude stale files on metadata/link read
Skip and warn the user for files which returned a stale file handle
error while reading the metadata associated to that file, or the
target in case of a symbolic link.

Instead of returning with a hard error, report the stale file handle
and skip over encoding this file entry in the pxar archive.

Link to issue in bugtracker:
https://bugzilla.proxmox.com/show_bug.cgi?id=5853

Link to thread in community forum:
https://forum.proxmox.com/threads/156822/

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 13:21:02 +01:00
Christian Ebner
efb49d8abe client: pxar: warn user and ignore stale file handles on file open
Do not fail hard if a file open fails because of a stale file handle.
Warn the user and ignore the file, just like the client already does
in case of missing privileges to access the file.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 13:21:02 +01:00
Christian Ebner
102ab18146 client: pxar: skip directory entries on stale file handle
Skip over the entries when a stale file handle is encountered during
generation of the entry list of a directory entry.

This will lead to the directory not being backed up if the directory
itself was invalidated, as then reading all child entries will fail
also, or the directory is backed up without entries which have been
invalidated.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 13:21:02 +01:00
Christian Ebner
1b9df4ba4f client: pxar: skip directories on stale file handle
Skip over the whole directory in case the file handle was invalidated
and therefore the filesystem type check returns with ESTALE.

Encode the directory start entry in the archive and the catalog only
after the filesystem type check, so the directory can be fully skipped.
At this point it is still possible to ignore the invalidated
directory. If the directory is invalidated afterwards, it will be
backed up only partially.

Introduce a helper method to report entries for which a stale file
handle was encountered, providing an optional path for cases where
the `Archiver`s state does not store the correct path.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 13:21:02 +01:00
Christian Ebner
1be78aad72 client: pxar: refactor report vanished/changed helpers
Switch from mutable reference to shared reference on `self` and drop
unused return value.

These helpers only write log messages, there is currently no need for
a mutable reference to `self`, nor to return a `Result`.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 13:21:02 +01:00
Christian Ebner
a5e3032d36 client: backup writer: allow push uploading index and chunks
Add a method `upload_index_chunk_info` to be used for uploading an
existing index and the corresponding chunk stream.
Instead of taking an input stream of raw bytes as the
`upload_stream`, this takes a stream of `MergedChunkInfo` object
provided by the local chunk reader of the sync jobs source.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 10:14:53 +01:00
Christian Ebner
008b38bfc7 client: backup writer: factor out merged chunk stream upload
In preparation for implementing push support for sync jobs.

Factor out the upload stream for merged chunks, which can be reused
to upload the local chunks to a remote target datastore during a
snapshot sync operation in push direction.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 10:14:53 +01:00
Christian Ebner
9fbe870d1c client: backup writer: refactor backup and upload stats counters
In preparation for push support in sync jobs.

Extend and move `BackupStats` into `backup_stats` submodule and add
method to create them from `UploadStats`.

Further, introduce `UploadCounters` struct to hold the Arc clones of
the chunk upload statistics counters, simplifying the house keeping.

By bundling the counters into the struct, they can be passed as
single function parameter when factoring out the common stream future
in the subsequent implementation of the chunk upload for sync jobs
in push direction.

Co-developed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-21 10:14:53 +01:00
Christian Ebner
76504bfcac client: pxar: add debug output for exclude pattern matches
Log the path of directory entries matched by an exclude pattern in
order to more conveniently debug possible issues.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-12 21:23:42 +01:00
Christian Ebner
7465ccd097 client: pxar: perform match pattern check only once
While traversing the filesystem tree, `generate_directory_file_list`
generates the list of entries to include for each directory level,
already matching the entry against the given list of match patterns.

Since this already excludes entries which should not be included in
the archive, the same check in the `add_entry` call is redundant,
as it is executed for each entry which is included in the list
generated by `generate_directory_file_list`.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-12 21:23:39 +01:00
Christian Ebner
da82aca849 client: catalog shell: avoid navigating below archive root
Avoid to underflow the catalogs shell position stack by navigating
below the archives root directory into the catalog root. Otherwise
the shell will panic, as the root entry is always expected to be
present.

This threats the archive root directory as being it's own parent
directory, mimicking the behaviour of most common shells.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-11-12 21:08:27 +01:00
Christian Ebner
59243d200e client: catalog shell: drop payload offset in stat output
Drop the payload offset output for the multi line formatting helper,
as the formatting was skewed anyways and the `stat` output is not
intended for debugging.

Commit 51e8fa96 ("client: pxar: include payload offset in entry
listing") introduced the payload offset output for pxar entries
in case of split archives for both, single line and multi line
formatting helpers with debugging prupose.

While the payload offset output is fine for the single line entry
formatting (generates the pxar dump output in debugging mode),
it should not be included in the multi line entry formatting helper,
used to generate the output for the `stat` command of the catalog
shell.

Fixes: 51e8fa96 ("client: pxar: include payload offset in entry listing")

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-10-25 14:22:32 +02:00
Fabian Grünbichler
dd16eabe19 pxar: tools: inline async recursion
this works since rustc 1.77, and makes the code less verbose.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2024-10-23 16:10:41 +02:00
Christian Ebner
5ddd59e167 client: catalog shell: fallback to accessor for navigation
Make the catalog optional and use the pxar accessor for navigation if
the catalog is not provided.
This allows to use the metadata archive for navigraion, as for split
pxar archives no dedicated catalog is encoded.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-10-23 16:10:41 +02:00
Christian Ebner
78e4098eae client: helper to mimic catalog find using metadata archive
Adds helper functions to reimplement the catalog shell functionality
for snapshots being encoded as split pxar archives.

Just as the `CatalogReader`s find method, recursively iterate entries
and call the given callback on all entries matched by the match
patterns, starting from the given parent entry.

The helper has been split into 2 functions for the async recursion to
work.
2024-10-23 16:10:41 +02:00
Christian Ebner
d530ba080d client: add helper to dump catalog from metadata archive
Implements the methods to dump the contents of a metadata pxar
archive using the same output format as used by the catalog dump.

The helper function has been split into 2 for async recursion to
work.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
2024-10-23 16:10:41 +02:00