Merge pull request #6016 from giuseppe/fix-create

v2, podman: fix create and entrypoint tests
This commit is contained in:
OpenShift Merge Robot
2020-05-01 15:32:00 +02:00
committed by GitHub
14 changed files with 96 additions and 59 deletions

View File

@ -49,9 +49,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"cap-drop", []string{}, "cap-drop", []string{},
"Drop capabilities from the container", "Drop capabilities from the container",
) )
cgroupNS := "" createFlags.String(
createFlags.StringVar(
&cgroupNS,
"cgroupns", containerConfig.CgroupNS(), "cgroupns", containerConfig.CgroupNS(),
"cgroup namespace to use", "cgroup namespace to use",
) )
@ -155,9 +153,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"device-write-iops", []string{}, "device-write-iops", []string{},
"Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)", "Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)",
) )
createFlags.StringVar( createFlags.String("entrypoint", "",
&cf.Entrypoint,
"entrypoint", "",
"Overwrite the default ENTRYPOINT of the image", "Overwrite the default ENTRYPOINT of the image",
) )
createFlags.StringArrayVarP( createFlags.StringArrayVarP(
@ -248,9 +244,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"interactive", "i", false, "interactive", "i", false,
"Keep STDIN open even if not attached", "Keep STDIN open even if not attached",
) )
ipcNS := "" createFlags.String(
createFlags.StringVar(
&ipcNS,
"ipc", containerConfig.IPCNS(), "ipc", containerConfig.IPCNS(),
"IPC namespace to use", "IPC namespace to use",
) )
@ -331,9 +325,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"use `OS` instead of the running OS for choosing images", "use `OS` instead of the running OS for choosing images",
) )
// markFlagHidden(createFlags, "override-os") // markFlagHidden(createFlags, "override-os")
pid := "" createFlags.String(
createFlags.StringVar(
&pid,
"pid", containerConfig.PidNS(), "pid", containerConfig.PidNS(),
"PID namespace to use", "PID namespace to use",
) )
@ -397,9 +389,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"security-opt", containerConfig.SecurityOptions(), "security-opt", containerConfig.SecurityOptions(),
"Security Options", "Security Options",
) )
shmSize := "" createFlags.String(
createFlags.StringVar(
&shmSize,
"shm-size", containerConfig.ShmSize(), "shm-size", containerConfig.ShmSize(),
"Size of /dev/shm "+sizeWithUnitFormat, "Size of /dev/shm "+sizeWithUnitFormat,
) )
@ -464,15 +454,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"user", "u", "", "user", "u", "",
"Username or UID (format: <name|uid>[:<group|gid>])", "Username or UID (format: <name|uid>[:<group|gid>])",
) )
userNS := "" createFlags.String(
createFlags.StringVar(
&userNS,
"userns", containerConfig.Containers.UserNS, "userns", containerConfig.Containers.UserNS,
"User namespace to use", "User namespace to use",
) )
utsNS := "" createFlags.String(
createFlags.StringVar(
&utsNS,
"uts", containerConfig.Containers.UTSNS, "uts", containerConfig.Containers.UTSNS,
"UTS namespace to use", "UTS namespace to use",
) )

View File

@ -31,7 +31,7 @@ type ContainerCLIOpts struct {
DeviceReadIOPs []string DeviceReadIOPs []string
DeviceWriteBPs []string DeviceWriteBPs []string
DeviceWriteIOPs []string DeviceWriteIOPs []string
Entrypoint string Entrypoint *string
env []string env []string
EnvHost bool EnvHost bool
EnvFile []string EnvFile []string

View File

@ -364,20 +364,20 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.WorkDir = workDir s.WorkDir = workDir
entrypoint := []string{} entrypoint := []string{}
userCommand := []string{} userCommand := []string{}
if ep := c.Entrypoint; len(ep) > 0 { if c.Entrypoint != nil {
// Check if entrypoint specified is json if ep := *c.Entrypoint; len(ep) > 0 {
if err := json.Unmarshal([]byte(c.Entrypoint), &entrypoint); err != nil { // Check if entrypoint specified is json
entrypoint = append(entrypoint, ep) if err := json.Unmarshal([]byte(*c.Entrypoint), &entrypoint); err != nil {
entrypoint = append(entrypoint, ep)
}
} }
s.Entrypoint = entrypoint
} }
var command []string var command []string
s.Entrypoint = entrypoint
// Build the command // Build the command
// If we have an entry point, it goes first // If we have an entry point, it goes first
if len(entrypoint) > 0 { if c.Entrypoint != nil {
command = entrypoint command = entrypoint
} }
if len(inputCommand) > 0 { if len(inputCommand) > 0 {
@ -386,9 +386,12 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
userCommand = append(userCommand, inputCommand...) userCommand = append(userCommand, inputCommand...)
} }
if len(inputCommand) > 0 { switch {
case len(inputCommand) > 0:
s.Command = userCommand s.Command = userCommand
} else { case c.Entrypoint != nil:
s.Command = []string{}
default:
s.Command = command s.Command = command
} }

