public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client
@ 2025-04-09 11:05 Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox 1/6] http: client: make https connector generic over resolver Christian Ebner
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

As discussed in issue #4788 [0], statically linking of the
`proxmox-backup-client` still suffers from possible incompatible
dependencies on the NSS module libraries, further described in
[1].

This patch series provides the means to statically compile the client
with a workaround for the NSS lib limitation by relying on
`hickory-dns` [2], as suggested by Thomas.
The hickory-resolver is used for name resolution with the statically
compiled binary instead of the default `getaddrinfo` based
`GaiResolver`.

Since hickory-resolver depends on `ipconfig` for Windows targets when
the `system-config` feature is enabled (required to read nameservers
from `/etc/resolv.conf`), also the dependency on `ipconfig` is
required by cargo. To workaround this, a dummy crate is registered in
the cargo registry.

Changes since version 4:
- Incorporated additions and suggestions regarding debian packaging

Changes since version 3:
- Added default type GaiResolver to HttpsConnector
- Include patch to mention different name resolution behavior in docs

Changes since version 2:
- Use packaged version for hickory-resolver
- Drop unneeded `ipconfig` dependency workaround
- Rebased onto current master

[0] https://bugzilla.proxmox.com/show_bug.cgi?id=4788
[1] 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
[2] https://github.com/hickory-dns/hickory-dns

proxmox:

Christian Ebner (1):
  http: client: make https connector generic over resolver

 proxmox-http/Cargo.toml              |  1 +
 proxmox-http/src/client/connector.rs | 17 ++++++++++++-----
 proxmox-http/src/client/simple.rs    |  3 ++-
 3 files changed, 15 insertions(+), 6 deletions(-)

proxmox-backup:

Christian Ebner (5):
  build: always set --target
  fix: 4788: Makefile: target for statically linked client binary
  buildsys: build and package statically linked client binary
  client: http: Use custom resolver for statically linked binary
  docs: mention different name resolution for statically linked binary

 Cargo.toml                                    |  1 +
 Makefile                                      | 28 +++++--
 debian/control                                |  8 ++
 ...oxmox-backup-client-static.bash-completion |  1 +
 debian/proxmox-backup-client-static.install   |  3 +
 debian/rules                                  |  2 +
 docs/backup-client.rst                        |  5 ++
 pbs-client/Cargo.toml                         |  1 +
 pbs-client/src/http_client.rs                 | 81 ++++++++++++++++++-
 9 files changed, 121 insertions(+), 9 deletions(-)
 create mode 100644 debian/proxmox-backup-client-static.bash-completion
 create mode 100644 debian/proxmox-backup-client-static.install

