From 8f8fbae1c25a918f7e840f251dee297d30bb7099 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Tue, 15 Jul 2025 10:29:45 -0600 Subject: [PATCH 01/14] add tomlplusplus.wrap file and tomlplsuplus.dep to Meson.build --- configuration.toml | 2 ++ meson.build | 7 ++++--- subprojects/tomlplusplus.wrap | 8 ++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 configuration.toml create mode 100644 subprojects/tomlplusplus.wrap diff --git a/configuration.toml b/configuration.toml new file mode 100644 index 00000000..78e2d2ad --- /dev/null +++ b/configuration.toml @@ -0,0 +1,2 @@ +use_squashfuse = false #change to 'true' if you want to mount uenv rootless, without needing a setuid binary +uenv_local_repos = [""] #add a list of local uenv repos to search through for `uenv image ls`, `uenv start`, and `uenv run` in addition to the user repo. \ No newline at end of file diff --git a/meson.build b/meson.build index 4f4cd65d..ca54e673 100644 --- a/meson.build +++ b/meson.build @@ -28,6 +28,7 @@ fmt_dep = subproject('fmt', default_options: ['werror=false', 'warning_level=0 json_dep = subproject('nlohmann_json', default_options: ['werror=false', 'warning_level=0']).get_variable('nlohmann_json_dep') spdlog_dep = subproject('spdlog', default_options: ['werror=false', 'warning_level=0','std_format=disabled','external_fmt=enabled']).get_variable('spdlog_dep') sqlite3_dep = subproject('sqlite3', default_options: ['werror=false', 'warning_level=0']).get_variable('sqlite3_dep') +tomlplusplus_dep = subproject('tomlplusplus', default_options: ['werror=false', 'warning_level=0']).get_variable('tomlplusplus_dep') subproject('curl', default_options: ['werror=false', 'warning_level=0', 'tests=disabled', 'unittests=disabled', 'tool=disabled']) curl_dep = dependency('libcurl', required: true) @@ -65,12 +66,12 @@ lib_uenv = static_library( 'libuenv', lib_src, include_directories: lib_inc, - dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep], + dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep, tomlplusplus_dep], ) uenv_dep = declare_dependency( link_with: lib_uenv, - dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep], + dependencies: [curl_dep, sqlite3_dep, fmt_dep, spdlog_dep, json_dep, barkeep_dep, tomlplusplus_dep], include_directories: lib_inc ) @@ -101,7 +102,7 @@ if uenv_cli cli = executable('uenv', sources: cli_src, - dependencies: [uenv_dep, sqlite3_dep, fmt_dep, spdlog_dep, cli11_dep, barkeep_dep], + dependencies: [uenv_dep, sqlite3_dep, fmt_dep, spdlog_dep, cli11_dep, barkeep_dep, tomlplusplus_dep], c_args: [ '-DVERSION="@0@"'.format(version), ], diff --git a/subprojects/tomlplusplus.wrap b/subprojects/tomlplusplus.wrap new file mode 100644 index 00000000..8807085e --- /dev/null +++ b/subprojects/tomlplusplus.wrap @@ -0,0 +1,8 @@ +[wrap-file] +directory = tomlplusplus-3.4.0 +source_url = https://github.com/marzer/tomlplusplus/archive/refs/tags/v3.4.0.tar.gz +source_filename = tomlplusplus-3.4.0.tar.gz +source_hash = 8517f65938a4faae9ccf8ebb36631a38c1cadfb5efa85d9a72e15b9e97d25155 + +[provide] +tomlplusplus = tomlplusplus_dep \ No newline at end of file From f69e5c4fb9e8c7d368f439d842a25cdb809ed954 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Tue, 15 Jul 2025 10:52:22 -0600 Subject: [PATCH 02/14] Add toml config for squashfs-mount-rootless option in start and run --- .vscode/settings.json | 62 +++++++++++++++++++++++++++++++++++++++++++ src/cli/run.cpp | 22 ++++++++++++++- src/cli/start.cpp | 22 ++++++++++++++- 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..1e47610b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,62 @@ +{ + "files.associations": { + "__bit_reference": "cpp", + "__hash_table": "cpp", + "__locale": "cpp", + "__node_handle": "cpp", + "__split_buffer": "cpp", + "__tree": "cpp", + "__verbose_abort": "cpp", + "any": "cpp", + "array": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "execution": "cpp", + "memory": "cpp", + "forward_list": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "locale": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "print": "cpp", + "queue": "cpp", + "ratio": "cpp", + "regex": "cpp", + "set": "cpp", + "span": "cpp", + "sstream": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "string_view": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "variant": "cpp", + "vector": "cpp", + "algorithm": "cpp" + } +} \ No newline at end of file diff --git a/src/cli/run.cpp b/src/cli/run.cpp index 48fb8090..81cb9992 100644 --- a/src/cli/run.cpp +++ b/src/cli/run.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -59,11 +60,30 @@ You need to finish the current session by typing 'exit' or hitting ''.)" return 1; } + //parse configuration.toml + toml::table config; + char *config_location = getenv("UENV_CONFIGURATION_PATH"); //gets config file from UENV_CONFIGURATION_PATH env variable + std::string_view config_sv{config_location}; + try{ + config = toml::parse_file(config_sv); + } catch(const toml::parse_error& err){ + term::err("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + } + bool use_squashfuse = config["use_squashfuse"].value_or(false); //parse use_squashfuse key from configuration.toml + auto runtime_environment = generate_environment(*env, globals.calling_environment, "SQFSMNT_FWD_"); // generate the mount list - std::vector commands = {"squashfs-mount"}; + std::vector commands = {}; + + if (use_squashfuse){ + commands.push_back("squashfs-mount-rootless"); + } + else{ + commands.push_back("squashfs-mount"); + } + for (auto e : env->uenvs) { commands.push_back(fmt::format("{}:{}", e.second.sqfs_path.string(), e.second.mount_path)); diff --git a/src/cli/start.cpp b/src/cli/start.cpp index 73787b9a..0f2577da 100644 --- a/src/cli/start.cpp +++ b/src/cli/start.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -102,11 +103,30 @@ will not work, because it starts a new interactive shell.)", return 1; } + //parse configuration.toml + toml::table config; + char *config_location = getenv("UENV_CONFIGURATION_PATH"); //gets config file from UENV_CONFIGURATION_PATH env variable + std::string_view config_sv{config_location}; + try{ + config = toml::parse_file(config_sv); + } catch(const toml::parse_error& err){ + term::err("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + } + bool use_squashfuse = config["use_squashfuse"].value_or(false); //parse use_squashfuse key from configuration.toml + auto runtime_environment = generate_environment(*env, globals.calling_environment, "SQFSMNT_FWD_"); // generate the mount list - std::vector commands = {"squashfs-mount"}; + std::vector commands = {}; + + if (use_squashfuse){ + commands.push_back("squashfs-mount-rootless"); + } + else{ + commands.push_back("squashfs-mount"); + } + for (auto e : env->uenvs) { commands.push_back(fmt::format("{}:{}", e.second.sqfs_path.string(), e.second.mount_path)); From 9ec2cc804eca484f2d6ac418ccb6d6db5b992fa3 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Tue, 15 Jul 2025 10:52:48 -0600 Subject: [PATCH 03/14] Remove vscode --- .vscode/settings.json | 62 ------------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1e47610b..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "files.associations": { - "__bit_reference": "cpp", - "__hash_table": "cpp", - "__locale": "cpp", - "__node_handle": "cpp", - "__split_buffer": "cpp", - "__tree": "cpp", - "__verbose_abort": "cpp", - "any": "cpp", - "array": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "charconv": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "complex": "cpp", - "condition_variable": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "execution": "cpp", - "memory": "cpp", - "forward_list": "cpp", - "fstream": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "ios": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "locale": "cpp", - "mutex": "cpp", - "new": "cpp", - "optional": "cpp", - "print": "cpp", - "queue": "cpp", - "ratio": "cpp", - "regex": "cpp", - "set": "cpp", - "span": "cpp", - "sstream": "cpp", - "stack": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "string": "cpp", - "string_view": "cpp", - "typeinfo": "cpp", - "unordered_map": "cpp", - "variant": "cpp", - "vector": "cpp", - "algorithm": "cpp" - } -} \ No newline at end of file From 5d242440e12cff1e069367865c76fc2074e6a7f1 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Tue, 15 Jul 2025 11:08:12 -0600 Subject: [PATCH 04/14] Add toml config parsing to recursively list uenv in locally defined repos --- src/cli/ls.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index b899ed3c..5566a148 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -43,6 +43,18 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { return 1; } + //parse configuration.toml + toml::table config; + char *config_location = getenv("UENV_CONFIGURATION_PATH"); //gets config file from UENV_CONFIGURATION_PATH env variable + std::string_view config_sv{config_location}; + try{ + config = toml::parse_file(config_sv); + } catch(const toml::parse_error& err){ + term::err("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + } + + toml::array& config_repo = *config["uenv_global_repo"].as_array(); + // open the repo auto store = uenv::open_repository(settings.config.repo.value()); if (!store) { @@ -72,9 +84,29 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { term::error("invalid search term: {}", store.error()); return 1; } - + printf("User Repository: %s\n", settings.config.repo.value().c_str()); print_record_set(*result, args.no_header, args.json); + // query the local repos + for (auto& repo : config_repo){ + if (repo.is_string()){//if repo is string, query + std::filesystem::path repo_path = repo.value_or(""); + auto local_store = uenv::open_repository(repo_path); + if (!local_store) { + term::error("unable to open local repo: {}", local_store.error()); + return 1; + } + + const auto local_result = local_store->query(label); + if (!local_result) { + term::error("invalid search term: {}", local_store.error()); + return 1; + } + printf("\nLocal Repository: %s\n", repo.value_or("")); + print_record_set(*local_result, args.no_header, args.json); //print local repo listing + } + } + return 0; } From 2c40586219f99477878e6964362d0b20adf9ab38 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Tue, 15 Jul 2025 11:17:14 -0600 Subject: [PATCH 05/14] Add support using uenv found in multiple local repos defined in toml config --- src/cli/ls.cpp | 1 + src/uenv/env.cpp | 61 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index 5566a148..1ba073de 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 3c5602a7..21afa753 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -159,22 +160,64 @@ concretise_env(const std::string& uenv_args, const auto results = *result; if (results.empty()) { - return unexpected(fmt::format("no uenv matches '{}'", *label)); - } + //parse configuration.toml + toml::table config; + char *config_location = getenv("UENV_CONFIGURATION_PATH"); //gets config file from UENV_CONFIGURATION_PATH env variable + std::string_view config_sv{config_location}; + try{ + config = toml::parse_file(config_sv); + } catch(const toml::parse_error& err){ + std::cerr << "Error parsing configuration.toml:\n" << err << "\n"; + } - // ensure that all results share a unique sha - if (!results.unique_sha()) { + toml::array& config_repo = *config["uenv_global_repo"].as_array(); //parses toml key as an array of repos + + auto global_results = results; + //recuse through uenv_global_repo array + for (auto& repo : config_repo){ + if (repo.is_string()){ //if repo is a string, then query + std::filesystem::path repo_path = repo.value_or(""); + const auto global_store = uenv::open_repository(repo_path); + const auto global_result = global_store->query(*label); + global_results = *global_result; + if (!global_results.empty()){ //if repo finds uenv, then set sqfs_path and break + const auto& r = *global_results.begin(); + sqfs_path = global_store->uenv_paths(r.sha).squashfs; + //printf("Uenv found in global repository: %s\n", repo.value_or("")); + break; + } + } + else{ + std::cerr << "Error: uenv global config isn't a string" << std::endl; + } + } + if (global_results.empty()){ //if uenv couldn't be found in local or global repo + return unexpected(fmt::format("no uenv matches '{}'", *label)); + } + // ensure that all results share a unique sha + if (!global_results.unique_sha()) { auto errmsg = fmt::format( "more than one uenv matches the uenv description " "'{}':\n", desc.label().value()); - errmsg += format_record_set(results); + errmsg += format_record_set(global_results); return unexpected(errmsg); - } + } + } else { + // ensure that all results share a unique sha + if (!results.unique_sha()) { + auto errmsg = fmt::format( + "more than one uenv matches the uenv description " + "'{}':\n", + desc.label().value()); + errmsg += format_record_set(results); + return unexpected(errmsg); + } - // set sqfs_path - const auto& r = *results.begin(); - sqfs_path = store->uenv_paths(r.sha).squashfs; + // set sqfs_path + const auto& r = *results.begin(); + sqfs_path = store->uenv_paths(r.sha).squashfs; + } } // otherwise an explicit filename was provided, e.g. // "/scratch/myimages/develp/store.squashfs" From 4bf52c7527966fed17fc9d0a698acf4f92dd9c07 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 12:34:20 -0600 Subject: [PATCH 06/14] Fixed term::err to term::error --- src/cli/ls.cpp | 2 +- src/cli/run.cpp | 2 +- src/cli/start.cpp | 2 +- src/uenv/env.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index 1ba073de..6b8f7567 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -51,7 +51,7 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { try{ config = toml::parse_file(config_sv); } catch(const toml::parse_error& err){ - term::err("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); } toml::array& config_repo = *config["uenv_global_repo"].as_array(); diff --git a/src/cli/run.cpp b/src/cli/run.cpp index 81cb9992..515719d1 100644 --- a/src/cli/run.cpp +++ b/src/cli/run.cpp @@ -67,7 +67,7 @@ You need to finish the current session by typing 'exit' or hitting ''.)" try{ config = toml::parse_file(config_sv); } catch(const toml::parse_error& err){ - term::err("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); } bool use_squashfuse = config["use_squashfuse"].value_or(false); //parse use_squashfuse key from configuration.toml diff --git a/src/cli/start.cpp b/src/cli/start.cpp index 0f2577da..8ea94a07 100644 --- a/src/cli/start.cpp +++ b/src/cli/start.cpp @@ -110,7 +110,7 @@ will not work, because it starts a new interactive shell.)", try{ config = toml::parse_file(config_sv); } catch(const toml::parse_error& err){ - term::err("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); } bool use_squashfuse = config["use_squashfuse"].value_or(false); //parse use_squashfuse key from configuration.toml diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 21afa753..78e602d0 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -167,7 +167,7 @@ concretise_env(const std::string& uenv_args, try{ config = toml::parse_file(config_sv); } catch(const toml::parse_error& err){ - std::cerr << "Error parsing configuration.toml:\n" << err << "\n"; + term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); } toml::array& config_repo = *config["uenv_global_repo"].as_array(); //parses toml key as an array of repos @@ -188,7 +188,7 @@ concretise_env(const std::string& uenv_args, } } else{ - std::cerr << "Error: uenv global config isn't a string" << std::endl; + term::error("{}", "Error: uenv global config isn't a string"); } } if (global_results.empty()){ //if uenv couldn't be found in local or global repo From a14f86f2e96117f2097fb5f6ad4bbc47237d9e82 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 12:36:52 -0600 Subject: [PATCH 07/14] Add terminal header --- src/uenv/env.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 78e602d0..98696c90 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -24,6 +24,8 @@ #include #include +#include "terminal.h" + namespace uenv { using util::unexpected; From 4a135f53391960e18c59d18bdf499db52a8e7270 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 12:40:59 -0600 Subject: [PATCH 08/14] Use unexpected() instead of terminal error --- src/uenv/env.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 98696c90..12582b20 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -24,8 +24,6 @@ #include #include -#include "terminal.h" - namespace uenv { using util::unexpected; @@ -170,6 +168,8 @@ concretise_env(const std::string& uenv_args, config = toml::parse_file(config_sv); } catch(const toml::parse_error& err){ term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); + return unexpected( + fmt::format("Error parsing configuration.toml:\n{}",err)); } toml::array& config_repo = *config["uenv_global_repo"].as_array(); //parses toml key as an array of repos From e144dad518ad15cd2cac37225eda1e90fec1fec0 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 12:45:01 -0600 Subject: [PATCH 09/14] Remove term::error's and switch global to local --- src/cli/ls.cpp | 2 +- src/uenv/env.cpp | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index 6b8f7567..925e7549 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -54,7 +54,7 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); } - toml::array& config_repo = *config["uenv_global_repo"].as_array(); + toml::array& config_repo = *config["uenv_local_repos"].as_array(); // open the repo auto store = uenv::open_repository(settings.config.repo.value()); diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 12582b20..059f1d56 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -167,42 +167,42 @@ concretise_env(const std::string& uenv_args, try{ config = toml::parse_file(config_sv); } catch(const toml::parse_error& err){ - term::error("{}", fmt::format("Error parsing configuration.toml:\n{}",err)); return unexpected( fmt::format("Error parsing configuration.toml:\n{}",err)); } - toml::array& config_repo = *config["uenv_global_repo"].as_array(); //parses toml key as an array of repos + toml::array& config_repo = *config["uenv_local_repos"].as_array(); //parses toml key as an array of repos - auto global_results = results; - //recuse through uenv_global_repo array + auto local_results = results; + //recuse through uenv_local_repo array for (auto& repo : config_repo){ if (repo.is_string()){ //if repo is a string, then query std::filesystem::path repo_path = repo.value_or(""); - const auto global_store = uenv::open_repository(repo_path); - const auto global_result = global_store->query(*label); - global_results = *global_result; - if (!global_results.empty()){ //if repo finds uenv, then set sqfs_path and break - const auto& r = *global_results.begin(); - sqfs_path = global_store->uenv_paths(r.sha).squashfs; - //printf("Uenv found in global repository: %s\n", repo.value_or("")); + const auto local_store = uenv::open_repository(repo_path); + const auto local_result = local_store->query(*label); + local_results = *local_result; + if (!local_results.empty()){ //if repo finds uenv, then set sqfs_path and break + const auto& r = *local_results.begin(); + sqfs_path = local_store->uenv_paths(r.sha).squashfs; + //printf("Uenv found in local repository: %s\n", repo.value_or("")); break; } } else{ - term::error("{}", "Error: uenv global config isn't a string"); + return unexpected( + fmt::format("Error: uenv local config isn't a string")); } } - if (global_results.empty()){ //if uenv couldn't be found in local or global repo + if (local_results.empty()){ //if uenv couldn't be found in local or local repo return unexpected(fmt::format("no uenv matches '{}'", *label)); } // ensure that all results share a unique sha - if (!global_results.unique_sha()) { + if (!local_results.unique_sha()) { auto errmsg = fmt::format( "more than one uenv matches the uenv description " "'{}':\n", desc.label().value()); - errmsg += format_record_set(global_results); + errmsg += format_record_set(local_results); return unexpected(errmsg); } } else { From 0e2d3e0a1244c2de2a4d62fc2d255ee73707359e Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 12:52:39 -0600 Subject: [PATCH 10/14] Change back to squashfuse option using squashfs-mount patch --- src/cli/run.cpp | 9 +++------ src/cli/start.cpp | 7 ++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/cli/run.cpp b/src/cli/run.cpp index 515719d1..a5ac8f61 100644 --- a/src/cli/run.cpp +++ b/src/cli/run.cpp @@ -75,15 +75,12 @@ You need to finish the current session by typing 'exit' or hitting ''.)" generate_environment(*env, globals.calling_environment, "SQFSMNT_FWD_"); // generate the mount list - std::vector commands = {}; + std::vector commands = {"squashfs-mount"}; if (use_squashfuse){ - commands.push_back("squashfs-mount-rootless"); + commands.push_back("--squashfuse"); } - else{ - commands.push_back("squashfs-mount"); - } - + for (auto e : env->uenvs) { commands.push_back(fmt::format("{}:{}", e.second.sqfs_path.string(), e.second.mount_path)); diff --git a/src/cli/start.cpp b/src/cli/start.cpp index 8ea94a07..0f8564be 100644 --- a/src/cli/start.cpp +++ b/src/cli/start.cpp @@ -118,13 +118,10 @@ will not work, because it starts a new interactive shell.)", generate_environment(*env, globals.calling_environment, "SQFSMNT_FWD_"); // generate the mount list - std::vector commands = {}; + std::vector commands = {"squashfs-mount"}; if (use_squashfuse){ - commands.push_back("squashfs-mount-rootless"); - } - else{ - commands.push_back("squashfs-mount"); + commands.push_back("--squashfuse"); } for (auto e : env->uenvs) { From 3531c4df653d47f60afc40d6a46bd951a62922f0 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 15:52:49 -0600 Subject: [PATCH 11/14] Add repo path validation for the local repos --- src/cli/ls.cpp | 15 ++++++++++++++- src/uenv/env.cpp | 17 +++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index 925e7549..26b3fad4 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -91,8 +91,21 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { // query the local repos for (auto& repo : config_repo){ if (repo.is_string()){//if repo is string, query - std::filesystem::path repo_path = repo.value_or(""); + std::string repo_path_string = repo.value_or(""); + + //validate local repo and skip if validation fails + if (auto rpath = + uenv::validate_repo_path(repo_path_string, false, false)) { + config.repo = path.value(); + } else { + spdlog::warn("invalid repo path {}", rpath.error()); + break; + } + + //open local repo if valid + std::filesystem::path repo_path = repo_path_string; auto local_store = uenv::open_repository(repo_path); + if (!local_store) { term::error("unable to open local repo: {}", local_store.error()); return 1; diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 059f1d56..01e059b2 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -177,8 +177,21 @@ concretise_env(const std::string& uenv_args, //recuse through uenv_local_repo array for (auto& repo : config_repo){ if (repo.is_string()){ //if repo is a string, then query - std::filesystem::path repo_path = repo.value_or(""); - const auto local_store = uenv::open_repository(repo_path); + std::string repo_path_string = repo.value_or(""); + + //validate local repo and skip if validation fails + if (auto rpath = + uenv::validate_repo_path(repo_path_string, false, false)) { + config.repo = path.value(); + } else { + spdlog::warn("invalid repo path {}", rpath.error()); + break; + } + + //open local repo if valid + std::filesystem::path repo_path = repo_path_string; + auto local_store = uenv::open_repository(repo_path); + const auto local_result = local_store->query(*label); local_results = *local_result; if (!local_results.empty()){ //if repo finds uenv, then set sqfs_path and break From f426dbe9148f69c65ce0e69e2e1b915c969c7992 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 15:56:55 -0600 Subject: [PATCH 12/14] Remove accidental code from copy and inverse validation statement --- src/cli/ls.cpp | 7 ++----- src/uenv/env.cpp | 7 ++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index 26b3fad4..f3588037 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -94,12 +94,9 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { std::string repo_path_string = repo.value_or(""); //validate local repo and skip if validation fails - if (auto rpath = - uenv::validate_repo_path(repo_path_string, false, false)) { - config.repo = path.value(); - } else { + if (!(auto rpath = uenv::validate_repo_path(repo_path_string, false, false))) { spdlog::warn("invalid repo path {}", rpath.error()); - break; + continue; } //open local repo if valid diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index 01e059b2..ef71b0be 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -180,12 +180,9 @@ concretise_env(const std::string& uenv_args, std::string repo_path_string = repo.value_or(""); //validate local repo and skip if validation fails - if (auto rpath = - uenv::validate_repo_path(repo_path_string, false, false)) { - config.repo = path.value(); - } else { + if (!(auto rpath = uenv::validate_repo_path(repo_path_string, false, false))) { spdlog::warn("invalid repo path {}", rpath.error()); - break; + continue; } //open local repo if valid From b678f034920b4407cb80c65e6f18bf612f564530 Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 16:03:21 -0600 Subject: [PATCH 13/14] Move valid local repo code inside validation if statement --- src/cli/ls.cpp | 37 +++++++++++++++++++------------------ src/uenv/env.cpp | 29 +++++++++++++++-------------- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/cli/ls.cpp b/src/cli/ls.cpp index f3588037..cf55e6c4 100644 --- a/src/cli/ls.cpp +++ b/src/cli/ls.cpp @@ -94,27 +94,28 @@ int image_ls(const image_ls_args& args, const global_settings& settings) { std::string repo_path_string = repo.value_or(""); //validate local repo and skip if validation fails - if (!(auto rpath = uenv::validate_repo_path(repo_path_string, false, false))) { + if (auto rpath = uenv::validate_repo_path(repo_path_string, false, false)) { + //open local repo if valid + std::filesystem::path repo_path = repo_path_string; + auto local_store = uenv::open_repository(repo_path); + + if (!local_store) { + term::error("unable to open local repo: {}", local_store.error()); + return 1; + } + + const auto local_result = local_store->query(label); + if (!local_result) { + term::error("invalid search term: {}", local_store.error()); + return 1; + } + printf("\nLocal Repository: %s\n", repo.value_or("")); + print_record_set(*local_result, args.no_header, args.json); //print local repo listing + + } else { spdlog::warn("invalid repo path {}", rpath.error()); continue; } - - //open local repo if valid - std::filesystem::path repo_path = repo_path_string; - auto local_store = uenv::open_repository(repo_path); - - if (!local_store) { - term::error("unable to open local repo: {}", local_store.error()); - return 1; - } - - const auto local_result = local_store->query(label); - if (!local_result) { - term::error("invalid search term: {}", local_store.error()); - return 1; - } - printf("\nLocal Repository: %s\n", repo.value_or("")); - print_record_set(*local_result, args.no_header, args.json); //print local repo listing } } diff --git a/src/uenv/env.cpp b/src/uenv/env.cpp index ef71b0be..0ae1b158 100644 --- a/src/uenv/env.cpp +++ b/src/uenv/env.cpp @@ -180,21 +180,22 @@ concretise_env(const std::string& uenv_args, std::string repo_path_string = repo.value_or(""); //validate local repo and skip if validation fails - if (!(auto rpath = uenv::validate_repo_path(repo_path_string, false, false))) { + if (auto rpath = uenv::validate_repo_path(repo_path_string, false, false)) { + + //open local repo if valid + std::filesystem::path repo_path = repo_path_string; + auto local_store = uenv::open_repository(repo_path); + + const auto local_result = local_store->query(*label); + local_results = *local_result; + if (!local_results.empty()){ //if repo finds uenv, then set sqfs_path and break + const auto& r = *local_results.begin(); + sqfs_path = local_store->uenv_paths(r.sha).squashfs; + //printf("Uenv found in local repository: %s\n", repo.value_or("")); + break; + } + } else { spdlog::warn("invalid repo path {}", rpath.error()); - continue; - } - - //open local repo if valid - std::filesystem::path repo_path = repo_path_string; - auto local_store = uenv::open_repository(repo_path); - - const auto local_result = local_store->query(*label); - local_results = *local_result; - if (!local_results.empty()){ //if repo finds uenv, then set sqfs_path and break - const auto& r = *local_results.begin(); - sqfs_path = local_store->uenv_paths(r.sha).squashfs; - //printf("Uenv found in local repository: %s\n", repo.value_or("")); break; } } From d9782b331cd5ecea11469e217ea331461c6b7e8d Mon Sep 17 00:00:00 2001 From: brubinstein Date: Thu, 17 Jul 2025 16:10:53 -0600 Subject: [PATCH 14/14] Activate.sh source for uenv_configuration_path variable --- activate.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 activate.sh diff --git a/activate.sh b/activate.sh new file mode 100644 index 00000000..89b2af48 --- /dev/null +++ b/activate.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +export UENV_CONFIGURATION_PATH=$(realpath .)/configuration.toml \ No newline at end of file