Skip to content

Commit 32a646f

Browse files
chaserhkjcgwalters
authored andcommitted
Help text improvement for cfsctl
- Bump clap version to enable "wrap_help" feature for better terminal visibility Signed-off-by: Chaser Huang <huangkangjing@gmail.com> Signed-off-by: Colin Walters <walters@verbum.org>
1 parent 1ae5ab8 commit 32a646f

2 files changed

Lines changed: 105 additions & 38 deletions

File tree

crates/cfsctl/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ rhel9 = ['composefs/rhel9']
2020
[dependencies]
2121
anyhow = { version = "1.0.87", default-features = false }
2222
fn-error-context = "0.2"
23-
clap = { version = "4.0.1", default-features = false, features = ["std", "help", "usage", "derive"] }
23+
clap = { version = "4.5.0", default-features = false, features = ["std", "help", "usage", "derive", "wrap_help"] }
2424
composefs = { workspace = true }
2525
composefs-boot = { workspace = true }
2626
composefs-oci = { workspace = true, optional = true }

crates/cfsctl/src/main.rs

Lines changed: 104 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ use composefs::{
2626
#[derive(Debug, Parser)]
2727
#[clap(name = "cfsctl", version)]
2828
pub struct App {
29+
/// Operate on repo at path
2930
#[clap(long, group = "repopath")]
3031
repo: Option<PathBuf>,
32+
/// Operate on repo at standard user location $HOME/.var/lib/composefs
3133
#[clap(long, group = "repopath")]
3234
user: bool,
35+
/// Operate on repo at standard system location /sysroot/composefs
3336
#[clap(long, group = "repopath")]
3437
system: bool,
3538

@@ -54,58 +57,91 @@ enum HashType {
5457
Sha512,
5558
}
5659

60+
/// Common options for operations using OCI config manifest streams that may transform the image rootfs
61+
#[derive(Debug, Parser)]
62+
struct OCIConfigFilesystemOptions {
63+
#[clap(flatten)]
64+
base_config: OCIConfigOptions,
65+
/// Whether bootable transformation should be performed on the image rootfs
66+
#[clap(long)]
67+
bootable: bool,
68+
}
69+
70+
/// Common options for operations using OCI config manifest streams
71+
#[derive(Debug, Parser)]
72+
struct OCIConfigOptions {
73+
/// the name of the target OCI manifest stream, either a stream ID in format oci-config-<hash_type>:<hash_digest> or a reference in 'ref/'
74+
config_name: String,
75+
/// verity digest for the manifest stream to be verified against
76+
config_verity: Option<String>,
77+
}
78+
5779
#[cfg(feature = "oci")]
5880
#[derive(Debug, Subcommand)]
5981
enum OciCommand {
60-
/// Stores a tar file as a splitstream in the repository.
82+
/// Stores a tar layer file as a splitstream in the repository.
6183
ImportLayer {
6284
digest: String,
6385
name: Option<String>,
6486
},
6587
/// Lists the contents of a tar stream
6688
LsLayer {
67-
/// the name of the stream
89+
/// the name of the stream to list, either a stream ID in format oci-config-<hash_type>:<hash_digest> or a reference in 'ref/'
6890
name: String,
6991
},
92+
/// Dump full content of the rootfs of a stored OCI image to a composefs dumpfile and write to stdout
7093
Dump {
71-
config_name: String,
72-
config_verity: Option<String>,
73-
#[clap(long)]
74-
bootable: bool,
94+
#[clap(flatten)]
95+
config_opts: OCIConfigFilesystemOptions,
7596
},
97+
/// Pull an OCI image to be stored in repo then prints the stream and verity digest of its manifest
7698
Pull {
99+
/// source image reference, as accepted by skopeo
77100
image: String,
101+
/// optional reference name for the manifest, use as 'ref/<name>' elsewhere
78102
name: Option<String>,
79103
},
104+
/// Compute the composefs image object id of the rootfs of a stored OCI image
80105
ComputeId {
81-
config_name: String,
82-
config_verity: Option<String>,
83-
#[clap(long)]
84-
bootable: bool,
106+
#[clap(flatten)]
107+
config_opts: OCIConfigFilesystemOptions,
85108
},
109+
/// Create the composefs image of the rootfs of a stored OCI image, commit it to the repo, and print its image object ID
86110
CreateImage {
87-
config_name: String,
88-
config_verity: Option<String>,
89-
#[clap(long)]
90-
bootable: bool,
111+
#[clap(flatten)]
112+
config_opts: OCIConfigFilesystemOptions,
113+
/// optional reference name for the image, use as 'ref/<name>' elsewhere
91114
#[clap(long)]
92115
image_name: Option<String>,
93116
},
117+
/// Seal a stored OCI image by creating a cloned manifest with embedded verity digest (a.k.a. composefs image object ID)
118+
/// in the repo, then prints the stream and verity digest of the new sealed manifest
94119
Seal {
95-
config_name: String,
96-
config_verity: Option<String>,
120+
#[clap(flatten)]
121+
config_opts: OCIConfigOptions,
97122
},
123+
/// Mounts a stored and sealed OCI image by looking up its composefs image. Note that the composefs image must be built
124+
/// and committed to the repo first
98125
Mount {
126+
/// the name of the target OCI manifest stream, either a stream ID in format oci-config-<hash_type>:<hash_digest> or a reference in 'ref/'
99127
name: String,
128+
/// the mountpoint
100129
mountpoint: String,
101130
},
131+
/// Create the composefs image of the rootfs of a stored OCI image, perform bootable transformation, commit it to the repo,
132+
/// then configure boot for the image by writing new boot resources and bootloader entries to boot partition. Performs
133+
/// state preparation for composefs-setup-root consumption as well. Note that state preparation here is not suitable for
134+
/// consumption by bootc.
102135
PrepareBoot {
103-
config_name: String,
104-
config_verity: Option<String>,
136+
#[clap(flatten)]
137+
config_opts: OCIConfigOptions,
138+
/// boot partition mount point
105139
#[clap(long, default_value = "/boot")]
106140
bootdir: PathBuf,
141+
/// Boot entry identifier to use. By default uses ID provided by the image or kernel version
107142
#[clap(long)]
108143
entry_id: Option<String>,
144+
/// additional kernel command line
109145
#[clap(long)]
110146
cmdline: Vec<String>,
111147
},
@@ -145,37 +181,44 @@ enum Command {
145181
},
146182
/// Imports a composefs image (unsafe!)
147183
ImportImage { reference: String },
148-
/// Commands for dealing with OCI layers
184+
/// Commands for dealing with OCI images and layers
149185
#[cfg(feature = "oci")]
150186
Oci {
151187
#[clap(subcommand)]
152188
cmd: OciCommand,
153189
},
154-
/// Mounts a composefs, possibly enforcing fsverity of the image
190+
/// Mounts a composefs image, possibly enforcing fsverity of the image
155191
Mount {
156192
/// the name of the image to mount, either an fs-verity hash or prefixed with 'ref/'
157193
name: String,
158194
/// the mountpoint
159195
mountpoint: String,
160196
},
161-
/// Creates a composefs image from a filesystem
197+
/// Read rootfs located at a path, add all files to the repo, then create the composefs image of the rootfs,
198+
/// commit it to the repo, and print its image object ID
162199
CreateImage {
163200
#[clap(flatten)]
164201
fs_opts: FsReadOptions,
202+
/// optional reference name for the image, use as 'ref/<name>' elsewhere
165203
image_name: Option<String>,
166204
},
167-
/// Computes the composefs image ID for a filesystem
205+
/// Read rootfs located at a path, add all files to the repo, then compute the composefs image object id of the rootfs.
206+
/// Note that this does not create or commit the composefs image itself.
168207
ComputeId {
169208
#[clap(flatten)]
170209
fs_opts: FsReadOptions,
171210
},
172-
/// Outputs the composefs dumpfile format for a filesystem
211+
/// Read rootfs located at a path, add all files to the repo, then dump full content of the rootfs to a composefs dumpfile
212+
/// and write to stdout.
173213
CreateDumpfile {
174214
#[clap(flatten)]
175215
fs_opts: FsReadOptions,
176216
},
177217
/// Lists all object IDs referenced by an image
178-
ImageObjects { name: String },
218+
ImageObjects {
219+
/// the name of the image to read, either an object ID digest or prefixed with 'ref/'
220+
name: String,
221+
},
179222
#[cfg(feature = "http")]
180223
Fetch { url: String, name: String },
181224
}
@@ -256,9 +299,15 @@ where
256299
composefs_oci::ls_layer(&repo, &name)?;
257300
}
258301
OciCommand::Dump {
259-
ref config_name,
260-
ref config_verity,
261-
bootable,
302+
config_opts:
303+
OCIConfigFilesystemOptions {
304+
base_config:
305+
OCIConfigOptions {
306+
ref config_name,
307+
ref config_verity,
308+
},
309+
bootable,
310+
},
262311
} => {
263312
let verity = verity_opt(config_verity)?;
264313
let mut fs =
@@ -269,9 +318,15 @@ where
269318
fs.print_dumpfile()?;
270319
}
271320
OciCommand::ComputeId {
272-
ref config_name,
273-
ref config_verity,
274-
bootable,
321+
config_opts:
322+
OCIConfigFilesystemOptions {
323+
base_config:
324+
OCIConfigOptions {
325+
ref config_name,
326+
ref config_verity,
327+
},
328+
bootable,
329+
},
275330
} => {
276331
let verity = verity_opt(config_verity)?;
277332
let mut fs =
@@ -283,9 +338,15 @@ where
283338
println!("{}", id.to_hex());
284339
}
285340
OciCommand::CreateImage {
286-
ref config_name,
287-
ref config_verity,
288-
bootable,
341+
config_opts:
342+
OCIConfigFilesystemOptions {
343+
base_config:
344+
OCIConfigOptions {
345+
ref config_name,
346+
ref config_verity,
347+
},
348+
bootable,
349+
},
289350
ref image_name,
290351
} => {
291352
let verity = verity_opt(config_verity)?;
@@ -305,8 +366,11 @@ where
305366
println!("verity {}", verity.to_hex());
306367
}
307368
OciCommand::Seal {
308-
ref config_name,
309-
ref config_verity,
369+
config_opts:
370+
OCIConfigOptions {
371+
ref config_name,
372+
ref config_verity,
373+
},
310374
} => {
311375
let verity = verity_opt(config_verity)?;
312376
let (digest, verity) =
@@ -321,8 +385,11 @@ where
321385
composefs_oci::mount(&repo, name, mountpoint, None)?;
322386
}
323387
OciCommand::PrepareBoot {
324-
ref config_name,
325-
ref config_verity,
388+
config_opts:
389+
OCIConfigOptions {
390+
ref config_name,
391+
ref config_verity,
392+
},
326393
ref bootdir,
327394
ref entry_id,
328395
ref cmdline,

0 commit comments

Comments
 (0)