summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/createparse.go21
-rw-r--r--cmd/podman/common/netflags.go90
-rw-r--r--cmd/podman/common/specgen.go8
-rw-r--r--cmd/podman/containers/run.go2
-rw-r--r--cmd/podman/images/inspect.go26
-rw-r--r--cmd/podman/images/rm.go32
-rw-r--r--cmd/podman/images/tree.go40
-rw-r--r--cmd/podman/inspect.go31
-rw-r--r--cmd/podman/system/service.go22
-rw-r--r--cmd/podman/system/service_abi.go57
-rw-r--r--cmd/podman/system/service_unsupported.go14
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")
+}