@@ -17,6 +17,7 @@ use fn_error_context::context;
17
17
use ostree:: gio;
18
18
use ostree_container:: store:: PrepareResult ;
19
19
use ostree_ext:: container as ostree_container;
20
+ use ostree_ext:: container:: Transport ;
20
21
use ostree_ext:: keyfileext:: KeyFileExt ;
21
22
use ostree_ext:: ostree;
22
23
@@ -191,6 +192,59 @@ pub(crate) enum ContainerOpts {
191
192
Lint ,
192
193
}
193
194
195
+ /// Subcommands which operate on images.
196
+ #[ derive( Debug , clap:: Subcommand , PartialEq , Eq ) ]
197
+ pub ( crate ) enum ImageOpts {
198
+ /// List fetched images stored in the bootc storage.
199
+ ///
200
+ /// Note that these are distinct from images stored via e.g. `podman`.
201
+ List ,
202
+ /// Copy a container image from the bootc storage to a target.
203
+ ///
204
+ /// ## Copying the booted container image to containers-storage: (podman)
205
+ ///
206
+ /// The source and target are both optional; if both are left unspecified,
207
+ /// via a simple invocation of `bootc image push`, then the default is to
208
+ /// push the currently booted image to `containers-storage` (as used by podman, etc.)
209
+ /// and tagged with the image name `localhost/bootc`,
210
+ ///
211
+ /// ## Copying the booted container image to a remote registry
212
+ ///
213
+ /// Aside from the special case above, default transport is `registry`. This
214
+ /// means that an invocation of
215
+ ///
216
+ /// `bootc image push --target quay.io/example/someimage:latest` will push the
217
+ /// booted container image to the target registry. This will be done via an
218
+ /// invocation equivalent to `skopeo copy`, and hence the defaults for that apply.
219
+ /// For example, the default registry authentication file applies.
220
+ ///
221
+ /// ## Copying a non-default container image
222
+ ///
223
+ /// It is also possible to copy an image other than the currently booted one by
224
+ /// specifying `--source`.
225
+ ///
226
+ /// ## Pulling images
227
+ ///
228
+ /// At the current time there is no explicit support for pulling images other than indirectly
229
+ /// via e.g. `bootc switch` or `bootc upgrade`.
230
+ Push {
231
+ /// The transport; e.g. oci, oci-archive, containers-storage. Defaults to `registry`.
232
+ ///
233
+ /// For more information, see `man containers-transports`.
234
+ #[ clap( long, default_value = "registry" ) ]
235
+ transport : String ,
236
+
237
+ #[ clap( long) ]
238
+ /// The source image; if not specified, the booted image will be used.
239
+ source : Option < String > ,
240
+
241
+ #[ clap( long) ]
242
+ /// The destination; if not specified, then the default is to push to `containers-storage:localhost/bootc`;
243
+ /// this will make the image accessible via e.g. `podman run localhost/bootc` and for builds.
244
+ target : Option < String > ,
245
+ } ,
246
+ }
247
+
194
248
/// Hidden, internal only options
195
249
#[ derive( Debug , clap:: Subcommand , PartialEq , Eq ) ]
196
250
pub ( crate ) enum InternalsOpts {
@@ -321,6 +375,12 @@ pub(crate) enum Opt {
321
375
/// Operations which can be executed as part of a container build.
322
376
#[ clap( subcommand) ]
323
377
Container ( ContainerOpts ) ,
378
+ /// Operations on container images
379
+ ///
380
+ /// Stability: This interface is not declared stable and may change or be removed
381
+ /// at any point in the future.
382
+ #[ clap( subcommand, hide = true ) ]
383
+ Image ( ImageOpts ) ,
324
384
/// Execute the given command in the host mount namespace
325
385
#[ cfg( feature = "install" ) ]
326
386
#[ clap( hide = true ) ]
@@ -732,6 +792,17 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
732
792
Ok ( ( ) )
733
793
}
734
794
} ,
795
+ Opt :: Image ( opts) => match opts {
796
+ ImageOpts :: List => crate :: image:: list_entrypoint ( ) . await ,
797
+ ImageOpts :: Push {
798
+ transport,
799
+ source,
800
+ target,
801
+ } => {
802
+ let transport = Transport :: try_from ( transport. as_str ( ) ) ?;
803
+ crate :: image:: push_entrypoint ( transport, source. as_deref ( ) , target. as_deref ( ) ) . await
804
+ }
805
+ } ,
735
806
#[ cfg( feature = "install" ) ]
736
807
Opt :: Install ( opts) => match opts {
737
808
InstallOpts :: ToDisk ( opts) => crate :: install:: install_to_disk ( opts) . await ,
0 commit comments