-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] [PATCH v5 proxmox 1/6] http: client: make https connector generic over resolver
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
@ 2025-04-09 11:05 ` Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 2/6] build: always set --target Christian Ebner
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

Allow to instantiate a `HttpsConnector` not using the default
`getaddrinfo` based `GaiResolver` for domain name resolution, but
rather a custom resolver implementing the required traits.

The usecase for this is to swap out the DNS resolver for the
statically linked proxmox-backup-client binary, where the glibc
dependency is problematic because of possible ABI incompatibility.

However, set the generic type on `HttpsConnector` to default to
`GaiResolver` to limit inconvenience for implementations using it.

Adds tower-service as cargo workspace dependency and build dependency
to debian/control.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
changes since version 4:
- no changes

 proxmox-http/Cargo.toml              |  1 +
 proxmox-http/src/client/connector.rs | 17 ++++++++++++-----
 proxmox-http/src/client/simple.rs    |  3 ++-
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/proxmox-http/Cargo.toml b/proxmox-http/Cargo.toml
index c8c963f7..6bfb1413 100644
--- a/proxmox-http/Cargo.toml
+++ b/proxmox-http/Cargo.toml
@@ -22,6 +22,7 @@ openssl =  { version = "0.10", optional = true }
 serde_json = { workspace = true, optional = true }
 tokio = { workspace = true, features = [], optional = true }
 tokio-openssl = { workspace = true, optional = true }
+tower-service.workspace = true
 ureq = { version = "2.4", features = ["native-certs", "native-tls"], optional = true, default-features = false }
 url = { workspace = true, optional = true }
 
diff --git a/proxmox-http/src/client/connector.rs b/proxmox-http/src/client/connector.rs
index 63b9d10c..2e04680f 100644
--- a/proxmox-http/src/client/connector.rs
+++ b/proxmox-http/src/client/connector.rs
@@ -6,6 +6,7 @@ use std::task::{Context, Poll};
 
 use futures::*;
 use http::Uri;
+use hyper::client::connect::dns::{GaiResolver, Name};
 use hyper::client::HttpConnector;
 use openssl::ssl::SslConnector;
 use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
@@ -23,8 +24,8 @@ use crate::{RateLimitedStream, ShareableRateLimit};
 type SharedRateLimit = Arc<dyn ShareableRateLimit>;
 
 #[derive(Clone)]
-pub struct HttpsConnector {
-    connector: HttpConnector,
+pub struct HttpsConnector<T = GaiResolver> {
+    connector: HttpConnector<T>,
     ssl_connector: Arc<SslConnector>,
     proxy: Option<ProxyConfig>,
     tcp_keepalive: u32,
@@ -32,9 +33,9 @@ pub struct HttpsConnector {
     write_limiter: Option<SharedRateLimit>,
 }
 
-impl HttpsConnector {
+impl<T> HttpsConnector<T> {
     pub fn with_connector(
-        mut connector: HttpConnector,
+        mut connector: HttpConnector<T>,
         ssl_connector: SslConnector,
         tcp_keepalive: u32,
     ) -> Self {
@@ -122,7 +123,13 @@ impl HttpsConnector {
     }
 }
 
-impl hyper::service::Service<Uri> for HttpsConnector {
+impl<T> hyper::service::Service<Uri> for HttpsConnector<T>
+where
+    T: tower_service::Service<Name> + Clone + Send + Sync + 'static,
+    T::Future: Send,
+    T::Error: Into<Box<(dyn std::error::Error + Send + Sync + 'static)>>,
+    T::Response: std::iter::Iterator<Item = std::net::SocketAddr>,
+{
     type Response = MaybeTlsStream<RateLimitedStream<TcpStream>>;
     type Error = Error;
     #[allow(clippy::type_complexity)]
diff --git a/proxmox-http/src/client/simple.rs b/proxmox-http/src/client/simple.rs
index 062889ac..cb8bb777 100644
--- a/proxmox-http/src/client/simple.rs
+++ b/proxmox-http/src/client/simple.rs
@@ -8,6 +8,7 @@ use futures::*;
 #[cfg(all(feature = "client-trait", feature = "proxmox-async"))]
 use http::header::HeaderName;
 use http::{HeaderValue, Request, Response};
+use hyper::client::connect::dns::GaiResolver;
 use hyper::client::Client as HyperClient;
 use hyper::client::HttpConnector;
 use hyper::Body;
@@ -18,7 +19,7 @@ use crate::HttpOptions;
 
 /// Asynchronous HTTP client implementation
 pub struct Client {
-    client: HyperClient<HttpsConnector, Body>,
+    client: HyperClient<HttpsConnector<GaiResolver>, Body>,
     options: HttpOptions,
 }
 
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] [PATCH v5 proxmox-backup 2/6] build: always set --target
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox 1/6] http: client: make https connector generic over resolver Christian Ebner
@ 2025-04-09 11:05 ` Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 3/6] fix: 4788: Makefile: target for statically linked client binary Christian Ebner
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

since it affects whether cargo puts build artifacts directly into
target/debug (or target/release) or into a target-specific
sub-directory.

the package build will always pass `--target $(DEB_HOST_RUST_TYPE)`,
since it invokes the cargo wrapper in /usr/share/cargo/bin/cargo, so
this change unifies the behaviour across plain `make` and `make
deb`.

direct calls to `cargo build/test/..` will still work as before.

Originally-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
Reviewed-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
---
changes since version 4:
- not present in previous version

 Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index dfbaacab4..dc6aa72fc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,10 @@
 include /usr/share/dpkg/default.mk
+include /usr/share/rustc/architecture.mk
 include defines.mk
 
 PACKAGE := proxmox-backup
 ARCH := $(DEB_BUILD_ARCH)
+export DEB_HOST_RUST_TYPE
 
 SUBDIRS := etc www docs templates
 