View File

@ -1,8 +1,10 @@
package containers package containers
import ( import (
"context"
"fmt" "fmt"
"os" "os"
"strings"
"github.com/containers/common/pkg/config" "github.com/containers/common/pkg/config"
"github.com/containers/libpod/cmd/podman/common" "github.com/containers/libpod/cmd/podman/common"
@ -106,6 +108,10 @@ func create(cmd *cobra.Command, args []string) error {
return err return err
} }
if _, err := createPodIfNecessary(s); err != nil {
return err
}
report, err := registry.ContainerEngine().ContainerCreate(registry.GetContext(), s) report, err := registry.ContainerEngine().ContainerCreate(registry.GetContext(), s)
if err != nil { if err != nil {
return err return err
@ -160,6 +166,10 @@ func createInit(c *cobra.Command) error {
if c.Flag("cgroupns").Changed { if c.Flag("cgroupns").Changed {
cliVals.CGroupsNS = c.Flag("cgroupns").Value.String() cliVals.CGroupsNS = c.Flag("cgroupns").Value.String()
} }
if c.Flag("entrypoint").Changed {
val := c.Flag("entrypoint").Value.String()
cliVals.Entrypoint = &val
}
// Docker-compatibility: the "-h" flag for run/create is reserved for // Docker-compatibility: the "-h" flag for run/create is reserved for
// the hostname (see https://github.com/containers/libpod/issues/1367). // the hostname (see https://github.com/containers/libpod/issues/1367).
@ -181,8 +191,10 @@ func pullImage(imageName string) error {
return errors.New("unable to find a name and tag match for busybox in repotags: no such image") return errors.New("unable to find a name and tag match for busybox in repotags: no such image")
} }
_, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{ _, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
Authfile: cliVals.Authfile, Authfile: cliVals.Authfile,
Quiet: cliVals.Quiet, Quiet: cliVals.Quiet,
OverrideArch: cliVals.OverrideArch,
OverrideOS: cliVals.OverrideOS,
}) })
if pullErr != nil { if pullErr != nil {
return pullErr return pullErr
@ -204,3 +216,25 @@ func openCidFile(cidfile string) (*os.File, error) {
} }
return cidFile, nil return cidFile, nil
} }
// createPodIfNecessary automatically creates a pod when requested. if the pod name
// has the form new:ID, the pod ID is created and the name in the spec generator is replaced
// with ID.
func createPodIfNecessary(s *specgen.SpecGenerator) (*entities.PodCreateReport, error) {
if !strings.HasPrefix(s.Pod, "new:") {
return nil, nil
}
podName := strings.Replace(s.Pod, "new:", "", 1)
if len(podName) < 1 {
return nil, errors.Errorf("new pod name must be at least one character")
}
createOptions := entities.PodCreateOptions{
Name: podName,
Infra: true,
Net: &entities.NetOptions{
PublishPorts: s.PortMappings,
},
}
s.Pod = podName
return registry.ContainerEngine().PodCreate(context.Background(), createOptions)
}

View File

