Skip to content
Snippets Groups Projects
Commit 09ff62fb authored by Simon McVittie's avatar Simon McVittie
Browse files

wrap: Parse several environment variables for paths to mount

This takes over responsibility from the shell scripts that currently
wrap this executable.

When combined with a Steam update, this should resolve a lot of issues
involving paths outside the current working directory.

Resolves: pressure-vessel#4
Resolves: pressure-vessel#11
Resolves: pressure-vessel#12
Resolves: https://github.com/ValveSoftware/steam-runtime/issues/217
Resolves: https://github.com/ValveSoftware/steam-runtime/issues/236
Resolves: https://github.com/ValveSoftware/steam-runtime/issues/257


Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 602bdfae
No related branches found
No related tags found
No related merge requests found
......@@ -255,10 +255,11 @@ The following environment variables (among others) are read by
: Equivalent to `--steam-app-id="$STEAM_COMPAT_APP_ID"`.
`STEAM_COMPAT_APP_LIBRARY_PATH` (path)
: (Not used yet, but should be.)
: Deprecated equivalent of `STEAM_COMPAT_MOUNTS`, except that it is
a single path instead of being colon-delimited.
`STEAM_COMPAT_APP_LIBRARY_PATHS` (path)
: (Not used yet, but should be?)
`STEAM_COMPAT_APP_LIBRARY_PATHS` (`:`-separated list of paths)
: Deprecated equivalent of `STEAM_COMPAT_MOUNTS`.
`STEAM_COMPAT_CLIENT_INSTALL_PATH` (path)
: When used as a Steam compatibility tool, the absolute path to the
......@@ -270,11 +271,40 @@ The following environment variables (among others) are read by
variable data directory used by Proton, if any.
This is made available read/write in the container.
`STEAM_COMPAT_INSTALL_PATH` (path)
: Top-level directory containing the game itself, even if the current
working directory is actually a subdirectory of this.
This is made available read/write in the container.
`STEAM_COMPAT_LIBRARY_PATHS` (`:`-separated list of paths)
: Colon-delimited list of paths to Steam Library directories containing
the game, the compatibility tools if any, and any other resources
that the game will need, such as DirectX installers.
Each is currently made available read/write in the container.
`STEAM_COMPAT_MOUNT_PATHS` (`:`-separated list of paths)
: Deprecated equivalent of `STEAM_COMPAT_MOUNTS`.
`STEAM_COMPAT_MOUNTS` (`:`-separated list of paths)
: Colon-delimited list of paths to additional directories that are to
be made available read/write in the container.
`STEAM_COMPAT_SESSION_ID` (integer)
: (Not used yet, but should be.)
`STEAM_COMPAT_SHADER_PATH` (path)
: When used as a Steam compatibility tool, the absolute path to the
variable data directory used for cached shaders, if any.
This is made available read/write in the container.
`STEAM_COMPAT_TOOL_PATH` (path)
: Deprecated equivalent of `STEAM_COMPAT_TOOL_PATHS`, except that it is
a single path instead of being colon-delimited.
`STEAM_COMPAT_TOOL_PATHS` (`:`-separated list of paths)
: (Not used yet, but should be.)
: Colon-delimited list of paths to Steam compatibility tools in use,
such as Proton and the Steam Linux Runtime.
They are currently made available read/write in the container.
`STEAM_RUNTIME` (path)
: **pressure-vessel-wrap** refuses to run if this environment variable
......
......@@ -325,15 +325,49 @@ export_contents_of_run (FlatpakBwrap *bwrap,
return TRUE;
}
typedef enum
{
ENV_MOUNT_FLAGS_COLON_DELIMITED = (1 << 0),
ENV_MOUNT_FLAGS_DEPRECATED = (1 << 1),
ENV_MOUNT_FLAGS_NONE = 0
} EnvMountFlags;
typedef struct
{
const char *name;
EnvMountFlags flags;
} EnvMount;
static const EnvMount known_required_env[] =
{
{ "STEAM_COMPAT_APP_LIBRARY_PATH", ENV_MOUNT_FLAGS_DEPRECATED },
{ "STEAM_COMPAT_APP_LIBRARY_PATHS",
ENV_MOUNT_FLAGS_COLON_DELIMITED | ENV_MOUNT_FLAGS_DEPRECATED },
{ "STEAM_COMPAT_CLIENT_INSTALL_PATH", ENV_MOUNT_FLAGS_NONE },
{ "STEAM_COMPAT_DATA_PATH", ENV_MOUNT_FLAGS_NONE },
{ "STEAM_COMPAT_INSTALL_PATH", ENV_MOUNT_FLAGS_NONE },
{ "STEAM_COMPAT_LIBRARY_PATHS", ENV_MOUNT_FLAGS_COLON_DELIMITED },
{ "STEAM_COMPAT_MOUNT_PATHS",
ENV_MOUNT_FLAGS_COLON_DELIMITED | ENV_MOUNT_FLAGS_DEPRECATED },
{ "STEAM_COMPAT_MOUNTS", ENV_MOUNT_FLAGS_COLON_DELIMITED },
{ "STEAM_COMPAT_SHADER_PATH", ENV_MOUNT_FLAGS_NONE },
{ "STEAM_COMPAT_TOOL_PATH", ENV_MOUNT_FLAGS_DEPRECATED },
{ "STEAM_COMPAT_TOOL_PATHS", ENV_MOUNT_FLAGS_COLON_DELIMITED },
};
static void
bind_and_propagate_from_environ (FlatpakExports *exports,
FlatpakBwrap *bwrap,
FlatpakFilesystemMode mode,
const char *variable)
const char *variable,
EnvMountFlags flags)
{
g_autofree gchar *value_host = NULL;
g_autofree gchar *canon = NULL;
g_auto(GStrv) values = NULL;
const char *value;
const char *before;
const char *after;
gboolean changed = FALSE;
gsize i;
g_return_if_fail (exports != NULL);
g_return_if_fail ((unsigned) mode <= FLATPAK_FILESYSTEM_MODE_LAST);
......@@ -344,24 +378,63 @@ bind_and_propagate_from_environ (FlatpakExports *exports,
if (value == NULL)
return;
if (!g_file_test (value, G_FILE_TEST_EXISTS))
if (flags & ENV_MOUNT_FLAGS_DEPRECATED)
g_message ("Setting $%s is deprecated", variable);
if (flags & ENV_MOUNT_FLAGS_COLON_DELIMITED)
{
values = g_strsplit (value, ":", -1);
before = "...:";
after = ":...";
}
else
{
g_debug ("Not bind-mounting %s=\"%s\" because it does not exist",
variable, value);
return;
values = g_new0 (gchar *, 2);
values[0] = g_strdup (value);
values[1] = NULL;
before = "";
after = "";
}
canon = g_canonicalize_filename (value, NULL);
value_host = pv_current_namespace_path_to_host_path (canon);
for (i = 0; values[i] != NULL; i++)
{
g_autofree gchar *value_host = NULL;
g_autofree gchar *canon = NULL;
g_debug ("Bind-mounting %s=\"%s\" from the current env as %s=\"%s\" in the host",
variable, value, variable, value_host);
flatpak_exports_add_path_expose (exports, mode, canon);
if (values[i][0] == '\0')
continue;
if (strcmp (value, value_host) != 0)
flatpak_bwrap_add_args (bwrap,
"--setenv", variable, value_host,
NULL);
if (!g_file_test (values[i], G_FILE_TEST_EXISTS))
{
g_debug ("Not bind-mounting %s=\"%s%s%s\" because it does not exist",
variable, before, values[i], after);
continue;
}
canon = g_canonicalize_filename (values[i], NULL);
value_host = pv_current_namespace_path_to_host_path (canon);
g_debug ("Bind-mounting %s=\"%s%s%s\" from the current env as %s=\"%s%s%s\" in the host",
variable, before, values[i], after,
variable, before, value_host, after);
flatpak_exports_add_path_expose (exports, mode, canon);
if (strcmp (values[i], value_host) != 0)
{
g_clear_pointer (&values[i], g_free);
values[i] = g_steal_pointer (&value_host);
changed = TRUE;
}
}
if (changed)
{
g_autofree gchar *joined = g_strjoinv (":", values);
flatpak_bwrap_add_args (bwrap,
"--setenv", variable, joined,
NULL);
}
}
/* Order matters here: root, steam and steambeta are or might be symlinks
......@@ -1032,12 +1105,6 @@ main (int argc,
const gchar *bwrap_help_argv[] = { "<bwrap>", "--help", NULL };
g_autoptr(PvRuntime) runtime = NULL;
g_autoptr(FILE) original_stdout = NULL;
const char * const known_required_env[] =
{
"STEAM_COMPAT_CLIENT_INSTALL_PATH",
"STEAM_COMPAT_DATA_PATH",
"STEAM_COMPAT_TOOL_PATH",
};
my_pid = getpid ();
......@@ -1716,7 +1783,8 @@ main (int argc,
for (i = 0; i < G_N_ELEMENTS (known_required_env); i++)
bind_and_propagate_from_environ (exports, bwrap,
FLATPAK_FILESYSTEM_MODE_READ_WRITE,
known_required_env[i]);
known_required_env[i].name,
known_required_env[i].flags);
/* Make arbitrary filesystems available. This is not as complete as
* Flatpak yet. */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment