[pbs-devel] superseded: Re: [PATCH backup v2] http_client: fallback if XDG_RUNTIME_DIR is not set
Maximiliano Sandoval
m.sandoval at proxmox.com
Wed Apr 16 14:57:13 CEST 2025
Wolfgang Bumiller <w.bumiller at proxmox.com> writes:
> On Mon, Apr 14, 2025 at 04:22:17PM +0200, Maximiliano Sandoval wrote:
>> xdg::BaseDirectory's [place_directory_file] errors out if
>
> Should be `place_runtime_file`, since other directories will fall back
> to the regular $HOME paths.
>
> For the runtime dir this makes sense. A user who is not logged into a
> seat does not *have* one.
>
>> `XDG_RUNTIME_DIR` is not set.
>>
>> This is not ideal, as per the the base directory [specification]:
>>
>> > If $XDG_RUNTIME_DIR is not set applications should fall back to a
>> replacement directory with similar capabilities and print a warning
>> message. Applications should use this directory for communication and
>> synchronization purposes and should not place larger files in it, since
>> it might reside in runtime memory and cannot necessarily be swapped out
>> to disk.
>
> ^ This is not useful information for why this patch is doing what it
> does.
>
>>
>> At the moment, running the proxmox-backup-client with sudo will print an error:
>> ```
>> storing login ticket failed: $XDG_RUNTIME_DIR must be set
>> ```
>>
>> We add a helper that places a runtime file `basename` which fallbacks to
>> `/run/user/{uid}/{prefix}/{basename}`.
>
> A runtime directory is created when the user logs into a seat, so a
> logged in user always has one, so if not, is the `/run/user/$uid`
> directory really the right choice? Are there any other tools that do
> this?
>
> For this case I'd argue that we should instead switch from the runtime
> directory to the cache directory. This should also work via sudo and
> makes more sense. The ticket can still be used if the machine reboots,
> after all.
>>
>> [place_directory_file] https://docs.rs/xdg/latest/xdg/struct.BaseDirectories.html#method.place_runtime_file
>> [specification]: https://specifications.freedesktop.org/basedir-spec/latest/
>>
>> Signed-off-by: Maximiliano Sandoval <m.sandoval at proxmox.com>
>> ---
>> Differences from v1:
>> - Actually use `prefix` argument in fallback branch
>> - Stop checking for root, always use /run/user/{uid}/{prefix}
>>
>> pbs-client/src/http_client.rs | 50 +++++++++++++++++++++++++----------
>> 1 file changed, 36 insertions(+), 14 deletions(-)
>>
>> diff --git a/pbs-client/src/http_client.rs b/pbs-client/src/http_client.rs
>> index c95def07b..9b1a9595c 100644
>> --- a/pbs-client/src/http_client.rs
>> +++ b/pbs-client/src/http_client.rs
>> @@ -1,8 +1,9 @@
>> use std::io::{IsTerminal, Write};
>> +use std::path::PathBuf;
>> use std::sync::{Arc, Mutex, RwLock};
>> use std::time::Duration;
>>
>> -use anyhow::{bail, format_err, Error};
>> +use anyhow::{bail, format_err, Context, Error};
>> use futures::*;
>> #[cfg(not(target_feature = "crt-static"))]
>> use hyper::client::connect::dns::GaiResolver;
>> @@ -27,7 +28,7 @@ use proxmox_async::broadcast_future::BroadcastFuture;
>> use proxmox_http::client::HttpsConnector;
>> use proxmox_http::uri::{build_authority, json_object_to_query};
>> use proxmox_http::{ProxyConfig, RateLimiter};
>> -use proxmox_log::{error, info, warn};
>> +use proxmox_log::{debug, error, info, warn};
>>
>> use pbs_api_types::percent_encoding::DEFAULT_ENCODE_SET;
>> use pbs_api_types::{Authid, RateLimitConfig, Userid};
>> @@ -216,10 +217,7 @@ pub struct HttpClient {
>>
>> /// Delete stored ticket data (logout)
>> pub fn delete_ticket_info(prefix: &str, server: &str, username: &Userid) -> Result<(), Error> {
>> - let base = BaseDirectories::with_prefix(prefix)?;
>> -
>> - // usually /run/user/<uid>/...
>> - let path = base.place_runtime_file("tickets")?;
>> + let path = place_runtime_file(prefix, "tickets")?;
>>
>> let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
>>
>> @@ -305,10 +303,7 @@ fn store_ticket_info(
>> ticket: &str,
>> token: &str,
>> ) -> Result<(), Error> {
>> - let base = BaseDirectories::with_prefix(prefix)?;
>> -
>> - // usually /run/user/<uid>/...
>> - let path = base.place_runtime_file("tickets")?;
>> + let path = place_runtime_file(prefix, "tickets")?;
>>
>> let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
>>
>> @@ -345,10 +340,9 @@ fn store_ticket_info(
>> }
>>
>> fn load_ticket_info(prefix: &str, server: &str, userid: &Userid) -> Option<(String, String)> {
>> - let base = BaseDirectories::with_prefix(prefix).ok()?;
>> -
>> - // usually /run/user/<uid>/...
>> - let path = base.place_runtime_file("tickets").ok()?;
>> + let path = place_runtime_file(prefix, "tickets")
>> + .inspect_err(|err| error!("could not place runtime file: {err:#}"))
>> + .ok()?;
>> let data = file_get_json(path, None).ok()?;
>> let now = proxmox_time::epoch_i64();
>> let ticket_lifetime = proxmox_auth_api::TICKET_LIFETIME - 60;
>> @@ -1181,3 +1175,31 @@ impl H2Client {
>> Ok(request)
>> }
>> }
>> +
>> +// Returns an absolute path in `XDG_RUNTIME_DIR` where a runtime file may be
>> +// stored. Leading directories in the returned path are pre-created; if that is
>> +// not possible, an error is returned.
>> +//
>> +// Similar to [BaseDirectories::place_runtime_file] but will fall back to
>> +// `/run/user/{uid}/{prefix}` if the `XDG_RUNTIME_DIR` variable is not set.
>> +fn place_runtime_file(prefix: &str, basename: &str) -> Result<PathBuf, Error> {
>> + let base =
>> + BaseDirectories::with_prefix(prefix).with_context(|| "failed to get base directories")?;
>> +
>> + let path = if base.has_runtime_directory() {
>> + base.place_runtime_file(basename)
>> + .with_context(|| format!("failed to place runtime file {basename}"))?
>> + } else {
>> + let uid = nix::unistd::Uid::current();
>> + let path = PathBuf::from(format!("/run/user/{uid}/{prefix}/"));
>> + std::fs::create_dir_all(&path)?;
>> + debug!(
>> + "XDG_RUNTIME_DIR is not set, using {} as fallback",
>> + path.display()
>> + );
>> + path.join(basename)
>> + };
>> + debug!("placing {basename} at {}", path.display());
>> +
>> + Ok(path)
>> +}
>> --
>> 2.39.5
superseded by
https://lore.proxmox.com/pbs-devel/20250416125651.334868-1-m.sandoval@proxmox.com/T/#t.
More information about the pbs-devel
mailing list