@ -146,6 +146,10 @@ func run(cmd *cobra.Command, args []string) error {
} }
runOpts.Spec = s runOpts.Spec = s
if _, err := createPodIfNecessary(s); err != nil {
return err
}
report, err := registry.ContainerEngine().ContainerRun(registry.GetContext(), runOpts) report, err := registry.ContainerEngine().ContainerRun(registry.GetContext(), runOpts)
// report.ExitCode is set by ContainerRun even it it returns an error // report.ExitCode is set by ContainerRun even it it returns an error
if report != nil { if report != nil {

View File

@ -99,7 +99,7 @@ func start(cmd *cobra.Command, args []string) error {
for _, r := range responses { for _, r := range responses {
if r.Err == nil { if r.Err == nil {
fmt.Println(r.Id) fmt.Println(r.RawInput)
} else { } else {
errs = append(errs, r.Err) errs = append(errs, r.Err)
} }

View File

@ -227,6 +227,7 @@ type ContainerStartOptions struct {
// containers from the cli // containers from the cli
type ContainerStartReport struct { type ContainerStartReport struct {
Id string Id string
RawInput string
Err error Err error
ExitCode int ExitCode int
} }

View File

@ -32,9 +32,9 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// getContainersByContext gets pods whether all, latest, or a slice of names/ids // getContainersAndInputByContext gets containers whether all, latest, or a slice of names/ids
// is specified. // is specified. It also returns a list of the corresponding input name used to lookup each container.
func getContainersByContext(all, latest bool, names []string, runtime *libpod.Runtime) (ctrs []*libpod.Container, err error) { func getContainersAndInputByContext(all, latest bool, names []string, runtime *libpod.Runtime) (ctrs []*libpod.Container, rawInput []string, err error) {
var ctr *libpod.Container var ctr *libpod.Container
ctrs = []*libpod.Container{} ctrs = []*libpod.Container{}
@ -43,6 +43,7 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
ctrs, err = runtime.GetAllContainers() ctrs, err = runtime.GetAllContainers()
case latest: case latest:
ctr, err = runtime.GetLatestContainer() ctr, err = runtime.GetLatestContainer()
rawInput = append(rawInput, ctr.ID())
ctrs = append(ctrs, ctr) ctrs = append(ctrs, ctr)
default: default:
for _, n := range names { for _, n := range names {
@ -54,6 +55,7 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
err = e err = e
} }
} else { } else {
rawInput = append(rawInput, n)
ctrs = append(ctrs, ctr) ctrs = append(ctrs, ctr)
} }
} }
@ -61,6 +63,13 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
return return
} }
// getContainersByContext gets containers whether all, latest, or a slice of names/ids
// is specified.
func getContainersByContext(all, latest bool, names []string, runtime *libpod.Runtime) (ctrs []*libpod.Container, err error) {
ctrs, _, err = getContainersAndInputByContext(all, latest, names, runtime)
return
}
// TODO: Should return *entities.ContainerExistsReport, error // TODO: Should return *entities.ContainerExistsReport, error
func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) { func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrId string) (*entities.BoolReport, error) {
_, err := ic.Libpod.LookupContainer(nameOrId) _, err := ic.Libpod.LookupContainer(nameOrId)
@ -555,12 +564,14 @@ func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, o
func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
var reports []*entities.ContainerStartReport var reports []*entities.ContainerStartReport
var exitCode = define.ExecErrorCodeGeneric var exitCode = define.ExecErrorCodeGeneric
ctrs, err := getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod) ctrs, rawInputs, err := getContainersAndInputByContext(false, options.Latest, namesOrIds, ic.Libpod)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// There can only be one container if attach was used // There can only be one container if attach was used
for _, ctr := range ctrs { for i := range ctrs {
ctr := ctrs[i]
rawInput := rawInputs[i]
ctrState, err := ctr.State() ctrState, err := ctr.State()
if err != nil { if err != nil {
return nil, err return nil, err
@ -574,6 +585,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
// Exit cleanly immediately // Exit cleanly immediately
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
RawInput: rawInput,
Err: nil, Err: nil,
ExitCode: 0, ExitCode: 0,
}) })
@ -584,6 +596,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
logrus.Debugf("Deadlock error: %v", err) logrus.Debugf("Deadlock error: %v", err)
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
RawInput: rawInput,
Err: err, Err: err,
ExitCode: define.ExitCode(err), ExitCode: define.ExitCode(err),
}) })
@ -593,6 +606,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
if ctrRunning { if ctrRunning {
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
RawInput: rawInput,
Err: nil, Err: nil,
ExitCode: 0, ExitCode: 0,
}) })
@ -602,6 +616,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
if err != nil { if err != nil {
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
RawInput: rawInput,
Err: err, Err: err,
ExitCode: exitCode, ExitCode: exitCode,
}) })
@ -624,6 +639,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
} }
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
RawInput: rawInput,
Err: err, Err: err,
ExitCode: exitCode, ExitCode: exitCode,
}) })
@ -636,6 +652,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
// If the container is in a pod, also set to recursively start dependencies // If the container is in a pod, also set to recursively start dependencies
report := &entities.ContainerStartReport{ report := &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
RawInput: rawInput,
ExitCode: 125, ExitCode: 125,
} }
if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil { if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {

View File

@ -24,11 +24,10 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
// If joining a pod, retrieve the pod for use. // If joining a pod, retrieve the pod for use.
var pod *libpod.Pod var pod *libpod.Pod
if s.Pod != "" { if s.Pod != "" {
foundPod, err := rt.LookupPod(s.Pod) pod, err = rt.LookupPod(s.Pod)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error retrieving pod %s", s.Pod) return nil, errors.Wrapf(err, "error retrieving pod %s", s.Pod)
} }
pod = foundPod
} }
// Set defaults for unset namespaces // Set defaults for unset namespaces
@ -130,12 +129,8 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
logrus.Debugf("setting container name %s", s.Name) logrus.Debugf("setting container name %s", s.Name)
options = append(options, libpod.WithName(s.Name)) options = append(options, libpod.WithName(s.Name))
} }
if s.Pod != "" { if pod != nil {
pod, err := rt.LookupPod(s.Pod) logrus.Debugf("adding container to pod %s", pod.Name())
if err != nil {
return nil, err
}
logrus.Debugf("adding container to pod %s", s.Pod)
options = append(options, rt.WithPod(pod)) options = append(options, rt.WithPod(pod))
} }
destinations := []string{} destinations := []string{}
@ -160,11 +155,12 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
options = append(options, libpod.WithNamedVolumes(vols)) options = append(options, libpod.WithNamedVolumes(vols))
} }
if len(s.Command) != 0 { if s.Command != nil {
options = append(options, libpod.WithCommand(s.Command)) options = append(options, libpod.WithCommand(s.Command))
} }
if s.Entrypoint != nil {
options = append(options, libpod.WithEntrypoint(s.Entrypoint)) options = append(options, libpod.WithEntrypoint(s.Entrypoint))
}
if s.StopSignal != nil { if s.StopSignal != nil {
options = append(options, libpod.WithStopSignal(*s.StopSignal)) options = append(options, libpod.WithStopSignal(*s.StopSignal))
} }

