Merge pull request #27999 from baude/applytransports

add bootc transports to os-apply
This commit is contained in:
Paul Holzinger
2026-02-03 14:53:18 +01:00
committed by GitHub
11 changed files with 336 additions and 54 deletions

View File

@@ -504,12 +504,12 @@ func simplePathJoinUnix(p1, p2 string) string {
return p1 + "/" + p2 return p1 + "/" + p2
} }
// validCurrentCmdLine validates the current cmd line // ValidCurrentCmdLine validates the current cmd line
// It utilizes the Args function from the cmd struct // It utilizes the Args function from the cmd struct
// In most cases the Args function validates the args length but it // In most cases the Args function validates the args length but it
// is also used to verify that --latest is not given with an argument. // is also used to verify that --latest is not given with an argument.
// This function helps to makes sure we only complete valid arguments. // This function helps to makes sure we only complete valid arguments.
func validCurrentCmdLine(cmd *cobra.Command, args []string, toComplete string) bool { func ValidCurrentCmdLine(cmd *cobra.Command, args []string, toComplete string) bool {
if cmd.Args == nil { if cmd.Args == nil {
// Without an Args function we cannot check so assume it's correct // Without an Args function we cannot check so assume it's correct
return true return true
@@ -592,14 +592,14 @@ func getBoolCompletion(_ string) ([]string, cobra.ShellCompDirective) {
/* Autocomplete Functions for cobra ValidArgsFunction */ /* Autocomplete Functions for cobra ValidArgsFunction */
func AutocompleteArtifacts(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteArtifacts(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getArtifacts(cmd, toComplete) return getArtifacts(cmd, toComplete)
} }
func AutocompleteArtifactAdd(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteArtifactAdd(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) == 0 { if len(args) == 0 {
@@ -611,7 +611,7 @@ func AutocompleteArtifactAdd(cmd *cobra.Command, args []string, toComplete strin
// AutocompleteContainers - Autocomplete all container names. // AutocompleteContainers - Autocomplete all container names.
func AutocompleteContainers(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainers(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getContainers(cmd, toComplete, completeDefault) return getContainers(cmd, toComplete, completeDefault)
@@ -619,7 +619,7 @@ func AutocompleteContainers(cmd *cobra.Command, args []string, toComplete string
// AutocompleteContainersCreated - Autocomplete only created container names. // AutocompleteContainersCreated - Autocomplete only created container names.
func AutocompleteContainersCreated(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersCreated(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getContainers(cmd, toComplete, completeDefault, "created") return getContainers(cmd, toComplete, completeDefault, "created")
@@ -627,7 +627,7 @@ func AutocompleteContainersCreated(cmd *cobra.Command, args []string, toComplete
// AutocompleteContainersExited - Autocomplete only exited container names. // AutocompleteContainersExited - Autocomplete only exited container names.
func AutocompleteContainersExited(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersExited(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getContainers(cmd, toComplete, completeDefault, "exited") return getContainers(cmd, toComplete, completeDefault, "exited")
@@ -635,7 +635,7 @@ func AutocompleteContainersExited(cmd *cobra.Command, args []string, toComplete
// AutocompleteContainersPaused - Autocomplete only paused container names. // AutocompleteContainersPaused - Autocomplete only paused container names.
func AutocompleteContainersPaused(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersPaused(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getContainers(cmd, toComplete, completeDefault, "paused") return getContainers(cmd, toComplete, completeDefault, "paused")
@@ -643,7 +643,7 @@ func AutocompleteContainersPaused(cmd *cobra.Command, args []string, toComplete
// AutocompleteContainersRunning - Autocomplete only running container names. // AutocompleteContainersRunning - Autocomplete only running container names.
func AutocompleteContainersRunning(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersRunning(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getContainers(cmd, toComplete, completeDefault, "running") return getContainers(cmd, toComplete, completeDefault, "running")
@@ -651,7 +651,7 @@ func AutocompleteContainersRunning(cmd *cobra.Command, args []string, toComplete
// AutocompleteContainersStartable - Autocomplete only created and exited container names. // AutocompleteContainersStartable - Autocomplete only created and exited container names.
func AutocompleteContainersStartable(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersStartable(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getContainers(cmd, toComplete, completeDefault, "created", "exited") return getContainers(cmd, toComplete, completeDefault, "created", "exited")
@@ -659,7 +659,7 @@ func AutocompleteContainersStartable(cmd *cobra.Command, args []string, toComple
// AutocompletePods - Autocomplete all pod names. // AutocompletePods - Autocomplete all pod names.
func AutocompletePods(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompletePods(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getPods(cmd, toComplete, completeDefault) return getPods(cmd, toComplete, completeDefault)
@@ -668,7 +668,7 @@ func AutocompletePods(cmd *cobra.Command, args []string, toComplete string) ([]s
// AutocompletePodsRunning - Autocomplete only running pod names. // AutocompletePodsRunning - Autocomplete only running pod names.
// It considers degraded as running. // It considers degraded as running.
func AutocompletePodsRunning(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompletePodsRunning(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getPods(cmd, toComplete, completeDefault, "running", "degraded") return getPods(cmd, toComplete, completeDefault, "running", "degraded")
@@ -678,7 +678,7 @@ func AutocompletePodsRunning(cmd *cobra.Command, args []string, toComplete strin
// When a pod has a few containers paused, that ends up in degraded state // When a pod has a few containers paused, that ends up in degraded state
// So autocomplete degraded pod names as well // So autocomplete degraded pod names as well
func AutoCompletePodsPause(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutoCompletePodsPause(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getPods(cmd, toComplete, completeDefault, "paused", "degraded") return getPods(cmd, toComplete, completeDefault, "paused", "degraded")
@@ -686,7 +686,7 @@ func AutoCompletePodsPause(cmd *cobra.Command, args []string, toComplete string)
// AutocompleteForKube - Autocomplete all Podman objects supported by kube generate. // AutocompleteForKube - Autocomplete all Podman objects supported by kube generate.
func AutocompleteForKube(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteForKube(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
containers, _ := getContainers(cmd, toComplete, completeDefault) containers, _ := getContainers(cmd, toComplete, completeDefault)
@@ -704,7 +704,7 @@ func AutocompleteForGenerate(cmd *cobra.Command, args []string, toComplete strin
// AutocompleteContainersAndPods - Autocomplete container names and pod names. // AutocompleteContainersAndPods - Autocomplete container names and pod names.
func AutocompleteContainersAndPods(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersAndPods(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
containers, _ := getContainers(cmd, toComplete, completeDefault) containers, _ := getContainers(cmd, toComplete, completeDefault)
@@ -714,7 +714,7 @@ func AutocompleteContainersAndPods(cmd *cobra.Command, args []string, toComplete
// AutocompleteContainersAndImages - Autocomplete container names and pod names. // AutocompleteContainersAndImages - Autocomplete container names and pod names.
func AutocompleteContainersAndImages(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainersAndImages(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
containers, _ := getContainers(cmd, toComplete, completeDefault) containers, _ := getContainers(cmd, toComplete, completeDefault)
@@ -724,7 +724,7 @@ func AutocompleteContainersAndImages(cmd *cobra.Command, args []string, toComple
// AutocompleteVolumes - Autocomplete volumes. // AutocompleteVolumes - Autocomplete volumes.
func AutocompleteVolumes(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteVolumes(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getVolumes(cmd, toComplete) return getVolumes(cmd, toComplete)
@@ -732,7 +732,7 @@ func AutocompleteVolumes(cmd *cobra.Command, args []string, toComplete string) (
// AutocompleteSecrets - Autocomplete secrets. // AutocompleteSecrets - Autocomplete secrets.
func AutocompleteSecrets(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteSecrets(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getSecrets(cmd, toComplete, completeDefault) return getSecrets(cmd, toComplete, completeDefault)
@@ -747,7 +747,7 @@ func AutocompleteSecretCreate(_ *cobra.Command, args []string, _ string) ([]stri
// AutocompleteImages - Autocomplete images. // AutocompleteImages - Autocomplete images.
func AutocompleteImages(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteImages(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getImages(cmd, toComplete) return getImages(cmd, toComplete)
@@ -755,7 +755,7 @@ func AutocompleteImages(cmd *cobra.Command, args []string, toComplete string) ([
// AutocompleteQuadlets - Autocomplete quadlets. // AutocompleteQuadlets - Autocomplete quadlets.
func AutocompleteQuadlets(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteQuadlets(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getQuadlets(cmd, toComplete) return getQuadlets(cmd, toComplete)
@@ -763,7 +763,7 @@ func AutocompleteQuadlets(cmd *cobra.Command, args []string, toComplete string)
// AutocompleteManifestListAndMember - Autocomplete names of manifest lists and digests of items in them. // AutocompleteManifestListAndMember - Autocomplete names of manifest lists and digests of items in them.
func AutocompleteManifestListAndMember(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteManifestListAndMember(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) == 0 { if len(args) == 0 {
@@ -787,7 +787,7 @@ func AutocompletePodExitPolicy(_ *cobra.Command, _ []string, _ string) ([]string
// AutocompleteCreateRun - Autocomplete only the fist argument as image and then do file completion. // AutocompleteCreateRun - Autocomplete only the fist argument as image and then do file completion.
func AutocompleteCreateRun(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteCreateRun(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) < 1 { if len(args) < 1 {
@@ -829,7 +829,7 @@ func AutocompleteCreateRun(cmd *cobra.Command, args []string, toComplete string)
// AutocompleteRegistries - Autocomplete registries. // AutocompleteRegistries - Autocomplete registries.
func AutocompleteRegistries(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteRegistries(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getRegistries() return getRegistries()
@@ -837,7 +837,7 @@ func AutocompleteRegistries(cmd *cobra.Command, args []string, toComplete string
// AutocompleteNetworks - Autocomplete networks. // AutocompleteNetworks - Autocomplete networks.
func AutocompleteNetworks(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteNetworks(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return getNetworks(cmd, toComplete, completeDefault) return getNetworks(cmd, toComplete, completeDefault)
@@ -860,7 +860,7 @@ func AutocompleteDefaultOneArg(_ *cobra.Command, args []string, _ string) ([]str
// AutocompleteCommitCommand - Autocomplete podman commit command args. // AutocompleteCommitCommand - Autocomplete podman commit command args.
func AutocompleteCommitCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteCommitCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) == 0 { if len(args) == 0 {
@@ -875,7 +875,7 @@ func AutocompleteCommitCommand(cmd *cobra.Command, args []string, toComplete str
// AutocompleteCpCommand - Autocomplete podman cp command args. // AutocompleteCpCommand - Autocomplete podman cp command args.
func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) < 2 { if len(args) < 2 {
@@ -921,7 +921,7 @@ func AutocompleteCpCommand(cmd *cobra.Command, args []string, toComplete string)
// AutocompleteExecCommand - Autocomplete podman exec command args. // AutocompleteExecCommand - Autocomplete podman exec command args.
func AutocompleteExecCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteExecCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) == 0 { if len(args) == 0 {
@@ -932,7 +932,7 @@ func AutocompleteExecCommand(cmd *cobra.Command, args []string, toComplete strin
// AutocompleteRunlabelCommand - Autocomplete podman container runlabel command args. // AutocompleteRunlabelCommand - Autocomplete podman container runlabel command args.
func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) == 0 { if len(args) == 0 {
@@ -949,7 +949,7 @@ func AutocompleteRunlabelCommand(cmd *cobra.Command, args []string, toComplete s
// AutocompleteContainerOneArg - Autocomplete containers as fist arg. // AutocompleteContainerOneArg - Autocomplete containers as fist arg.
func AutocompleteContainerOneArg(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteContainerOneArg(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
if len(args) == 0 { if len(args) == 0 {
@@ -991,7 +991,7 @@ func AutocompleteTopCmd(cmd *cobra.Command, args []string, toComplete string) ([
// AutocompleteInspect - Autocomplete podman inspect. // AutocompleteInspect - Autocomplete podman inspect.
func AutocompleteInspect(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteInspect(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
containers, _ := getContainers(cmd, toComplete, completeDefault) containers, _ := getContainers(cmd, toComplete, completeDefault)
@@ -1010,7 +1010,7 @@ func AutocompleteInspect(cmd *cobra.Command, args []string, toComplete string) (
} }
func AutoCompleteFarms(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutoCompleteFarms(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
farms, err := podmanConfig.ContainersConfDefaultsRO.GetAllFarms() farms, err := podmanConfig.ContainersConfDefaultsRO.GetAllFarms()
@@ -1029,7 +1029,7 @@ func AutoCompleteFarms(cmd *cobra.Command, args []string, toComplete string) ([]
// AutocompleteSystemConnections - Autocomplete system connections. // AutocompleteSystemConnections - Autocomplete system connections.
func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
@@ -1050,7 +1050,7 @@ func AutocompleteSystemConnections(cmd *cobra.Command, args []string, toComplete
// AutocompleteScp returns a list of connections, images, or both, depending on the amount of arguments // AutocompleteScp returns a list of connections, images, or both, depending on the amount of arguments
func AutocompleteScp(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteScp(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
switch len(args) { switch len(args) {
@@ -1957,7 +1957,7 @@ func AutocompleteCompressionFormat(_ *cobra.Command, _ []string, _ string) ([]st
// AutocompleteClone - Autocomplete container and image names // AutocompleteClone - Autocomplete container and image names
func AutocompleteClone(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteClone(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
switch len(args) { switch len(args) {
@@ -1977,7 +1977,7 @@ func AutocompleteClone(cmd *cobra.Command, args []string, toComplete string) ([]
// AutocompleteSSH - Autocomplete ssh modes // AutocompleteSSH - Autocomplete ssh modes
func AutocompleteSSH(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteSSH(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) { if !ValidCurrentCmdLine(cmd, args, toComplete) {
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
return []string{string(ssh.GolangMode), string(ssh.NativeMode)}, cobra.ShellCompDirectiveNoFileComp return []string{string(ssh.GolangMode), string(ssh.NativeMode)}, cobra.ShellCompDirectiveNoFileComp

View File

@@ -23,7 +23,7 @@ var (
PersistentPreRunE: machinePreRunE, PersistentPreRunE: machinePreRunE,
RunE: inspect, RunE: inspect,
Example: `podman machine inspect myvm`, Example: `podman machine inspect myvm`,
ValidArgsFunction: autocompleteMachine, ValidArgsFunction: AutocompleteMachine,
} }
inspectFlag = inspectFlagType{} inspectFlag = inspectFlagType{}
) )

View File

@@ -12,6 +12,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/containers/podman/v6/cmd/podman/common"
"github.com/containers/podman/v6/cmd/podman/registry" "github.com/containers/podman/v6/cmd/podman/registry"
"github.com/containers/podman/v6/cmd/podman/validate" "github.com/containers/podman/v6/cmd/podman/validate"
"github.com/containers/podman/v6/libpod/events" "github.com/containers/podman/v6/libpod/events"
@@ -93,9 +94,9 @@ func autocompleteMachineCp(_ *cobra.Command, args []string, toComplete string) (
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp
} }
// autocompleteMachine - Autocomplete machines. // AutocompleteMachine - Autocomplete machines.
func autocompleteMachine(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { func AutocompleteMachine(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if len(args) == 0 { if common.ValidCurrentCmdLine(cmd, args, toComplete) {
return getMachines(toComplete) return getMachines(toComplete)
} }
return nil, cobra.ShellCompDirectiveNoFileComp return nil, cobra.ShellCompDirectiveNoFileComp

View File

@@ -12,14 +12,25 @@ import (
) )
var applyCmd = &cobra.Command{ var applyCmd = &cobra.Command{
Use: "apply [options] IMAGE [NAME]", Use: "apply [options] URI|IMAGE [MACHINE]",
Short: "Apply an OCI image to a Podman Machine's OS", Short: "Apply an OCI image to a Podman Machine's OS",
Long: "Apply custom layers from a containerized Fedora CoreOS OCI image on top of an existing VM", Long: "Apply custom layers from a containerized Fedora CoreOS OCI image on top of an existing VM",
PersistentPreRunE: validate.NoOp, PersistentPreRunE: validate.NoOp,
Args: cobra.RangeArgs(1, 2), Args: cobra.RangeArgs(1, 2),
RunE: apply, RunE: apply,
ValidArgsFunction: common.AutocompleteImages, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]cobra.Completion, cobra.ShellCompDirective) {
Example: `podman machine os apply myimage`, switch len(args) {
case 0:
images, _ := common.AutocompleteImages(cmd, args, toComplete)
// We also accept an URI so ignore ShellCompDirectiveNoFileComp and use the default one instead to get file paths completed by the shell.
return images, cobra.ShellCompDirectiveDefault
case 1:
return machine.AutocompleteMachine(cmd, args, toComplete)
default:
return nil, cobra.ShellCompDirectiveNoFileComp
}
},
Example: `podman machine os apply myimage`,
} }
var restart bool var restart bool

View File

@@ -18,7 +18,7 @@ var rmCmd = &cobra.Command{
RunE: rm, RunE: rm,
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
Example: `podman machine rm podman-machine-default`, Example: `podman machine rm podman-machine-default`,
ValidArgsFunction: autocompleteMachine, ValidArgsFunction: AutocompleteMachine,
} }
var destroyOptions machine.RemoveOptions var destroyOptions machine.RemoveOptions

View File

@@ -21,7 +21,7 @@ var (
RunE: start, RunE: start,
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
Example: `podman machine start podman-machine-default`, Example: `podman machine start podman-machine-default`,
ValidArgsFunction: autocompleteMachine, ValidArgsFunction: AutocompleteMachine,
} }
startOpts = machine.StartOptions{} startOpts = machine.StartOptions{}
setDefaultSystemConn bool setDefaultSystemConn bool

View File

@@ -19,7 +19,7 @@ var stopCmd = &cobra.Command{
RunE: stop, RunE: stop,
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
Example: `podman machine stop podman-machine-default`, Example: `podman machine stop podman-machine-default`,
ValidArgsFunction: autocompleteMachine, ValidArgsFunction: AutocompleteMachine,
} }
func init() { func init() {

View File

@@ -4,7 +4,7 @@
podman\-machine\-os\-apply - Apply an OCI image to a Podman Machine's OS podman\-machine\-os\-apply - Apply an OCI image to a Podman Machine's OS
## SYNOPSIS ## SYNOPSIS
**podman machine os apply** [*options*] *image* [vm] **podman machine os apply** [*options*] *uri* [vm]
## DESCRIPTION ## DESCRIPTION
@@ -19,7 +19,16 @@ customized distribution and cannot be updated with this command.
Note: WSL-based machines are upgradable by using the `podman machine ssh <machine_name>` command followed by `sudo dnf update`. This can, however, result in unexpected results in Note: WSL-based machines are upgradable by using the `podman machine ssh <machine_name>` command followed by `sudo dnf update`. This can, however, result in unexpected results in
Podman client and server version differences. Podman client and server version differences.
The applying of the OCI image is done by a command called `bootc`. The applying of the OCI image is done by a command called `bootc` and specifically `bootc switch`. By default, this command
takes an OCI registry image reference like `quay.io/custom/machine-os:latest`. However, `bootc` also
understands references with different transports. At present, Podman will support the following transports:
* containers-storage
* oci
* oci-archive
* registry
Examples for these transports in URI form are provided below.
Podman machine images are stored as OCI images at `quay.io/podman/machine-os`. When applying an image using this Podman machine images are stored as OCI images at `quay.io/podman/machine-os`. When applying an image using this
command, the fully qualified OCI reference name must be used including tag where the tag is the command, the fully qualified OCI reference name must be used including tag where the tag is the
@@ -47,15 +56,37 @@ bootable OCI image.
Note: This may result in having a newer Podman version inside the machine Note: This may result in having a newer Podman version inside the machine
than the client. Unexpected results may occur. than the client. Unexpected results may occur.
Update the default Podman machine to the most recent Podman 6.1 bootable Apply a new custom operating system from an OCI bootable image on quay.
OCI image.
``` ```
$ podman machine os apply quay.io/podman/machine-os:6.1 $ podman machine os apply quay.io/custom/machine-os:latest
``` ```
Update the specified Podman machine to latest Podman 6.1 bootable OCI image. Apply a new custom operating system to a specific machine from an OCI bootable image on quay.
``` ```
$ podman machine os apply quay.io/podman/machine-os:6.1 mymachine $ podman machine os apply quay.io/custom/machine-os:latest mymachine
```
Apply a new custom operating system that was pulled or built on your existing machine by the unprivileged user.
Note the use of brackets around the path because this command is run by the root user.
```
$ podman machine os apply containers-storage:[/home/core/.local/share/containers/storage]localhost/mycustomimage:latest
```
Apply a new custom operating system that was pulled or built on your existing machine by the privileged user. Note that
because a privileged user built or pulled the image, `bootc` will resolve that users storage and the path
is not needed.
```
$ podman machine os apply containers-storage:localhost/mycustomimage:latest
```
Apply a new custom operating system from an OCI archive in tar form.
```
$ podman machine os apply oci-archive:/tmp/oci-image.tar
```
Apply a new custom operating system from an OCI formatted directory.
```
$ podman machine os apply oci:/tmp/oci-image/
``` ```
## SEE ALSO ## SEE ALSO

View File

@@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"strings"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
@@ -16,6 +17,7 @@ import (
"go.podman.io/image/v5/docker/reference" "go.podman.io/image/v5/docker/reference"
"go.podman.io/image/v5/image" "go.podman.io/image/v5/image"
"go.podman.io/image/v5/manifest" "go.podman.io/image/v5/manifest"
"go.podman.io/image/v5/transports/alltransports"
"go.podman.io/image/v5/types" "go.podman.io/image/v5/types"
) )
@@ -27,7 +29,17 @@ type OSTree struct{}
// is pulled from an OCI registry. We simply pass the user // is pulled from an OCI registry. We simply pass the user
// input to bootc without any manipulation. // input to bootc without any manipulation.
func (dist *OSTree) Apply(image string, _ ApplyOptions) error { func (dist *OSTree) Apply(image string, _ ApplyOptions) error {
cli := []string{"bootc", "switch", image} t, pathOrImageRef, err := parseApplyInput(image)
if err != nil {
return err
}
cli := []string{"bootc", "switch"}
// registry is the default transport and therefore not
// necessary
if t != "registry" {
cli = append(cli, "--transport", t)
}
cli = append(cli, pathOrImageRef)
cmd := exec.Command("sudo", cli...) cmd := exec.Command("sudo", cli...)
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
@@ -185,3 +197,79 @@ func printJSON(out UpgradeOutput) error {
fmt.Println(string(b)) fmt.Println(string(b))
return nil return nil
} }
// parseApplyInput takes well known OCI references and splits them up. this
// function should only be used to deal with bootc transports. podman takes
// the entire reference as an oci reference but bootc requires we use
// --transport if the default transport is not used. also, bootc's default
// transport is "registry" which mimics docker in the way it is handled.
func parseApplyInput(arg string) (string, string, error) {
var (
containersStorageTransport = "containers-storage"
dockerTransport = "docker"
ociArchiveTransport = "oci-archive"
ociTransport = "oci"
registryTransport = "registry"
)
// The order of this parsing matters. Be careful when you edit.
// containers-storage:/home/user:localhost/fedora-bootc:latest
afterCS, hasCS := strings.CutPrefix(arg, containersStorageTransport+":")
if hasCS {
return containersStorageTransport, afterCS, nil
}
imgRef, err := alltransports.ParseImageName(arg)
if err == nil {
transportName := imgRef.Transport().Name()
if imgRef.DockerReference() != nil {
// bootc docs do not show the docker transport, but the
// code apparently does handle it and because docker is
// a well-known transport, we do as well, but we change
// it to registry for convenience.
if transportName == dockerTransport {
transportName = registryTransport
}
// docker://quay.io/fedora/fedora-bootc:40
return transportName, imgRef.DockerReference().String(), nil
}
imagePath := imgRef.StringWithinTransport()
if transportName == ociTransport { //nolint:staticcheck
// oci:/tmp/oci-image
imagePath, _, _ = strings.Cut(imagePath, ":")
} else if transportName == ociArchiveTransport {
// oci-archive:/tmp/myimage.tar
imagePath = strings.TrimSuffix(imagePath, ":")
}
return transportName, imagePath, nil
}
// quay.io/fedora/fedora-bootc:40
if _, err := reference.ParseNamed(arg); err == nil {
return registryTransport, arg, nil
}
// registry://quay.io/fedora/fedora-bootc:40
afterReg, hasRegistry := strings.CutPrefix(arg, registryTransport+"://")
if hasRegistry {
return registryTransport, afterReg, nil
}
// oci-archive:/var/tmp/fedora-bootc.tar
// oci-archive:/mnt/usb/images/myapp.tar
afterOCIArchive, hasOCIArchive := strings.CutPrefix(arg, ociArchiveTransport+":")
if hasOCIArchive {
return ociArchiveTransport, afterOCIArchive, nil
}
// oci:/tmp/oci-image
// oci:/var/mnt/usb/bootc-image
afterOCI, hasOCI := strings.CutPrefix(arg, ociTransport+":")
if hasOCI {
return ociTransport, afterOCI, nil
}
return "", "", fmt.Errorf("unknown transport %q given", arg)
}

View File

@@ -89,3 +89,151 @@ func Test_compareMajorMinor(t *testing.T) {
}) })
} }
} }
func Test_parseApplyInput(t *testing.T) {
type args struct {
arg string
}
tests := []struct {
name string
args args
want string
want1 string
wantErr bool
}{
{
name: "bare registry reference with tag",
args: args{arg: "quay.io/fedora/fedora-bootc:40"},
want: "registry",
want1: "quay.io/fedora/fedora-bootc:40",
wantErr: false,
},
{
name: "docker transport with tag",
args: args{arg: "docker://quay.io/fedora/fedora-bootc:40"},
want: "registry",
want1: "quay.io/fedora/fedora-bootc:40",
wantErr: false,
},
{
name: "docker transport with digest",
args: args{arg: "docker://quay.io/podman/stable@sha256:9cca0703342e24806a9f64e08c053dca7f2cd90f10529af8ea872afb0a0c77d4"},
want: "registry",
want1: "quay.io/podman/stable@sha256:9cca0703342e24806a9f64e08c053dca7f2cd90f10529af8ea872afb0a0c77d4",
wantErr: false,
},
{
name: "registry transport with tag",
args: args{arg: "registry://quay.io/fedora/fedora-bootc:40"},
want: "registry",
want1: "quay.io/fedora/fedora-bootc:40",
wantErr: false,
},
{
name: "registry transport with digest",
args: args{arg: "registry://quay.io/podman/stable@sha256:9cca0703342e24806a9f64e08c053dca7f2cd90f10529af8ea872afb0a0c77d4"},
want: "registry",
want1: "quay.io/podman/stable@sha256:9cca0703342e24806a9f64e08c053dca7f2cd90f10529af8ea872afb0a0c77d4",
wantErr: false,
},
{
name: "registry transport with port",
args: args{arg: "registry://localhost:5000/myapp:latest"},
want: "registry",
want1: "localhost:5000/myapp:latest",
wantErr: false,
},
{
name: "oci transport var path",
args: args{arg: "oci:/var/mnt/usb/bootc-image"},
want: "oci",
want1: "/var/mnt/usb/bootc-image",
wantErr: false,
},
{
name: "oci transport opt path",
args: args{arg: "oci:/opt/images/mylayout"},
want: "oci",
want1: "/opt/images/mylayout",
wantErr: false,
},
{
name: "oci transport tmp path",
args: args{arg: "oci:/tmp/oci-image"},
want: "oci",
want1: "/tmp/oci-image",
wantErr: false,
},
{
name: "oci transport with reference",
args: args{arg: "oci:/path/to/oci-dir:myref"},
want: "oci",
want1: "/path/to/oci-dir:myref",
wantErr: false,
},
{
name: "oci-archive transport tmp tar",
args: args{arg: "oci-archive:/tmp/myimage.tar"},
want: "oci-archive",
want1: "/tmp/myimage.tar",
wantErr: false,
},
{
name: "oci-archive transport mnt path",
args: args{arg: "oci-archive:/mnt/usb/images/myapp.tar"},
want: "oci-archive",
want1: "/mnt/usb/images/myapp.tar",
wantErr: false,
},
{
name: "oci-archive transport with reference",
args: args{arg: "oci-archive:/home/user/archives/image.tar:myref"},
want: "oci-archive",
want1: "/home/user/archives/image.tar:myref",
wantErr: false,
},
{
name: "containers-storage transport with tag",
args: args{arg: "containers-storage:quay.io/podman/machine-os:6.0"},
want: "containers-storage",
want1: "quay.io/podman/machine-os:6.0",
wantErr: false,
},
{
name: "containers-storage transport with graph root",
args: args{arg: "containers-storage:[/home/core/.local/share/containers/storage]quay.io/podman/machine-os:6.0"},
want: "containers-storage",
want1: "[/home/core/.local/share/containers/storage]quay.io/podman/machine-os:6.0",
wantErr: false,
},
{
name: "good reference bad transport",
args: args{"foobar://quay.io/podman/machine-os:6.0"},
want: "",
want1: "",
wantErr: true,
},
{
name: "similar name but incorrect transport",
args: args{"oci-dir:/foo/bar/bar.tar"},
want: "",
want1: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1, err := parseApplyInput(tt.args.arg)
if (err != nil) != tt.wantErr {
t.Errorf("parseApplyInput() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("parseApplyInput() got = '%v', want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("parseApplyInput() got1 = '%v', want %v", got1, tt.want1)
}
})
}
}

View File

@@ -196,7 +196,10 @@ function check_shell_completion() {
_check_completion_end NoSpace _check_completion_end NoSpace
else else
_check_completion_end Default _check_completion_end Default
_check_no_suggestions # machine os apply is special and offers images and normal shell completion
if [[ "$cmd" != "apply" ]]; then
_check_no_suggestions
fi
fi fi
;; ;;