use clap::{Parser, Subcommand, Args}; #[derive(Parser)] #[command(name = "apt-ostree")] #[command(about = "Debian/Ubuntu equivalent of rpm-ostree")] #[command(version = "0.1.0")] #[command(propagate_version = true)] pub struct Cli { #[command(subcommand)] pub command: Commands, } #[derive(Subcommand)] pub enum Commands { /// Get the version of the booted system Status(StatusArgs), /// Perform a system upgrade Upgrade(UpgradeArgs), /// Revert to the previously booted tree Rollback(RollbackArgs), /// Deploy a specific commit Deploy(DeployArgs), /// Switch to a different tree Rebase(RebaseArgs), /// Overlay additional packages Install(InstallArgs), /// Remove overlayed additional packages Uninstall(UninstallArgs), /// Search for packages Search(SearchArgs), /// Enable or disable local initramfs regeneration Initramfs(InitramfsArgs), /// Add files to the initramfs InitramfsEtc(InitramfsEtcArgs), /// Query or modify kernel arguments Kargs(KargsArgs), /// Reload configuration Reload(ReloadArgs), /// Cancel an active transaction Cancel(CancelArgs), /// Manage active transactions Transaction(TransactionArgs), /// Commands to compose a tree Compose(ComposeArgs), /// Commands to query the package database Db(DbArgs), /// Manage base package overrides Override(OverrideArgs), /// Remove all mutations Reset(ResetArgs), /// Generate package repository metadata RefreshMd(RefreshMdArgs), /// Apply pending deployment changes to booted deployment ApplyLive(ApplyLiveArgs), /// Apply a transient overlayfs to /usr Usroverlay(UsroverlayArgs), /// Clear cached/pending data Cleanup(CleanupArgs), /// Unset the finalization locking state and reboot FinalizeDeployment(FinalizeDeploymentArgs), /// Display system metrics and performance information Metrics(MetricsArgs), /// Start the daemon StartDaemon(StartDaemonArgs), /// Experimental features Ex(ExArgs), /// Telemetry and usage statistics Countme(CountmeArgs), /// Container management Container(ContainerArgs), /// Development and debugging tools (hidden) #[command(hide = true)] Testutils(TestutilsArgs), /// Shared library backend (hidden) #[command(hide = true)] ShlibBackend(ShlibBackendArgs), /// Internal system commands (hidden) #[command(hide = true)] Internals(InternalsArgs), } #[derive(Args)] pub struct StatusArgs { /// Pretty print output #[arg(short, long)] pub pretty: bool, /// Verbose output #[arg(short, long)] pub verbose: bool, /// Output JSON #[arg(long)] pub json: bool, } #[derive(Args)] pub struct UpgradeArgs { /// Initiate a reboot after operation is complete #[arg(short, long)] pub reboot: bool, /// Just preview package differences (implies --unchanged-exit-77) #[arg(long)] pub preview: bool, /// Just check if an upgrade is available (implies --unchanged-exit-77) #[arg(long)] pub check: bool, /// Do not download latest ostree and APT data #[arg(short, long)] pub cache_only: bool, /// Just download latest ostree and APT data, don't deploy #[arg(long)] pub download_only: bool, /// If no new deployment made, exit 77 #[arg(long)] pub unchanged_exit_77: bool, /// Overlay additional packages #[arg(long, value_delimiter = ',')] pub install: Vec, /// Remove overlayed additional packages #[arg(long, value_delimiter = ',')] pub uninstall: Vec, /// Additional packages to install #[arg(long)] pub packages: Vec, } #[derive(Args)] pub struct RollbackArgs { /// Initiate a reboot after operation #[arg(short, long)] pub reboot: bool, /// Exit 77 if unchanged #[arg(long)] pub unchanged_exit_77: bool, /// Deploy index to rollback to #[arg(long)] pub deploy_index: Option, } #[derive(Args)] pub struct DeployArgs { /// Commit to deploy pub commit: String, /// Initiate a reboot after operation #[arg(short, long)] pub reboot: bool, /// Lock finalization #[arg(long)] pub lock_finalization: bool, } #[derive(Args)] pub struct RebaseArgs { /// Target tree to rebase to pub target: String, /// Initiate a reboot after operation #[arg(short, long)] pub reboot: bool, /// Lock finalization #[arg(long)] pub lock_finalization: bool, } #[derive(Args)] pub struct InstallArgs { /// Packages to install pub packages: Vec, /// Initiate a reboot after operation #[arg(short, long)] pub reboot: bool, /// Lock finalization #[arg(long)] pub lock_finalization: bool, } #[derive(Args)] pub struct UninstallArgs { /// Packages to remove pub packages: Vec, /// Initiate a reboot after operation #[arg(short, long)] pub reboot: bool, /// Lock finalization #[arg(long)] pub lock_finalization: bool, } #[derive(Args)] pub struct SearchArgs { /// Search query pub query: String, /// Search in installed packages #[arg(long)] pub installed: bool, /// Search in available packages #[arg(long)] pub available: bool, /// Output format #[arg(long, default_value = "text")] pub format: String, } #[derive(Args)] pub struct InitramfsArgs { /// Enable local initramfs regeneration #[arg(long)] pub enable: bool, /// Disable local initramfs regeneration #[arg(long)] pub disable: bool, /// Initiate a reboot after operation #[arg(short, long)] pub reboot: bool, } #[derive(Args)] pub struct InitramfsEtcArgs { /// Add files to initramfs #[arg(long)] pub add: Vec, /// Remove files from initramfs #[arg(long)] pub remove: Vec, /// List files in initramfs #[arg(long)] pub list: bool, } #[derive(Args)] pub struct KargsArgs { /// Initiate a reboot after operation #[arg(long)] pub reboot: bool, /// Lock finalization #[arg(long)] pub lock_finalization: bool, /// Exit 77 if unchanged #[arg(long)] pub unchanged_exit_77: bool, /// Import from /proc/cmdline #[arg(long)] pub import_proc_cmdline: bool, /// Use editor mode #[arg(long)] pub editor: bool, /// Deploy index #[arg(long)] pub deploy_index: Option, /// Append kernel arguments #[arg(long, value_delimiter = ',')] pub append: Vec, /// Replace kernel arguments #[arg(long, value_delimiter = ',')] pub replace: Vec, /// Delete kernel arguments #[arg(long, value_delimiter = ',')] pub delete: Vec, } #[derive(Args)] pub struct ReloadArgs { /// Reload configuration #[arg(long)] pub config: bool, /// Reload daemon #[arg(long)] pub daemon: bool, } #[derive(Args)] pub struct CancelArgs { /// Transaction ID to cancel pub transaction_id: Option, } #[derive(Args)] pub struct TransactionArgs { #[command(subcommand)] pub subcommand: TransactionSubcommands, } #[derive(Subcommand)] pub enum TransactionSubcommands { /// List active transactions List, /// Show transaction details Show { transaction_id: String }, /// Wait for transaction completion Wait { transaction_id: String }, } #[derive(Args)] pub struct ComposeArgs { #[command(subcommand)] pub subcommand: ComposeSubcommands, } #[derive(Subcommand)] pub enum ComposeSubcommands { /// Process a "treefile"; install packages and commit the result to an OSTree repository Tree { /// Path to treefile treefile: String, /// Path to OSTree repository #[arg(short, long)] repo: Option, /// Path to OSTree repository for ostree-layers and ostree-override-layers #[arg(long)] layer_repo: Option, /// Always create a new OSTree commit, even if nothing appears to have changed #[arg(long)] force_nocache: bool, /// Assume cache is present, do not attempt to update it #[arg(long)] cache_only: bool, /// Cached state #[arg(long)] cachedir: Option, /// Rootfs to use for configuring libdnf #[arg(long)] source_root: Option, /// Like --dry-run, but download and import RPMs as well; requires --cachedir #[arg(long)] download_only: bool, /// Like --dry-run, but download RPMs as well; requires --cachedir #[arg(long)] download_only_rpms: bool, /// HTTP proxy #[arg(long)] proxy: Option, /// Just print the transaction and exit #[arg(long)] dry_run: bool, /// Just expand any includes and print treefile #[arg(long)] print_only: bool, /// Disable SELinux labeling, even if manifest enables it #[arg(long)] disable_selinux: bool, /// Update the modification time on FILE if a new commit was created #[arg(long)] touch_if_changed: Option, /// Use this commit for change detection #[arg(long)] previous_commit: Option, /// Use this input hash for change detection #[arg(long)] previous_inputhash: Option, /// Use this version number for automatic version numbering #[arg(long)] previous_version: Option, /// Working directory #[arg(long)] workdir: Option, /// Also run default postprocessing #[arg(long)] postprocess: bool, /// Write lockfile to FILE #[arg(long)] ex_write_lockfile_to: Option, /// Read lockfile from FILE #[arg(long)] ex_lockfile: Option, /// With --ex-lockfile, only allow installing locked packages #[arg(long)] ex_lockfile_strict: bool, /// Append given key and value (in string format) to metadata #[arg(long)] add_metadata_string: Vec, /// Parse the given JSON file as object, convert to GVariant, append to OSTree commit #[arg(long)] add_metadata_from_json: Option, /// File to write the composed commitid to instead of updating the ref #[arg(long)] write_commitid_to: Option, /// Write JSON to FILE containing information about the compose run #[arg(long)] write_composejson_to: Option, /// Always commit without a parent #[arg(long)] no_parent: bool, /// Commit with specific parent #[arg(long)] parent: Option, /// Enable verbose output #[arg(long)] verbose: bool, /// Generate container image #[arg(long)] container: bool, }, /// Install packages into a target path Install { /// Path to treefile treefile: String, /// Destination directory destdir: String, /// Path to OSTree repository #[arg(short, long)] repo: Option, /// Path to OSTree repository for ostree-layers and ostree-override-layers #[arg(long)] layer_repo: Option, /// Always create a new OSTree commit, even if nothing appears to have changed #[arg(long)] force_nocache: bool, /// Assume cache is present, do not attempt to update it #[arg(long)] cache_only: bool, /// Cached state #[arg(long)] cachedir: Option, /// Rootfs to use for configuring libdnf #[arg(long)] source_root: Option, /// Like --dry-run, but download and import RPMs as well; requires --cachedir #[arg(long)] download_only: bool, /// Like --dry-run, but download RPMs as well; requires --cachedir #[arg(long)] download_only_rpms: bool, /// HTTP proxy #[arg(long)] proxy: Option, /// Just print the transaction and exit #[arg(long)] dry_run: bool, /// Just expand any includes and print treefile #[arg(long)] print_only: bool, /// Disable SELinux labeling, even if manifest enables it #[arg(long)] disable_selinux: bool, /// Update the modification time on FILE if a new commit was created #[arg(long)] touch_if_changed: Option, /// Use this commit for change detection #[arg(long)] previous_commit: Option, /// Use this input hash for change detection #[arg(long)] previous_inputhash: Option, /// Use this version number for automatic version numbering #[arg(long)] previous_version: Option, /// Working directory #[arg(long)] workdir: Option, /// Also run default postprocessing #[arg(long)] postprocess: bool, /// Write lockfile to FILE #[arg(long)] ex_write_lockfile_to: Option, /// Read lockfile from FILE #[arg(long)] ex_lockfile: Option, /// With --ex-lockfile, only allow installing locked packages #[arg(long)] ex_lockfile_strict: bool, }, /// Perform final postprocessing on an installation root Postprocess { /// Path to rootfs rootfs: String, /// Path to treefile (optional) treefile: Option, }, /// Commit a target path to an OSTree repository Commit { /// Path to treefile treefile: String, /// Path to rootfs rootfs: String, /// Path to OSTree repository #[arg(short, long)] repo: Option, /// Path to OSTree repository for ostree-layers and ostree-override-layers #[arg(long)] layer_repo: Option, /// Use new "unified core" codepath #[arg(long)] unified_core: bool, /// Append given key and value (in string format) to metadata #[arg(long)] add_metadata_string: Vec, /// Parse the given JSON file as object, convert to GVariant, append to OSTree commit #[arg(long)] add_metadata_from_json: Option, /// File to write the composed commitid to instead of updating the ref #[arg(long)] write_commitid_to: Option, /// Write JSON to FILE containing information about the compose run #[arg(long)] write_composejson_to: Option, /// Always commit without a parent #[arg(long)] no_parent: bool, /// Commit with specific parent #[arg(long)] parent: Option, }, /// Download packages guaranteed to depsolve with a base OSTree Extensions { /// Path to treefile treefile: String, /// Path to extensions YAML file extyaml: String, /// Path to OSTree repository #[arg(short, long)] repo: Option, /// Path to OSTree repository for ostree-layers and ostree-override-layers #[arg(long)] layer_repo: Option, /// Use new "unified core" codepath #[arg(long)] unified_core: bool, /// Path to extensions output directory #[arg(long)] output_dir: Option, /// Base OSTree revision #[arg(long)] base_rev: Option, /// Cached state #[arg(long)] cachedir: Option, /// Path to already present rootfs #[arg(long)] rootfs: Option, /// Update the modification time on FILE if new extensions were downloaded #[arg(long)] touch_if_changed: Option, }, /// Generate a reproducible "chunked" container image (using RPM data) from a treefile Image { /// Path to the manifest file manifest: String, /// Target path to write output: String, /// Directory to use for caching downloaded packages and other data #[arg(long)] cachedir: Option, /// Rootfs to use for resolving package system configuration #[arg(long)] source_root: Option, /// Container authentication file #[arg(long)] authfile: Option, /// OSTree repository to use for ostree-layers and ostree-override-layers #[arg(long)] layer_repo: Option, /// Do not query previous image in target location; use this for the first build #[arg(short, long)] initialize: bool, /// Control conditions under which the image is written #[arg(long, default_value = "query")] initialize_mode: Option, /// Output format #[arg(long, default_value = "ociarchive")] format: Option, /// Force a build #[arg(long)] force_nocache: bool, /// Operate only on cached data, do not access network repositories #[arg(long)] offline: bool, /// Path to write a JSON-formatted lockfile #[arg(long)] write_lockfile_to: Option, /// JSON-formatted lockfile; can be specified multiple times #[arg(long)] lockfile: Vec, /// With --lockfile, only allow installing locked packages #[arg(long)] lockfile_strict: bool, /// Additional labels for the container image, in KEY=VALUE format #[arg(short, long)] label: Vec, /// Path to container image configuration in JSON format #[arg(long)] image_config: Option, /// Update the timestamp or create this file on changes #[arg(long)] touch_if_changed: Option, /// Number of times to retry copying an image to remote destination #[arg(long)] copy_retry_times: Option, /// Maximum number of layers to use #[arg(long)] max_layers: Option, }, /// Generate a root filesystem tree from a treefile Rootfs { /// Path to the input manifest manifest: String, /// Path to the target root filesystem tree dest: String, /// Directory to use for caching downloaded packages and other data #[arg(long)] cachedir: Option, /// Source root for package system configuration #[arg(long)] source_root: Option, /// Rootfs to use for resolving package system configuration #[arg(long)] source_root_rw: Option, }, /// Generate a "chunked" OCI archive from an input rootfs BuildChunkedOci { /// Path to the source root filesystem tree #[arg(long)] rootfs: Option, /// Use the provided image (in containers-storage) #[arg(long)] from: Option, /// If set, configure the output OCI image to be a bootc container #[arg(long)] bootc: bool, /// The format version #[arg(long, default_value = "1")] format_version: Option, /// Maximum number of layers to use #[arg(long)] max_layers: Option, /// Tag to use for output image, or latest if unset #[arg(long, default_value = "latest")] reference: Option, /// Output image reference, in TRANSPORT:TARGET syntax #[arg(long)] output: String, }, /// Generate a reproducible "chunked" container image (using RPM data) from an OSTree commit ContainerEncapsulate { /// OSTree branch name or checksum ostree_ref: String, /// Image reference, e.g. registry:quay.io/exampleos/exampleos:latest imgref: String, /// Path to OSTree repository #[arg(long)] repo: Option, /// Additional labels for the container #[arg(short, long)] label: Vec, /// Path to container image configuration in JSON format #[arg(long)] image_config: Option, /// Override the architecture #[arg(long)] arch: Option, /// Propagate an OSTree commit metadata key to container label #[arg(long)] copymeta: Vec, /// Propagate an optionally-present OSTree commit metadata key to container label #[arg(long)] copymeta_opt: Vec, /// Corresponds to the Dockerfile CMD instruction #[arg(long)] cmd: Option, /// Maximum number of container image layers #[arg(long)] max_layers: Option, /// The encapsulated container format version; must be 1 or 2 #[arg(long, default_value = "1")] format_version: Option, /// Output content metadata as JSON #[arg(long)] write_contentmeta_json: Option, /// Compare OCI layers of current build with another(imgref) #[arg(long)] compare_with_build: Option, /// Prevent a change in packing structure by taking a previous build metadata #[arg(long)] previous_build_manifest: Option, }, } #[derive(Args)] pub struct DbArgs { #[command(subcommand)] pub subcommand: DbSubcommands, } #[derive(Subcommand)] pub enum DbSubcommands { /// List packages List, /// Show package info Info { /// Package name to get info for package: String }, /// Search packages Search { /// Search query query: String }, /// Show package dependencies Depends { /// Package name to get dependencies for package: String }, /// Install packages into a target path Install { /// Packages to install packages: Vec, /// Target path for installation #[arg(long, default_value = "/")] target: String, /// Repository to use #[arg(long)] repo: Option, }, /// Remove packages from a target path Remove { /// Packages to remove packages: Vec, /// Target path for removal #[arg(long, default_value = "/")] target: String, /// Repository to use #[arg(long)] repo: Option, }, } #[derive(Args)] pub struct OverrideArgs { #[command(subcommand)] pub subcommand: OverrideSubcommands, } #[derive(Subcommand)] pub enum OverrideSubcommands { /// Add package override Add { package: String }, /// Remove package override Remove { package: String }, /// List package overrides List, } #[derive(Args)] pub struct ResetArgs { /// Reset to base deployment #[arg(long)] pub base: bool, /// Reset all mutations #[arg(long)] pub all: bool, } #[derive(Args)] pub struct RefreshMdArgs { /// Force refresh #[arg(short, long)] pub force: bool, /// Dry run #[arg(long)] pub dry_run: bool, } #[derive(Args)] pub struct ApplyLiveArgs { /// Apply changes immediately #[arg(long)] pub immediate: bool, /// Reboot after applying #[arg(short, long)] pub reboot: bool, } #[derive(Args)] pub struct UsroverlayArgs { /// Overlay directory pub directory: String, /// Mount point #[arg(long)] pub mount_point: Option, } #[derive(Args)] pub struct CleanupArgs { /// Clean cache #[arg(long)] pub cache: bool, /// Clean pending data #[arg(long)] pub pending: bool, /// Clean all #[arg(long)] pub all: bool, } #[derive(Args)] pub struct FinalizeDeploymentArgs { /// Reboot after finalization #[arg(short, long)] pub reboot: bool, } #[derive(Args)] pub struct MetricsArgs { /// Show system metrics #[arg(long)] pub system: bool, /// Show performance metrics #[arg(long)] pub performance: bool, /// Show all metrics #[arg(long)] pub all: bool, } #[derive(Args)] pub struct StartDaemonArgs { /// Debug mode #[arg(short, long)] pub debug: bool, /// System root path #[arg(long, default_value = "/")] pub sysroot: String, } #[derive(Args)] pub struct ExArgs { #[command(subcommand)] pub subcommand: ExSubcommands, } #[derive(Subcommand)] pub enum ExSubcommands { /// Unpack OSTree commit Unpack { commit: String, destination: String, #[arg(long)] force: bool, }, /// Show history History { #[arg(long)] verbose: bool, }, /// Manage initramfs /etc InitramfsEtc { #[arg(long)] add: Vec, #[arg(long)] remove: Vec, }, /// Manage modules Module { #[arg(long)] enable: String, #[arg(long)] disable: String, }, /// Rebuild system Rebuild { #[arg(long)] force: bool, }, /// Deploy from self DeployFromSelf { #[arg(long)] force: bool, }, } #[derive(Args)] pub struct CountmeArgs { /// Force countme #[arg(short, long)] pub force: bool, /// Dry run #[arg(long)] pub dry_run: bool, /// Verbose output #[arg(short, long)] pub verbose: bool, } #[derive(Args)] pub struct ContainerArgs { #[command(subcommand)] pub subcommand: ContainerSubcommands, } #[derive(Subcommand)] pub enum ContainerSubcommands { /// Install container Install { image: String }, /// Uninstall container Uninstall { name: String }, /// List containers List, /// Show container info Info { name: String }, } #[derive(Args)] pub struct TestutilsArgs { #[command(subcommand)] pub subcommand: TestutilsSubcommands, } #[derive(Subcommand)] pub enum TestutilsSubcommands { /// Inject package list metadata into OSTree commits InjectPkglist(InjectPkglistArgs), /// Run scripts in bubblewrap containers ScriptShell(ScriptShellArgs), /// Generate synthetic OS updates by modifying ELF files GenerateSyntheticUpgrade(GenerateSyntheticUpgradeArgs), /// Run integration tests on booted machine IntegrationReadOnly, /// Run C unit tests CUnits, /// Test command for development verification Moo, } #[derive(Args)] pub struct InjectPkglistArgs { /// Repository path pub repo: String, /// OSTree reference pub refspec: String, } #[derive(Args)] pub struct ScriptShellArgs { /// Script or command to execute pub script: String, /// Arguments for the script pub args: Vec, /// Root path for script execution #[arg(long, default_value = "/")] pub rootpath: String, /// Run in read-only mode #[arg(long)] pub read_only: bool, /// User to run as #[arg(long)] pub user: Option, /// Group to run as #[arg(long)] pub group: Option, /// Working directory #[arg(long)] pub cwd: Option, /// Environment variables (format: KEY=VALUE) #[arg(long)] pub env: Vec, } #[derive(Args)] pub struct GenerateSyntheticUpgradeArgs { /// Repository path #[arg(long)] pub repo: String, /// Source reference #[arg(long = "srcref")] pub src_ref: Option, /// OSTree reference #[arg(long = "ref")] pub ostref: String, /// Percentage of binaries to modify #[arg(long, default_value = "30")] pub percentage: u32, /// Commit version #[arg(long)] pub commit_version: Option, } #[derive(Args)] pub struct ShlibBackendArgs { #[command(subcommand)] pub subcommand: ShlibBackendSubcommands, } #[derive(Subcommand)] pub enum ShlibBackendSubcommands { /// Get base architecture GetBasearch, /// Variable substitution for architecture VarsubstBasearch { /// Source string for substitution source: String, }, /// Extract package list from OSTree commit PackagelistFromCommit { /// Commit hash commit: String, }, } #[derive(Args)] pub struct InternalsArgs { #[command(subcommand)] pub subcommand: InternalsSubcommands, } #[derive(Subcommand)] pub enum InternalsSubcommands { /// Internal system diagnostics Diagnostics, /// System state validation ValidateState, /// Debug information dump DebugDump, }