@@ -37,9 +39,10 @@ SUBCRATES != cargo metadata --no-deps --format-version=1 \
 	| sed -e "s!.*$$PWD/!!g" -e 's/\#.*$$//g' -e 's/)$$//g'
 
 ifeq ($(BUILD_MODE), release)
-CARGO_BUILD_ARGS += --release
+CARGO_BUILD_ARGS += --release --target $(DEB_HOST_RUST_TYPE)
 COMPILEDIR := target/$(DEB_HOST_RUST_TYPE)/release
 else
+CARGO_BUILD_ARGS += --target $(DEB_HOST_RUST_TYPE)
 COMPILEDIR := target/$(DEB_HOST_RUST_TYPE)/debug
 endif
 
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] [PATCH v5 proxmox-backup 3/6] fix: 4788: Makefile: target for statically linked client binary
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox 1/6] http: client: make https connector generic over resolver Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 2/6] build: always set --target Christian Ebner
@ 2025-04-09 11:05 ` Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 4/6] buildsys: build and package " Christian Ebner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

Adds the build target including workarounds to generate a statically
linked version of the proxmox-backup-client binary.

Fixes: https://bugzilla.proxmox.com/show_bug.cgi?id=4788
Suggested-by: Christoph Heiss <c.heiss@proxmox.com>
Originally-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
Tested-by: Lukas Wagner <l.wagner@proxmox.com>
---
changes since version 4:
- no changes

 Makefile | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Makefile b/Makefile
index dc6aa72fc..8d102871d 100644
--- a/Makefile
+++ b/Makefile
@@ -230,3 +230,12 @@ upload: $(SERVER_DEB) $(CLIENT_DEB) $(RESTORE_DEB) $(DOC_DEB)
 	  | ssh -X repoman@repo.proxmox.com upload --product pbs --dist $(UPLOAD_DIST)
 	tar cf - $(CLIENT_DEB) $(CLIENT_DBG_DEB) | ssh -X repoman@repo.proxmox.com upload --product "pve,pmg,pbs-client" --dist $(UPLOAD_DIST)
 	tar cf - $(RESTORE_DEB) $(RESTORE_DBG_DEB) | ssh -X repoman@repo.proxmox.com upload --product "pve" --dist $(UPLOAD_DIST)
+
+.PHONY: proxmox-backup-client-static
+proxmox-backup-client-static:
+	mkdir -p target/release/deps/ && \
+          echo '!<arch>' > target/release/deps/libsystemd.a # workaround for to greedy linkage and proxmox-systemd
+	RUSTFLAGS='-C target-feature=+crt-static -C strip=debuginfo' \
+        $(CARGO) build $(CARGO_BUILD_ARGS) \
+          --package proxmox-backup-client --bin proxmox-backup-client \
+          --target x86_64-unknown-linux-gnu
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] [PATCH v5 proxmox-backup 4/6] buildsys: build and package statically linked client binary
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
                   ` (2 preceding siblings ...)
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 3/6] fix: 4788: Makefile: target for statically linked client binary Christian Ebner
@ 2025-04-09 11:05 ` Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 5/6] client: http: Use custom resolver for statically linked binary Christian Ebner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

Build and package the a statically linked binary version of
proxmox-backup-client to facilitate updates and distribution.
This provides a mechanism to obtain and repackage the client for
external parties and Linux distributions.

The statically linked client is provided as dedicated package,
conflicting with the regular package. Symlinks are created to invoke
the client with the regular command name.

Since the RUSTFLAGS env variables are not preserved when building
with dpkg-buildpackage, invoke via `cargo rustc` instead which allows
to set the recquried arguments.

Credit goes also to Christoph Heiss, as this patch is loosely based
on his pre-existing work for the proxmox-auto-install-assistant [0],
which provided a good template.

Also, place the libsystemd stub into its own subdirectory for cleaner
separation from the compiled artifacts.

[0] https://lore.proxmox.com/pve-devel/20240816161942.2044889-1-c.heiss@proxmox.com/

Suggested-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
changes since version 4:
- squashed in also changes for generation of deb package

 Makefile                                      | 26 ++++++++++++-------
 debian/control                                |  8 ++++++
 ...oxmox-backup-client-static.bash-completion |  1 +
 debian/proxmox-backup-client-static.install   |  3 +++
 debian/rules                                  |  2 ++
 5 files changed, 30 insertions(+), 10 deletions(-)
 create mode 100644 debian/proxmox-backup-client-static.bash-completion
 create mode 100644 debian/proxmox-backup-client-static.install

diff --git a/Makefile b/Makefile
index 8d102871d..51a547553 100644
--- a/Makefile
+++ b/Makefile
@@ -38,12 +38,16 @@ SUBCRATES != cargo metadata --no-deps --format-version=1 \
 	| grep "$$PWD/" \
 	| sed -e "s!.*$$PWD/!!g" -e 's/\#.*$$//g' -e 's/)$$//g'
 
+STATIC_TARGET_DIR := target/static-build
+
 ifeq ($(BUILD_MODE), release)
 CARGO_BUILD_ARGS += --release --target $(DEB_HOST_RUST_TYPE)
 COMPILEDIR := target/$(DEB_HOST_RUST_TYPE)/release
+STATIC_COMPILEDIR := $(STATIC_TARGET_DIR)/$(DEB_HOST_RUST_TYPE)/release
 else
 CARGO_BUILD_ARGS += --target $(DEB_HOST_RUST_TYPE)
 COMPILEDIR := target/$(DEB_HOST_RUST_TYPE)/debug
+STATIC_COMPILEDIR := $(STATIC_TARGET_DIR)/$(DEB_HOST_RUST_TYPE)/debug
 endif
 
 ifeq ($(valgrind), yes)
@@ -63,10 +67,11 @@ CLIENT_DEB=$(PACKAGE)-client_$(DEB_VERSION)_$(ARCH).deb
 CLIENT_DBG_DEB=$(PACKAGE)-client-dbgsym_$(DEB_VERSION)_$(ARCH).deb
 RESTORE_DEB=proxmox-backup-file-restore_$(DEB_VERSION)_$(ARCH).deb
 RESTORE_DBG_DEB=proxmox-backup-file-restore-dbgsym_$(DEB_VERSION)_$(ARCH).deb
+STATIC_CLIENT_DEB=$(PACKAGE)-client-static_$(DEB_VERSION)_$(ARCH).deb
 DOC_DEB=$(PACKAGE)-docs_$(DEB_VERSION)_all.deb
 
 DEBS=$(SERVER_DEB) $(SERVER_DBG_DEB) $(CLIENT_DEB) $(CLIENT_DBG_DEB) \
-     $(RESTORE_DEB) $(RESTORE_DBG_DEB)
+     $(RESTORE_DEB) $(RESTORE_DBG_DEB) $(STATIC_CLIENT_DEB)
 
 DSC = rust-$(PACKAGE)_$(DEB_VERSION).dsc
 
@@ -198,7 +203,7 @@ $(COMPILED_BINS) $(COMPILEDIR)/dump-catalog-shell-cli $(COMPILEDIR)/docgen: .do-
 lint:
 	cargo clippy -- -A clippy::all -D clippy::correctness
 
-install: $(COMPILED_BINS)
+install: $(COMPILED_BINS) proxmox-backup-client-static
 	install -dm755 $(DESTDIR)$(BINDIR)
 	install -dm755 $(DESTDIR)$(ZSH_COMPL_DEST)
 	$(foreach i,$(USR_BIN), \
@@ -217,25 +222,26 @@ install: $(COMPILED_BINS)
 	install -m4755 -o root -g root $(COMPILEDIR)/sg-tape-cmd $(DESTDIR)$(LIBEXECDIR)/proxmox-backup/sg-tape-cmd
 	$(foreach i,$(SERVICE_BIN), \
 	    install -m755 $(COMPILEDIR)/$(i) $(DESTDIR)$(LIBEXECDIR)/proxmox-backup/ ;)
+	install -m755 $(STATIC_COMPILEDIR)/proxmox-backup-client $(DESTDIR)$(BINDIR)/proxmox-backup-client-static
 	$(MAKE) -C www install
 	$(MAKE) -C docs install
 	$(MAKE) -C templates install
 
 .PHONY: upload
 upload: UPLOAD_DIST ?= $(DEB_DISTRIBUTION)
-upload: $(SERVER_DEB) $(CLIENT_DEB) $(RESTORE_DEB) $(DOC_DEB)
+upload: $(SERVER_DEB) $(CLIENT_DEB) $(RESTORE_DEB) $(DOC_DEB) $(STATIC_CLIENT_DEB)
 	# check if working directory is clean
 	git diff --exit-code --stat && git diff --exit-code --stat --staged
-	tar cf - $(SERVER_DEB) $(SERVER_DBG_DEB) $(DOC_DEB) $(CLIENT_DEB) $(CLIENT_DBG_DEB) \
+	tar cf - $(SERVER_DEB) $(SERVER_DBG_DEB) $(DOC_DEB) $(CLIENT_DEB) $(CLIENT_DBG_DEB) $(STATIC_CLIENT_DEB) \
 	  | ssh -X repoman@repo.proxmox.com upload --product pbs --dist $(UPLOAD_DIST)
 	tar cf - $(CLIENT_DEB) $(CLIENT_DBG_DEB) | ssh -X repoman@repo.proxmox.com upload --product "pve,pmg,pbs-client" --dist $(UPLOAD_DIST)
+	tar cf - $(STATIC_CLIENT_DEB) | ssh -X repoman@repo.proxmox.com upload --product "pbs-client" --dist $(UPLOAD_DIST)
 	tar cf - $(RESTORE_DEB) $(RESTORE_DBG_DEB) | ssh -X repoman@repo.proxmox.com upload --product "pve" --dist $(UPLOAD_DIST)
 
 .PHONY: proxmox-backup-client-static
 proxmox-backup-client-static:
-	mkdir -p target/release/deps/ && \
-          echo '!<arch>' > target/release/deps/libsystemd.a # workaround for to greedy linkage and proxmox-systemd
-	RUSTFLAGS='-C target-feature=+crt-static -C strip=debuginfo' \
-        $(CARGO) build $(CARGO_BUILD_ARGS) \
-          --package proxmox-backup-client --bin proxmox-backup-client \
-          --target x86_64-unknown-linux-gnu
+	mkdir -p $(STATIC_COMPILEDIR)/deps-stubs/ && \
+          echo '!<arch>' > $(STATIC_COMPILEDIR)/deps-stubs/libsystemd.a # workaround for to greedy linkage and proxmox-systemd
+	$(CARGO) rustc $(CARGO_BUILD_ARGS)  --package proxmox-backup-client --bin proxmox-backup-client \
+          	--target $(STATIC_TARGET) --target-dir $(STATIC_TARGET_DIR) -- \
+		-C target-feature=+crt-static -L $(STATIC_COMPILEDIR)/deps-stubs/
diff --git a/debian/control b/debian/control
index 9687ebffa..b8f7cfa4a 100644
--- a/debian/control
+++ b/debian/control
@@ -205,6 +205,14 @@ Description: Proxmox Backup Client tools
  This package contains the Proxmox Backup client, which provides a
  simple command line tool to create and restore backups.
 
+Package: proxmox-backup-client-static
+Architecture: any
+Depends: qrencode, ${misc:Depends},
+Conflicts: proxmox-backup-client
+Description: Proxmox Backup Client tools (statically linked)
+ This package contains the Proxmox Backup client, which provides a
+ simple command line tool to create and restore backups.
+
 Package: proxmox-backup-docs
 Build-Profiles: <!nodoc>
 Section: doc
diff --git a/debian/proxmox-backup-client-static.bash-completion b/debian/proxmox-backup-client-static.bash-completion
new file mode 100644
index 000000000..f8b9b4394
--- /dev/null
+++ b/debian/proxmox-backup-client-static.bash-completion
@@ -0,0 +1 @@
+debian/proxmox-backup-client.bc proxmox-backup-client
diff --git a/debian/proxmox-backup-client-static.install b/debian/proxmox-backup-client-static.install
new file mode 100644
index 000000000..690303a74
--- /dev/null
+++ b/debian/proxmox-backup-client-static.install
@@ -0,0 +1,3 @@
+usr/share/man/man1/proxmox-backup-client.1
+usr/share/man/man1/pxar.1
+usr/share/zsh/vendor-completions/_proxmox-backup-client
diff --git a/debian/rules b/debian/rules
index a03fe11ba..be7c93c2e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -47,6 +47,8 @@ override_dh_auto_install:
 	dh_auto_install -- \
 	    PROXY_USER=backup \
 	    LIBDIR=/usr/lib/$(DEB_HOST_MULTIARCH)
+	mkdir -p debian/proxmox-backup-client-static/usr/bin
+	mv debian/tmp/usr/bin/proxmox-backup-client-static debian/proxmox-backup-client-static/usr/bin/proxmox-backup-client
 
 override_dh_installsystemd:
 	dh_installsystemd -pproxmox-backup-server  proxmox-backup-daily-update.timer
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] [PATCH v5 proxmox-backup 5/6] client: http: Use custom resolver for statically linked binary
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
                   ` (3 preceding siblings ...)
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 4/6] buildsys: build and package " Christian Ebner
@ 2025-04-09 11:05 ` Christian Ebner
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 6/6] docs: mention different name resolution " Christian Ebner
  2025-04-09 13:32 ` [pbs-devel] applied-series: [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Fabian Grünbichler
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

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>
---
changes since version 4:
- no changes

 Cargo.toml                    |  1 +
 pbs-client/Cargo.toml         |  1 +
 pbs-client/src/http_client.rs | 81 +++++++++++++++++++++++++++++++++--
 3 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index fb925bdeb..18f4f1938 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -127,6 +127,7 @@ futures = "0.3"
 h2 = { version = "0.4", features = [ "legacy", "stream" ] }
 handlebars = "3.0"
 hex = "0.4.3"
+hickory-resolver = { version = "0.24.1", default-features = false, features = [ "system-config", "tokio-runtime" ] }
 hyper = { version = "0.14", features = [ "backports", "deprecated", "full" ] }
 libc = "0.2"
 log = "0.4.17"
diff --git a/pbs-client/Cargo.toml b/pbs-client/Cargo.toml
index c28fe87ca..b4f78b5fd 100644
--- a/pbs-client/Cargo.toml
+++ b/pbs-client/Cargo.toml
@@ -27,6 +27,7 @@ tokio = { workspace = true, features = [ "fs", "signal" ] }
 tokio-stream.workspace = true
 tower-service.workspace = true
 xdg.workspace = true
+hickory-resolver.workspace = true
 
 pathpatterns.workspace = true
 
diff --git a/pbs-client/src/http_client.rs b/pbs-client/src/http_client.rs
index 8a89031c8..c95def07b 100644
--- a/pbs-client/src/http_client.rs
+++ b/pbs-client/src/http_client.rs
@@ -4,6 +4,8 @@ use std::time::Duration;
 
 use anyhow::{bail, format_err, Error};
 use futures::*;
+#[cfg(not(target_feature = "crt-static"))]
+use hyper::client::connect::dns::GaiResolver;
 use hyper::client::{Client, HttpConnector};
 use hyper::http::header::HeaderValue;
 use hyper::http::Uri;
@@ -33,6 +35,74 @@ use pbs_api_types::{Authid, RateLimitConfig, Userid};
 use super::pipe_to_stream::PipeToSendStream;
 use super::PROXMOX_BACKUP_TCP_KEEPALIVE_TIME;
 
+#[cfg(not(target_feature = "crt-static"))]
+type DnsResolver = GaiResolver;
+
+#[cfg(target_feature = "crt-static")]
+type DnsResolver = resolver::HickoryDnsResolver;
+
+#[cfg(target_feature = "crt-static")]
+mod resolver {
+    use std::net::SocketAddr;
+    use std::pin::Pin;
+    use std::sync::Arc;
+    use std::task::{Context, Poll};
+
+    use futures::Future;
+    use hickory_resolver::error::ResolveError;
+    use hickory_resolver::lookup_ip::LookupIpIntoIter;
+    use hickory_resolver::TokioAsyncResolver;
+    use hyper::client::connect::dns::Name;
+    use tower_service::Service;
+
+    pub(crate) struct SocketAddrIter {
+        inner: LookupIpIntoIter,
+    }
+
+    impl Iterator for SocketAddrIter {
+        type Item = SocketAddr;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            self.inner.next().map(|ip_addr| SocketAddr::new(ip_addr, 0))
+        }
+    }
+
+    #[derive(Clone)]
+    pub(crate) struct HickoryDnsResolver {
+        inner: Arc<TokioAsyncResolver>,
+    }
+
+    impl HickoryDnsResolver {
+        pub(crate) fn new() -> Self {
+            Self {
+                inner: Arc::new(TokioAsyncResolver::tokio_from_system_conf().unwrap()),
+            }
+        }
+    }
+
+    impl Service<Name> for HickoryDnsResolver {
+        type Response = SocketAddrIter;
+        type Error = ResolveError;
+        type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
+
+        fn poll_ready(&mut self, _ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+            Poll::Ready(Ok(()))
+        }
+
+        fn call(&mut self, name: Name) -> Self::Future {
+            let inner = self.inner.clone();
+            Box::pin(async move {
+                inner
+                    .lookup_ip(name.as_str())
+                    .await
+                    .map(|r| SocketAddrIter {
+                        inner: r.into_iter(),
+                    })
+            })
+        }
+    }
+}
+
 /// Timeout used for several HTTP operations that are expected to finish quickly but may block in
 /// certain error conditions. Keep it generous, to avoid false-positive under high load.
 const HTTP_TIMEOUT: Duration = Duration::from_secs(2 * 60);
