Skip to content

Commit

Permalink
Introducing podman artifact inspect
Browse files Browse the repository at this point in the history
the podman artifact verb is used to manage OCi artifacts. inspect is the
first of several sub-verb commands we need.  this pr introduces the
command and the neccesary plumbing to do the rest of the artifact
commands without an overwhelmingly huge PR.

until more sub commands are implemented, e2e tests are not possible.

there are TODOs in this code; most of which cannot be firmly established
at the moment and therefore are as such.

Signed-off-by: Brent Baude <[email protected]>

wip

Signed-off-by: Brent Baude <[email protected]>

wip

Signed-off-by: Brent Baude <[email protected]>
  • Loading branch information
baude committed Dec 12, 2024
1 parent 9a66cbf commit d08dc29
Show file tree
Hide file tree
Showing 30 changed files with 1,701 additions and 87 deletions.
49 changes: 49 additions & 0 deletions cmd/podman/artifact/add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package artifact

import (
"fmt"
"github.com/containers/podman/v5/pkg/domain/entities"

"github.com/containers/podman/v5/cmd/podman/registry"
"github.com/spf13/cobra"
)

var (
addCmd = &cobra.Command{
Use: "add [options] PATH ARTIFACT",
Short: "Add an OCI artifact to the local store",
Long: "Add an OCI artifact to the local store from the local filesystem",
RunE: add,
Args: cobra.MinimumNArgs(2),
Example: `podman artifact add /tmp/foobar.txt quay.io/myimage/myartifact:latest`,
}
addFlag = addFlagType{}
)

// TODO at some point force will be a required option; but this cannot be
// until we have artifacts being consumed by other parts of libpod like
// volumes
type addFlagType struct {
}

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: addCmd,
Parent: artifactCmd,
})

// TODO When the inspect structure has been defined, we need to uncommand and redirect this. Reminder, this
// will also need to be reflected in the podman-artifact-inspect man page
// _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&machine.InspectInfo{}))
}

func add(cmd *cobra.Command, args []string) error {
//_, err := registry.ImageEngine().ArtifactRm(registry.GetContext(), args[0], entities.ArtifactRemoveOptions{})
//return err
report, err := registry.ImageEngine().ArtifactAdd(registry.Context(), args[0], args[1], entities.ArtifactAddoptions{})
if err != nil {
return err
}
fmt.Println(report.NewBlobDigest)
return nil
}
25 changes: 25 additions & 0 deletions cmd/podman/artifact/artifact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package artifact

import (
"github.com/containers/podman/v5/cmd/podman/registry"
"github.com/containers/podman/v5/cmd/podman/validate"
"github.com/spf13/cobra"
)

var (
json = registry.JSONLibrary()
// Command: podman _artifact_
artifactCmd = &cobra.Command{
Use: "artifact",
Short: "Manage OCI artifacts",
Long: "Manage OCI artifacts",
//PersistentPreRunE: validate.NoOp,
RunE: validate.SubCommandExists,
}
)

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: artifactCmd,
})
}
69 changes: 69 additions & 0 deletions cmd/podman/artifact/inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package artifact

import (
"fmt"
"os"

"github.com/containers/podman/v5/cmd/podman/registry"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/spf13/cobra"
)

var (
inspectCmd = &cobra.Command{
Use: "inspect [options] [ARTIFACT...]",
Short: "Inspect an OCI artifact",
Long: "Provide details on an OCI artifact",
RunE: inspect,
Args: cobra.MinimumNArgs(1),
Example: `podman artifact inspect quay.io/myimage/myartifact:latest`,
}
inspectFlag = inspectFlagType{}
)

type inspectFlagType struct {
format string
remote bool
}

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: inspectCmd,
Parent: artifactCmd,
})
flags := inspectCmd.Flags()
formatFlagName := "format"
flags.StringVar(&inspectFlag.format, formatFlagName, "", "Format volume output using JSON or a Go template")
remoteFlagName := "remote"
flags.BoolVar(&inspectFlag.remote, remoteFlagName, false, "Inspect the image on a container image registry")

// TODO When the inspect structure has been defined, we need to uncommand and redirect this. Reminder, this
// will also need to be reflected in the podman-artifact-inspect man page
// _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&machine.InspectInfo{}))
}

func inspect(cmd *cobra.Command, args []string) error {
if inspectFlag.remote {
return fmt.Errorf("not implemented")
}

if inspectFlag.format != "" {
return fmt.Errorf("not implemented")
}

artifactOptions := entities.ArtifactInspectOptions{}
inspectData, err := registry.ImageEngine().ArtifactInspect(registry.GetContext(), args[0], artifactOptions)
if err != nil {
return err
}
return printJSON(inspectData)
}

func printJSON(data interface{}) error {
enc := json.NewEncoder(os.Stdout)
// by default, json marshallers will force utf=8 from
// a string.
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
return enc.Encode(data)
}
69 changes: 69 additions & 0 deletions cmd/podman/artifact/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package artifact

import (
"fmt"
"os"
"strings"
"text/tabwriter"

"github.com/containers/podman/v5/cmd/podman/registry"
"github.com/containers/podman/v5/pkg/domain/entities"
units "github.com/docker/go-units"
"github.com/spf13/cobra"
)

var (
ListCmd = &cobra.Command{
Use: "list [options]",
Aliases: []string{"ls"},
Short: "List OCI artifacts",
Long: "List OCI artifacts in local store",
RunE: list,
Args: cobra.NoArgs,
Example: `podman artifact ls`,
}
ListFlag = inspectFlagType{}
)

type listFlagType struct {
format string
}

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: ListCmd,
Parent: artifactCmd,
})
flags := ListCmd.Flags()
formatFlagName := "format"
flags.StringVar(&inspectFlag.format, formatFlagName, "", "Format volume output using JSON or a Go template")

// TODO When the inspect structure has been defined, we need to uncommand and redirect this. Reminder, this
// will also need to be reflected in the podman-artifact-inspect man page
// _ = inspectCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&machine.InspectInfo{}))
}

func list(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("format") {
return fmt.Errorf("not implemented")
}
reports, err := registry.ImageEngine().ArtifactList(registry.GetContext(), entities.ArtifactListOptions{})
if err != nil {
return err
}

return writeTemplate(cmd, reports)
}

func writeTemplate(cmd *cobra.Command, reports []*entities.ArtifactListReport) error {
fmt.Println("")
tw := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
fmt.Fprintln(tw, "NAME\tSIZE")
for _, art := range reports {
splitsees := strings.SplitN(art.List.Reference.StringWithinTransport(), ":", 2)
fmt.Fprintf(tw, "%s\t\t%s\n", splitsees[1], units.HumanSize(float64(art.TotalSize())))
}
tw.Flush()
fmt.Println("")
return nil
}
Loading

0 comments on commit d08dc29

Please sign in to comment.