View File

@ -67,7 +67,7 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image
finalCommand = append(finalCommand, entrypoint...) finalCommand = append(finalCommand, entrypoint...)
command := s.Command command := s.Command
if len(command) == 0 && img != nil { if command == nil && img != nil {
newCmd, err := img.Cmd(ctx) newCmd, err := img.Cmd(ctx)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -18,7 +18,6 @@ var _ = Describe("Podman create", func() {
) )
BeforeEach(func() { BeforeEach(func() {
Skip(v2fail)
tempdir, err = CreateTempDirInTempDir() tempdir, err = CreateTempDirInTempDir()
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)

View File

@ -18,7 +18,6 @@ var _ = Describe("Podman run entrypoint", func() {
) )
BeforeEach(func() { BeforeEach(func() {
Skip(v2fail)
tempdir, err = CreateTempDirInTempDir() tempdir, err = CreateTempDirInTempDir()
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)

View File

@ -634,7 +634,6 @@ USER mail`
}) })
It("podman run --volumes-from flag with built-in volumes", func() { It("podman run --volumes-from flag with built-in volumes", func() {
Skip(v2fail)
session := podmanTest.Podman([]string{"create", redis, "sh"}) session := podmanTest.Podman([]string{"create", redis, "sh"})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0)) Expect(session.ExitCode()).To(Equal(0))
@ -729,7 +728,6 @@ USER mail`
}) })
It("podman run --pod automatically", func() { It("podman run --pod automatically", func() {
Skip(v2fail)
session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", ALPINE, "ls"}) session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", ALPINE, "ls"})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0)) Expect(session.ExitCode()).To(Equal(0))

View File

@ -17,7 +17,6 @@ var _ = Describe("Podman start", func() {
) )
BeforeEach(func() { BeforeEach(func() {
Skip(v2fail)
tempdir, err = CreateTempDirInTempDir() tempdir, err = CreateTempDirInTempDir()
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)
@ -66,10 +65,11 @@ var _ = Describe("Podman start", func() {
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0)) Expect(session.ExitCode()).To(Equal(0))
cid := session.OutputToString() cid := session.OutputToString()
session = podmanTest.Podman([]string{"container", "start", cid[0:10]}) shortID := cid[0:10]
session = podmanTest.Podman([]string{"container", "start", shortID})
session.WaitWithDefaultTimeout() session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0)) Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal(cid)) Expect(session.OutputToString()).To(Equal(shortID))
}) })
It("podman start single container by name", func() { It("podman start single container by name", func() {