@@ -134,7 +204,7 @@ impl Default for HttpClientOptions {
 
 /// HTTP(S) API client
 pub struct HttpClient {
-    client: Client<HttpsConnector>,
+    client: Client<HttpsConnector<DnsResolver>>,
     server: String,
     port: u16,
     fingerprint: Arc<Mutex<Option<String>>>,
@@ -365,7 +435,8 @@ impl HttpClient {
             ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::NONE);
         }
 
-        let mut httpc = HttpConnector::new();
+        let resolver = DnsResolver::new();
+        let mut httpc = HttpConnector::new_with_resolver(resolver);
         httpc.set_nodelay(true); // important for h2 download performance!
         httpc.enforce_http(false); // we want https...
 
@@ -526,7 +597,9 @@ impl HttpClient {
             _options: options,
         })
     }
+}
 
+impl HttpClient {
     /// Login
     ///
     /// Login is done on demand, so this is only required if you need
@@ -814,7 +887,7 @@ impl HttpClient {
     }
 
     async fn credentials(
-        client: Client<HttpsConnector>,
+        client: Client<HttpsConnector<DnsResolver>>,
         server: String,
         port: u16,
         username: Userid,
@@ -859,7 +932,7 @@ impl HttpClient {
     }
 
     async fn api_request(
-        client: Client<HttpsConnector>,
+        client: Client<HttpsConnector<DnsResolver>>,
         req: Request<Body>,
     ) -> Result<Value, Error> {
         Self::api_response(
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] [PATCH v5 proxmox-backup 6/6] docs: mention different name resolution for statically linked binary
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
                   ` (4 preceding siblings ...)
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 5/6] client: http: Use custom resolver for statically linked binary Christian Ebner
@ 2025-04-09 11:05 ` Christian Ebner
  2025-04-09 13:32 ` [pbs-devel] applied-series: [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Fabian Grünbichler
  6 siblings, 0 replies; 8+ messages in thread
From: Christian Ebner @ 2025-04-09 11:05 UTC (permalink / raw)
  To: pbs-devel

Add a note mentioning that the statically linked binary does not use
the same mechanism for name resolution as the regular client, in
particular that this does not support NSS.

The statically linked binary cannot use the `getaddrinfo` based name
resolution because of possible ABI incompatibility. It therefore is
conditionally compiled and linked using the name resolution provided
by hickory-resolver, part of hickory-dns [0].

[0] https://github.com/hickory-dns/hickory-dns

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
---
changes since version 4:
- no changes

 docs/backup-client.rst | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/docs/backup-client.rst b/docs/backup-client.rst
index bc80525be..1e0b4ac6b 100644
--- a/docs/backup-client.rst
+++ b/docs/backup-client.rst
@@ -44,6 +44,11 @@ user\@pbs!token@host:store       ``user@pbs!token`` host:8007          store
 [ff80::51]:1234:mydatastore      ``root@pam``       [ff80::51]:1234    mydatastore
 ================================ ================== ================== ===========
 
+.. Note:: If you are using the statically linked binary of proxmox backup client
+   name resolution will not be performed via the mechanisms provided by libc,
+   but uses a resolver written purely in the Rust programming language.
+   Therefore, features and modules provided by Name Service Switch cannot be
+   used.
 
 .. _environment-variables:
 
-- 
2.39.5



_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [pbs-devel] applied-series: [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client
  2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
                   ` (5 preceding siblings ...)
  2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 6/6] docs: mention different name resolution " Christian Ebner
@ 2025-04-09 13:32 ` Fabian Grünbichler
  6 siblings, 0 replies; 8+ messages in thread
From: Fabian Grünbichler @ 2025-04-09 13:32 UTC (permalink / raw)
  To: Proxmox Backup Server development discussion

with some follow-ups/fix-ups folded in.

thanks!

On April 9, 2025 1:05 pm, Christian Ebner wrote:
> As discussed in issue #4788 [0], statically linking of the
> `proxmox-backup-client` still suffers from possible incompatible
> dependencies on the NSS module libraries, further described in
> [1].
> 
> This patch series provides the means to statically compile the client
> with a workaround for the NSS lib limitation by relying on
> `hickory-dns` [2], as suggested by Thomas.
> The hickory-resolver is used for name resolution with the statically
> compiled binary instead of the default `getaddrinfo` based
> `GaiResolver`.
> 
> Since hickory-resolver depends on `ipconfig` for Windows targets when
> the `system-config` feature is enabled (required to read nameservers
> from `/etc/resolv.conf`), also the dependency on `ipconfig` is
> required by cargo. To workaround this, a dummy crate is registered in
> the cargo registry.
> 
> Changes since version 4:
> - Incorporated additions and suggestions regarding debian packaging
> 
> Changes since version 3:
> - Added default type GaiResolver to HttpsConnector
> - Include patch to mention different name resolution behavior in docs
> 
> Changes since version 2:
> - Use packaged version for hickory-resolver
> - Drop unneeded `ipconfig` dependency workaround
> - Rebased onto current master
> 
> [0] https://bugzilla.proxmox.com/show_bug.cgi?id=4788
> [1] 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
> [2] https://github.com/hickory-dns/hickory-dns
> 
> proxmox:
> 
> Christian Ebner (1):
>   http: client: make https connector generic over resolver
> 
>  proxmox-http/Cargo.toml              |  1 +
>  proxmox-http/src/client/connector.rs | 17 ++++++++++++-----
>  proxmox-http/src/client/simple.rs    |  3 ++-
>  3 files changed, 15 insertions(+), 6 deletions(-)
> 
> proxmox-backup:
> 
> Christian Ebner (5):
>   build: always set --target
>   fix: 4788: Makefile: target for statically linked client binary
>   buildsys: build and package statically linked client binary
>   client: http: Use custom resolver for statically linked binary
>   docs: mention different name resolution for statically linked binary
> 
>  Cargo.toml                                    |  1 +
>  Makefile                                      | 28 +++++--
>  debian/control                                |  8 ++
>  ...oxmox-backup-client-static.bash-completion |  1 +
>  debian/proxmox-backup-client-static.install   |  3 +
>  debian/rules                                  |  2 +
>  docs/backup-client.rst                        |  5 ++
>  pbs-client/Cargo.toml                         |  1 +
>  pbs-client/src/http_client.rs                 | 81 ++++++++++++++++++-
>  9 files changed, 121 insertions(+), 9 deletions(-)
>  create mode 100644 debian/proxmox-backup-client-static.bash-completion
>  create mode 100644 debian/proxmox-backup-client-static.install
> 
> -- 
> 2.39.5
> 
> 
> 
> _______________________________________________
> pbs-devel mailing list
> pbs-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
> 
> 
> 


_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2025-04-09 13:32 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-04-09 11:05 [pbs-devel] [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Christian Ebner
2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox 1/6] http: client: make https connector generic over resolver Christian Ebner
2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 2/6] build: always set --target Christian Ebner
2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 3/6] fix: 4788: Makefile: target for statically linked client binary Christian Ebner
2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 4/6] buildsys: build and package " Christian Ebner
2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 5/6] client: http: Use custom resolver for statically linked binary Christian Ebner
2025-04-09 11:05 ` [pbs-devel] [PATCH v5 proxmox-backup 6/6] docs: mention different name resolution " Christian Ebner
2025-04-09 13:32 ` [pbs-devel] applied-series: [PATCH v5 proxmox proxmox-backup 0/6] fix 4788: statically linked proxmox-backup-client Fabian Grünbichler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal