Skip to content

Commit

Permalink
Improve Entrypoint and Command support
Browse files Browse the repository at this point in the history
We should not be overwriting the Specgen's Command and Entrypoint
when building the final command to pass in the OCI spec. Both of
these will be provided to Libpod for use in `podman inspect` and
committing containers, and both must be set to the user's input,
not overwritten by the image if unset.

Fix this by moving command generation into OCI spec generation
and not modifying the SpecGenerator when we do so.

Signed-off-by: Matthew Heon <[email protected]>
  • Loading branch information
mheon committed Apr 27, 2020
1 parent 02671a1 commit 67ec4e1
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 37 deletions.
25 changes: 0 additions & 25 deletions pkg/specgen/generate/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,10 @@ import (
envLib "github.com/containers/libpod/pkg/env"
"github.com/containers/libpod/pkg/signal"
"github.com/containers/libpod/pkg/specgen"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)

func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) error {
var appendEntryPoint bool

// If a rootfs is used, then there is no image data
if s.ContainerStorageConfig.Rootfs != "" {
return nil
Expand Down Expand Up @@ -107,28 +104,6 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
}
s.Annotations = annotations

// entrypoint
entrypoint, err := newImage.Entrypoint(ctx)
if err != nil {
return err
}
if len(s.Entrypoint) < 1 && len(entrypoint) > 0 {
appendEntryPoint = true
s.Entrypoint = entrypoint
}
command, err := newImage.Cmd(ctx)
if err != nil {
return err
}
if len(s.Command) < 1 && len(command) > 0 {
if appendEntryPoint {
s.Command = entrypoint
}
s.Command = append(s.Command, command...)
}
if len(s.Command) < 1 && len(s.Entrypoint) < 1 {
return errors.Errorf("No command provided or as CMD or ENTRYPOINT in this image")
}
// workdir
workingDir, err := newImage.WorkingDir(ctx)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/specgen/generate/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
}
options = append(options, createExitCommandOption(s, rt.StorageConfig(), rtc, podmanPath))

runtimeSpec, err := SpecGenToOCI(s, rt, rtc, newImage, finalMounts)
runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts)
if err != nil {
return nil, err
}
Expand Down
64 changes: 53 additions & 11 deletions pkg/specgen/generate/oci.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package generate

import (
"context"
"strings"

"github.com/containers/common/pkg/config"
Expand All @@ -11,6 +12,7 @@ import (
"github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
)

func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
Expand Down Expand Up @@ -49,7 +51,51 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) error {
return nil
}

func SpecGenToOCI(s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount) (*spec.Spec, error) {
// Produce the final command for the container.
func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image, rtc *config.Config) ([]string, error) {
finalCommand := []string{}

entrypoint := s.Entrypoint
if len(entrypoint) == 0 && img != nil {
newEntry, err := img.Entrypoint(ctx)
if err != nil {
return nil, err
}
entrypoint = newEntry
}

finalCommand = append(finalCommand, entrypoint...)

command := s.Command
if len(command) == 0 && img != nil {
newCmd, err := img.Cmd(ctx)
if err != nil {
return nil, err
}
command = newCmd
}

finalCommand = append(finalCommand, command...)

if len(finalCommand) == 0 {
return nil, errors.Errorf("no command or entrypoint provided, and no CMD or ENTRYPOINT from image")
}

if s.Init {
initPath := s.InitPath
if initPath == "" && rtc != nil {
initPath = rtc.Engine.InitPath
}
if initPath == "" {
return nil, errors.Errorf("no path to init binary found but container requested an init")
}
finalCommand = append([]string{initPath, "--"}, finalCommand...)
}

return finalCommand, nil
}

func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *image.Image, mounts []spec.Mount) (*spec.Spec, error) {
var (
inUserNS bool
)
Expand Down Expand Up @@ -174,17 +220,13 @@ func SpecGenToOCI(s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Conf
g.AddMount(cgroupMnt)
}
g.SetProcessCwd(s.WorkDir)
if s.Init {
initPath := s.InitPath
if initPath == "" && rtc != nil {
initPath = rtc.Engine.InitPath
}
cmd := []string{initPath, "--"}
cmd = append(cmd, s.Command...)
g.SetProcessArgs(cmd)
} else {
g.SetProcessArgs(s.Command)

finalCmd, err := makeCommand(ctx, s, newImage, rtc)
if err != nil {
return nil, err
}
g.SetProcessArgs(finalCmd)

g.SetProcessTerminal(s.Terminal)

for key, val := range s.Annotations {
Expand Down

0 comments on commit 67ec4e1

Please sign in to comment.