diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/podman/common/createparse.go | 21 | ||||
-rw-r--r-- | cmd/podman/common/netflags.go | 90 | ||||
-rw-r--r-- | cmd/podman/common/specgen.go | 8 | ||||
-rw-r--r-- | cmd/podman/containers/run.go | 2 | ||||
-rw-r--r-- | cmd/podman/images/inspect.go | 26 | ||||
-rw-r--r-- | cmd/podman/images/rm.go | 32 | ||||
-rw-r--r-- | cmd/podman/images/tree.go | 40 | ||||
-rw-r--r-- | cmd/podman/inspect.go | 31 | ||||
-rw-r--r-- | cmd/podman/system/service.go | 22 | ||||
-rw-r--r-- | cmd/podman/system/service_abi.go | 57 | ||||
-rw-r--r-- | cmd/podman/system/service_unsupported.go | 14 |
11 files changed, 261 insertions, 82 deletions
diff --git a/cmd/podman/common/createparse.go b/cmd/podman/common/createparse.go index aca6f752e..fe6e322c2 100644 --- a/cmd/podman/common/createparse.go +++ b/cmd/podman/common/createparse.go @@ -1,7 +1,6 @@ package common import ( - "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" ) @@ -17,27 +16,7 @@ func (c *ContainerCLIOpts) validate() error { if _, err := util.ValidatePullType(c.Pull); err != nil { return err } - // Verify the additional hosts are in correct format - for _, host := range c.Net.AddHosts { - if _, err := parse.ValidateExtraHost(host); err != nil { - return err - } - } - if dnsSearches := c.Net.DNSSearch; len(dnsSearches) > 0 { - // Validate domains are good - for _, dom := range dnsSearches { - if dom == "." { - if len(dnsSearches) > 1 { - return errors.Errorf("cannot pass additional search domains when also specifying '.'") - } - continue - } - if _, err := parse.ValidateDomain(dom); err != nil { - return err - } - } - } var imageVolType = map[string]string{ "bind": "", "tmpfs": "", diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go index 06c1b4521..1a47733e7 100644 --- a/cmd/podman/common/netflags.go +++ b/cmd/podman/common/netflags.go @@ -3,7 +3,9 @@ package common import ( "net" + "github.com/containers/libpod/cmd/podman/parse" "github.com/containers/libpod/pkg/domain/entities" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -58,20 +60,60 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { if err != nil { return nil, err } - servers, err := cmd.Flags().GetStringSlice("dns") - if err != nil { - return nil, err + // Verify the additional hosts are in correct format + for _, host := range opts.AddHosts { + if _, err := parse.ValidateExtraHost(host); err != nil { + return nil, err + } } - for _, d := range servers { - if d == "none" { - opts.DNSHost = true - break + + if cmd.Flags().Changed("dns") { + servers, err := cmd.Flags().GetStringSlice("dns") + if err != nil { + return nil, err + } + for _, d := range servers { + if d == "none" { + opts.UseImageResolvConf = true + if len(servers) > 1 { + return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d) + } + break + } + dns := net.ParseIP(d) + if dns == nil { + return nil, errors.Errorf("%s is not an ip address", d) + } + opts.DNSServers = append(opts.DNSServers, dns) } - opts.DNSServers = append(opts.DNSServers, net.ParseIP(d)) } - opts.DNSSearch, err = cmd.Flags().GetStringSlice("dns-search") - if err != nil { - return nil, err + + if cmd.Flags().Changed("dns-opt") { + options, err := cmd.Flags().GetStringSlice("dns-opt") + if err != nil { + return nil, err + } + opts.DNSOptions = options + } + + if cmd.Flags().Changed("dns-search") { + dnsSearches, err := cmd.Flags().GetStringSlice("dns-search") + if err != nil { + return nil, err + } + // Validate domains are good + for _, dom := range dnsSearches { + if dom == "." { + if len(dnsSearches) > 1 { + return nil, errors.Errorf("cannot pass additional search domains when also specifying '.'") + } + continue + } + if _, err := parse.ValidateDomain(dom); err != nil { + return nil, err + } + } + opts.DNSSearch = dnsSearches } m, err := cmd.Flags().GetString("mac-address") @@ -85,6 +127,7 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { } opts.StaticMAC = &mac } + inputPorts, err := cmd.Flags().GetStringSlice("publish") if err != nil { return nil, err @@ -95,6 +138,31 @@ func NetFlagsToNetOptions(cmd *cobra.Command) (*entities.NetOptions, error) { return nil, err } } + + ip, err := cmd.Flags().GetString("ip") + if err != nil { + return nil, err + } + if ip != "" { + staticIP := net.ParseIP(ip) + if staticIP == nil { + return nil, errors.Errorf("%s is not an ip address", ip) + } + opts.StaticIP = &staticIP + } + opts.NoHosts, err = cmd.Flags().GetBool("no-hosts") + + if cmd.Flags().Changed("network") { + network, err := cmd.Flags().GetString("network") + if err != nil { + return nil, err + } + + return nil, errors.Errorf("network %s is not yet supported", network) + // TODO How do I convert a string network to a Specgen.Namespace? + // opts.Network = specgen.Namespace{NSMode: network} + } + return &opts, err } diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go index b8526993c..1eb8fc0bd 100644 --- a/cmd/podman/common/specgen.go +++ b/cmd/podman/common/specgen.go @@ -292,9 +292,12 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string } s.ShmSize = &shmSize s.HostAdd = c.Net.AddHosts - s.DNSServer = c.Net.DNSServers + s.UseImageResolvConf = c.Net.UseImageResolvConf + s.DNSServers = c.Net.DNSServers s.DNSSearch = c.Net.DNSSearch - s.DNSOption = c.Net.DNSOptions + s.DNSOptions = c.Net.DNSOptions + s.StaticIP = c.Net.StaticIP + s.StaticMAC = c.Net.StaticMAC // deferred, must be added on libpod side //var ImageVolumes map[string]struct{} @@ -424,6 +427,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string } } + s.SeccompPolicy = c.SeccompPolicy // TODO any idea why this was done // storage.go from spec/ // grab it diff --git a/cmd/podman/containers/run.go b/cmd/podman/containers/run.go index 9d222e44d..16a54e578 100644 --- a/cmd/podman/containers/run.go +++ b/cmd/podman/containers/run.go @@ -122,7 +122,7 @@ func run(cmd *cobra.Command, args []string) error { return nil } if runRmi { - _, err := registry.ImageEngine().Delete(registry.GetContext(), []string{args[0]}, entities.ImageDeleteOptions{}) + _, err := registry.ImageEngine().Remove(registry.GetContext(), []string{args[0]}, entities.ImageRemoveOptions{}) if err != nil { logrus.Errorf("%s", errors.Wrapf(err, "failed removing image")) } diff --git a/cmd/podman/images/inspect.go b/cmd/podman/images/inspect.go index 4482ceee5..11bef02ba 100644 --- a/cmd/podman/images/inspect.go +++ b/cmd/podman/images/inspect.go @@ -20,11 +20,13 @@ import ( var ( // Command: podman image _inspect_ inspectCmd = &cobra.Command{ - Use: "inspect [flags] IMAGE", - Short: "Display the configuration of an image", - Long: `Displays the low-level information on an image identified by name or ID.`, - RunE: inspect, - Example: `podman image inspect alpine`, + Use: "inspect [flags] IMAGE", + Short: "Display the configuration of an image", + Long: `Displays the low-level information on an image identified by name or ID.`, + RunE: inspect, + Example: `podman inspect alpine + podman inspect --format "imageId: {{.Id}} size: {{.Size}}" alpine + podman inspect --format "image: {{.ImageName}} driver: {{.Driver}}" myctr`, } inspectOpts *entities.InspectOptions ) @@ -39,14 +41,14 @@ func init() { } func inspect(cmd *cobra.Command, args []string) error { - latestContainer := inspectOpts.Latest - - if len(args) == 0 && !latestContainer { - return errors.Errorf("container or image name must be specified: podman inspect [options [...]] name") + if inspectOpts.Size { + return fmt.Errorf("--size can only be used for containers") } - - if len(args) > 0 && latestContainer { - return errors.Errorf("you cannot provide additional arguments with --latest") + if inspectOpts.Latest { + return fmt.Errorf("--latest can only be used for containers") + } + if len(args) == 0 { + return errors.Errorf("image name must be specified: podman image inspect [options [...]] name") } results, err := registry.ImageEngine().Inspect(context.Background(), args, *inspectOpts) diff --git a/cmd/podman/images/rm.go b/cmd/podman/images/rm.go index 135fda387..da6a90d2b 100644 --- a/cmd/podman/images/rm.go +++ b/cmd/podman/images/rm.go @@ -2,7 +2,6 @@ package images import ( "fmt" - "os" "github.com/containers/libpod/cmd/podman/registry" "github.com/containers/libpod/pkg/domain/entities" @@ -23,7 +22,7 @@ var ( podman image rm c4dfb1609ee2 93fd78260bd1 c0ed59d05ff7`, } - imageOpts = entities.ImageDeleteOptions{} + imageOpts = entities.ImageRemoveOptions{} ) func init() { @@ -40,32 +39,25 @@ func imageRemoveFlagSet(flags *pflag.FlagSet) { flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images") flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image") } -func rm(cmd *cobra.Command, args []string) error { +func rm(cmd *cobra.Command, args []string) error { if len(args) < 1 && !imageOpts.All { return errors.Errorf("image name or ID must be specified") } if len(args) > 0 && imageOpts.All { return errors.Errorf("when using the --all switch, you may not pass any images names or IDs") } - report, err := registry.ImageEngine().Delete(registry.GetContext(), args, imageOpts) - if err != nil { - switch { - case report != nil && report.ImageNotFound != nil: - fmt.Fprintln(os.Stderr, err.Error()) - registry.SetExitCode(2) - case report != nil && report.ImageInUse != nil: - fmt.Fprintln(os.Stderr, err.Error()) - default: - return err + + report, err := registry.ImageEngine().Remove(registry.GetContext(), args, imageOpts) + if report != nil { + for _, u := range report.Untagged { + fmt.Println("Untagged: " + u) } + for _, d := range report.Deleted { + fmt.Println("Deleted: " + d) + } + registry.SetExitCode(report.ExitCode) } - for _, u := range report.Untagged { - fmt.Println("Untagged: " + u) - } - for _, d := range report.Deleted { - fmt.Println("Deleted: " + d) - } - return nil + return err } diff --git a/cmd/podman/images/tree.go b/cmd/podman/images/tree.go new file mode 100644 index 000000000..5e82e9dea --- /dev/null +++ b/cmd/podman/images/tree.go @@ -0,0 +1,40 @@ +package images + +import ( + "fmt" + + "github.com/containers/libpod/cmd/podman/registry" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/spf13/cobra" +) + +var ( + treeDescription = "Prints layer hierarchy of an image in a tree format" + treeCmd = &cobra.Command{ + Use: "tree [flags] IMAGE", + Args: cobra.ExactArgs(1), + Short: treeDescription, + Long: treeDescription, + RunE: tree, + Example: "podman image tree alpine:latest", + } + treeOpts entities.ImageTreeOptions +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: treeCmd, + Parent: imageCmd, + }) + treeCmd.Flags().BoolVar(&treeOpts.WhatRequires, "whatrequires", false, "Show all child images and layers of the specified image") +} + +func tree(_ *cobra.Command, args []string) error { + results, err := registry.ImageEngine().Tree(registry.Context(), args[0], treeOpts) + if err != nil { + return err + } + fmt.Println(results.Tree) + return nil +} diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index e67bc326b..93bf58bdd 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -1,10 +1,8 @@ package main import ( - "context" "fmt" - "github.com/containers/image/v5/docker/reference" "github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/containers" "github.com/containers/libpod/cmd/podman/images" @@ -21,11 +19,12 @@ var ( // Command: podman _inspect_ Object_ID inspectCmd = &cobra.Command{ Use: "inspect [flags] {CONTAINER_ID | IMAGE_ID}", - Args: cobra.ExactArgs(1), Short: "Display the configuration of object denoted by ID", Long: "Displays the low-level information on an object identified by name or ID", TraverseChildren: true, RunE: inspect, + Example: `podman inspect alpine + podman inspect --format "imageId: {{.Id}} size: {{.Size}}" alpine`, } ) @@ -35,21 +34,25 @@ func init() { Command: inspectCmd, }) inspectOpts = common.AddInspectFlagSet(inspectCmd) + flags := inspectCmd.Flags() + flags.StringVarP(&inspectOpts.Type, "type", "t", "", "Return JSON for specified type, (image or container) (default \"all\")") + if !registry.IsRemote() { + flags.BoolVarP(&inspectOpts.Latest, "latest", "l", false, "Act on the latest container podman is aware of (containers only)") + } } func inspect(cmd *cobra.Command, args []string) error { - // First check if the input is even valid for an image - if _, err := reference.Parse(args[0]); err == nil { - if found, err := registry.ImageEngine().Exists(context.Background(), args[0]); err != nil { - return err - } else if found.Value { - return images.Inspect(cmd, args, inspectOpts) + switch inspectOpts.Type { + case "image": + return images.Inspect(cmd, args, inspectOpts) + case "container": + return containers.Inspect(cmd, args, inspectOpts) + case "": + if err := images.Inspect(cmd, args, inspectOpts); err == nil { + return nil } - } - if found, err := registry.ContainerEngine().ContainerExists(context.Background(), args[0]); err != nil { - return err - } else if found.Value { return containers.Inspect(cmd, args, inspectOpts) + default: + return fmt.Errorf("invalid type %q is must be 'container' or 'image'", inspectOpts.Type) } - return fmt.Errorf("%s not found on system", args[0]) } diff --git a/cmd/podman/system/service.go b/cmd/podman/system/service.go index 6522a45f8..f4b91dd78 100644 --- a/cmd/podman/system/service.go +++ b/cmd/podman/system/service.go @@ -2,8 +2,10 @@ package system import ( "fmt" + "net/url" "os" "path/filepath" + "syscall" "time" "github.com/containers/libpod/cmd/podman/registry" @@ -59,6 +61,23 @@ func service(cmd *cobra.Command, args []string) error { } logrus.Infof("using API endpoint: '%s'", apiURI) + // Clean up any old existing unix domain socket + if len(apiURI) > 0 { + uri, err := url.Parse(apiURI) + if err != nil { + return err + } + + // socket activation uses a unix:// socket in the shipped unit files but apiURI is coded as "" at this layer. + if "unix" == uri.Scheme && !registry.IsRemote() { + if err := syscall.Unlink(uri.Path); err != nil && !os.IsNotExist(err) { + return err + } + mask := syscall.Umask(0177) + defer syscall.Umask(mask) + } + } + opts := entities.ServiceOptions{ URI: apiURI, Timeout: time.Duration(srvArgs.Timeout) * time.Second, @@ -71,7 +90,8 @@ func service(cmd *cobra.Command, args []string) error { logrus.Warn("This function is EXPERIMENTAL") fmt.Fprintf(os.Stderr, "This function is EXPERIMENTAL.\n") - return registry.ContainerEngine().RestService(registry.GetContext(), opts) + + return restService(opts, cmd.Flags(), registry.PodmanConfig()) } func resolveApiURI(_url []string) (string, error) { diff --git a/cmd/podman/system/service_abi.go b/cmd/podman/system/service_abi.go new file mode 100644 index 000000000..3da6ccfc7 --- /dev/null +++ b/cmd/podman/system/service_abi.go @@ -0,0 +1,57 @@ +// +build ABISupport + +package system + +import ( + "context" + "net" + "strings" + + api "github.com/containers/libpod/pkg/api/server" + "github.com/containers/libpod/pkg/domain/entities" + "github.com/containers/libpod/pkg/domain/infra" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/spf13/pflag" +) + +func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entities.PodmanConfig) error { + var ( + listener *net.Listener + err error + ) + + if opts.URI != "" { + fields := strings.Split(opts.URI, ":") + if len(fields) == 1 { + return errors.Errorf("%s is an invalid socket destination", opts.URI) + } + address := strings.Join(fields[1:], ":") + l, err := net.Listen(fields[0], address) + if err != nil { + return errors.Wrapf(err, "unable to create socket %s", opts.URI) + } + listener = &l + } + + rt, err := infra.GetRuntime(context.Background(), flags, cfg) + if err != nil { + return err + } + + server, err := api.NewServerWithSettings(rt, opts.Timeout, listener) + if err != nil { + return err + } + defer func() { + if err := server.Shutdown(); err != nil { + logrus.Warnf("Error when stopping API service: %s", err) + } + }() + + err = server.Serve() + if listener != nil { + _ = (*listener).Close() + } + return err +} diff --git a/cmd/podman/system/service_unsupported.go b/cmd/podman/system/service_unsupported.go new file mode 100644 index 000000000..95f8189f6 --- /dev/null +++ b/cmd/podman/system/service_unsupported.go @@ -0,0 +1,14 @@ +// +build !ABISupport + +package system + +import ( + "errors" + + "github.com/containers/libpod/pkg/domain/entities" + "github.com/spf13/pflag" +) + +func restService(opts entities.ServiceOptions, flags *pflag.FlagSet, cfg *entities.PodmanConfig) error { + return errors.New("not supported") +} |