InfraContainer Rework
InfraContainer should go through the same creation process as regular containers. This change was from the cmd level down, involving new container CLI opts and specgen creating functions. What now happens is that both container and pod cli options are populated in cmd and used to create a podSpecgen and a containerSpecgen. The process then goes as follows FillOutSpecGen (infra) -> MapSpec (podOpts -> infraOpts) -> PodCreate -> MakePod -> createPodOptions -> NewPod -> CompleteSpec (infra) -> MakeContainer -> NewContainer -> newContainer -> AddInfra (to pod state) Signed-off-by: cdoern <cdoern@redhat.com>
This commit is contained in:
parent
94c37d7d47
commit
d28e85741f
File diff suppressed because it is too large
Load Diff
|
@ -19,122 +19,6 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContainerCLIOpts struct {
|
|
||||||
Annotation []string
|
|
||||||
Attach []string
|
|
||||||
Authfile string
|
|
||||||
BlkIOWeight string
|
|
||||||
BlkIOWeightDevice []string
|
|
||||||
CapAdd []string
|
|
||||||
CapDrop []string
|
|
||||||
CgroupNS string
|
|
||||||
CGroupsMode string
|
|
||||||
CGroupParent string
|
|
||||||
CIDFile string
|
|
||||||
ConmonPIDFile string
|
|
||||||
CPUPeriod uint64
|
|
||||||
CPUQuota int64
|
|
||||||
CPURTPeriod uint64
|
|
||||||
CPURTRuntime int64
|
|
||||||
CPUShares uint64
|
|
||||||
CPUS float64
|
|
||||||
CPUSetCPUs string
|
|
||||||
CPUSetMems string
|
|
||||||
Devices []string
|
|
||||||
DeviceCGroupRule []string
|
|
||||||
DeviceReadBPs []string
|
|
||||||
DeviceReadIOPs []string
|
|
||||||
DeviceWriteBPs []string
|
|
||||||
DeviceWriteIOPs []string
|
|
||||||
Entrypoint *string
|
|
||||||
Env []string
|
|
||||||
EnvHost bool
|
|
||||||
EnvFile []string
|
|
||||||
Expose []string
|
|
||||||
GIDMap []string
|
|
||||||
GroupAdd []string
|
|
||||||
HealthCmd string
|
|
||||||
HealthInterval string
|
|
||||||
HealthRetries uint
|
|
||||||
HealthStartPeriod string
|
|
||||||
HealthTimeout string
|
|
||||||
Hostname string
|
|
||||||
HTTPProxy bool
|
|
||||||
ImageVolume string
|
|
||||||
Init bool
|
|
||||||
InitContainerType string
|
|
||||||
InitPath string
|
|
||||||
Interactive bool
|
|
||||||
IPC string
|
|
||||||
KernelMemory string
|
|
||||||
Label []string
|
|
||||||
LabelFile []string
|
|
||||||
LogDriver string
|
|
||||||
LogOptions []string
|
|
||||||
Memory string
|
|
||||||
MemoryReservation string
|
|
||||||
MemorySwap string
|
|
||||||
MemorySwappiness int64
|
|
||||||
Name string
|
|
||||||
NoHealthCheck bool
|
|
||||||
OOMKillDisable bool
|
|
||||||
OOMScoreAdj int
|
|
||||||
Arch string
|
|
||||||
OS string
|
|
||||||
Variant string
|
|
||||||
Personality string
|
|
||||||
PID string
|
|
||||||
PIDsLimit *int64
|
|
||||||
Platform string
|
|
||||||
Pod string
|
|
||||||
PodIDFile string
|
|
||||||
PreserveFDs uint
|
|
||||||
Privileged bool
|
|
||||||
PublishAll bool
|
|
||||||
Pull string
|
|
||||||
Quiet bool
|
|
||||||
ReadOnly bool
|
|
||||||
ReadOnlyTmpFS bool
|
|
||||||
Restart string
|
|
||||||
Replace bool
|
|
||||||
Requires []string
|
|
||||||
Rm bool
|
|
||||||
RootFS bool
|
|
||||||
Secrets []string
|
|
||||||
SecurityOpt []string
|
|
||||||
SdNotifyMode string
|
|
||||||
ShmSize string
|
|
||||||
SignaturePolicy string
|
|
||||||
StopSignal string
|
|
||||||
StopTimeout uint
|
|
||||||
StorageOpt []string
|
|
||||||
SubUIDName string
|
|
||||||
SubGIDName string
|
|
||||||
Sysctl []string
|
|
||||||
Systemd string
|
|
||||||
Timeout uint
|
|
||||||
TLSVerify bool
|
|
||||||
TmpFS []string
|
|
||||||
TTY bool
|
|
||||||
Timezone string
|
|
||||||
Umask string
|
|
||||||
UIDMap []string
|
|
||||||
Ulimit []string
|
|
||||||
User string
|
|
||||||
UserNS string
|
|
||||||
UTS string
|
|
||||||
Mount []string
|
|
||||||
Volume []string
|
|
||||||
VolumesFrom []string
|
|
||||||
Workdir string
|
|
||||||
SeccompPolicy string
|
|
||||||
PidFile string
|
|
||||||
|
|
||||||
Net *entities.NetOptions
|
|
||||||
|
|
||||||
CgroupConf []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringMaptoArray(m map[string]string) []string {
|
func stringMaptoArray(m map[string]string) []string {
|
||||||
a := make([]string, 0, len(m))
|
a := make([]string, 0, len(m))
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
|
@ -145,7 +29,7 @@ func stringMaptoArray(m map[string]string) []string {
|
||||||
|
|
||||||
// ContainerCreateToContainerCLIOpts converts a compat input struct to cliopts so it can be converted to
|
// ContainerCreateToContainerCLIOpts converts a compat input struct to cliopts so it can be converted to
|
||||||
// a specgen spec.
|
// a specgen spec.
|
||||||
func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*ContainerCLIOpts, []string, error) {
|
func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.ContainerCreateOptions, []string, error) {
|
||||||
var (
|
var (
|
||||||
capAdd []string
|
capAdd []string
|
||||||
cappDrop []string
|
cappDrop []string
|
||||||
|
@ -341,7 +225,7 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
|
||||||
// Note: several options here are marked as "don't need". this is based
|
// Note: several options here are marked as "don't need". this is based
|
||||||
// on speculation by Matt and I. We think that these come into play later
|
// on speculation by Matt and I. We think that these come into play later
|
||||||
// like with start. We believe this is just a difference in podman/compat
|
// like with start. We believe this is just a difference in podman/compat
|
||||||
cliOpts := ContainerCLIOpts{
|
cliOpts := entities.ContainerCreateOptions{
|
||||||
// Attach: nil, // don't need?
|
// Attach: nil, // don't need?
|
||||||
Authfile: "",
|
Authfile: "",
|
||||||
CapAdd: append(capAdd, cc.HostConfig.CapAdd...),
|
CapAdd: append(capAdd, cc.HostConfig.CapAdd...),
|
||||||
|
|
|
@ -8,8 +8,10 @@ import (
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DefineNetFlags(cmd *cobra.Command) {
|
func DefineNetFlags(cmd *cobra.Command) {
|
||||||
|
@ -87,12 +89,15 @@ func DefineNetFlags(cmd *cobra.Command) {
|
||||||
// NetFlagsToNetOptions parses the network flags for the given cmd.
|
// NetFlagsToNetOptions parses the network flags for the given cmd.
|
||||||
// The netnsFromConfig bool is used to indicate if the --network flag
|
// The netnsFromConfig bool is used to indicate if the --network flag
|
||||||
// should always be parsed regardless if it was set on the cli.
|
// should always be parsed regardless if it was set on the cli.
|
||||||
func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.NetOptions, error) {
|
func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet, netnsFromConfig bool) (*entities.NetOptions, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
opts := entities.NetOptions{}
|
if opts == nil {
|
||||||
opts.AddHosts, err = cmd.Flags().GetStringSlice("add-host")
|
opts = &entities.NetOptions{}
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.AddHosts, err = flags.GetStringSlice("add-host")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -103,56 +108,50 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.Flags().Changed("dns") {
|
servers, err := flags.GetStringSlice("dns")
|
||||||
servers, err := cmd.Flags().GetStringSlice("dns")
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
}
|
||||||
}
|
for _, d := range servers {
|
||||||
for _, d := range servers {
|
if d == "none" {
|
||||||
if d == "none" {
|
opts.UseImageResolvConf = true
|
||||||
opts.UseImageResolvConf = true
|
if len(servers) > 1 {
|
||||||
if len(servers) > 1 {
|
return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d)
|
||||||
return nil, errors.Errorf("%s is not allowed to be specified with other DNS ip addresses", d)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
dns := net.ParseIP(d)
|
break
|
||||||
if dns == nil {
|
|
||||||
return nil, errors.Errorf("%s is not an ip address", d)
|
|
||||||
}
|
|
||||||
opts.DNSServers = append(opts.DNSServers, dns)
|
|
||||||
}
|
}
|
||||||
|
dns := net.ParseIP(d)
|
||||||
|
if dns == nil {
|
||||||
|
return nil, errors.Errorf("%s is not an ip address", d)
|
||||||
|
}
|
||||||
|
opts.DNSServers = append(opts.DNSServers, dns)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.Flags().Changed("dns-opt") {
|
options, err := flags.GetStringSlice("dns-opt")
|
||||||
options, err := cmd.Flags().GetStringSlice("dns-opt")
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
|
}
|
||||||
|
opts.DNSOptions = options
|
||||||
|
|
||||||
|
dnsSearches, err := 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
|
return nil, err
|
||||||
}
|
}
|
||||||
opts.DNSOptions = options
|
|
||||||
}
|
}
|
||||||
|
opts.DNSSearch = dnsSearches
|
||||||
|
|
||||||
if cmd.Flags().Changed("dns-search") {
|
m, err := flags.GetString("mac-address")
|
||||||
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")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -164,18 +163,18 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
|
||||||
opts.StaticMAC = &mac
|
opts.StaticMAC = &mac
|
||||||
}
|
}
|
||||||
|
|
||||||
inputPorts, err := cmd.Flags().GetStringSlice("publish")
|
inputPorts, err := flags.GetStringSlice("publish")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(inputPorts) > 0 {
|
if len(inputPorts) > 0 {
|
||||||
opts.PublishPorts, err = CreatePortBindings(inputPorts)
|
opts.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ip, err := cmd.Flags().GetString("ip")
|
ip, err := flags.GetString("ip")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -190,15 +189,15 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
|
||||||
opts.StaticIP = &staticIP
|
opts.StaticIP = &staticIP
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.NoHosts, err = cmd.Flags().GetBool("no-hosts")
|
opts.NoHosts, err = flags.GetBool("no-hosts")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the --network value only when the flag is set or we need to use
|
// parse the --network value only when the flag is set or we need to use
|
||||||
// the netns config value, e.g. when --pod is not used
|
// the netns config value, e.g. when --pod is not used
|
||||||
if netnsFromConfig || cmd.Flag("network").Changed {
|
if netnsFromConfig || flags.Changed("network") {
|
||||||
network, err := cmd.Flags().GetString("network")
|
network, err := flags.GetString("network")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -215,12 +214,13 @@ func NetFlagsToNetOptions(cmd *cobra.Command, netnsFromConfig bool) (*entities.N
|
||||||
opts.CNINetworks = cniNets
|
opts.CNINetworks = cniNets
|
||||||
}
|
}
|
||||||
|
|
||||||
aliases, err := cmd.Flags().GetStringSlice("network-alias")
|
aliases, err := flags.GetStringSlice("network-alias")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(aliases) > 0 {
|
if len(aliases) > 0 {
|
||||||
opts.Aliases = aliases
|
opts.Aliases = aliases
|
||||||
}
|
}
|
||||||
return &opts, err
|
|
||||||
|
return opts, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -52,8 +53,8 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cliVals common.ContainerCLIOpts
|
|
||||||
InitContainerType string
|
InitContainerType string
|
||||||
|
cliVals entities.ContainerCreateOptions
|
||||||
)
|
)
|
||||||
|
|
||||||
func createFlags(cmd *cobra.Command) {
|
func createFlags(cmd *cobra.Command) {
|
||||||
|
@ -67,13 +68,18 @@ func createFlags(cmd *cobra.Command) {
|
||||||
)
|
)
|
||||||
|
|
||||||
flags.SetInterspersed(false)
|
flags.SetInterspersed(false)
|
||||||
common.DefineCreateFlags(cmd, &cliVals)
|
common.DefineCreateFlags(cmd, &cliVals, false)
|
||||||
common.DefineNetFlags(cmd)
|
common.DefineNetFlags(cmd)
|
||||||
|
|
||||||
flags.SetNormalizeFunc(utils.AliasFlags)
|
flags.SetNormalizeFunc(utils.AliasFlags)
|
||||||
|
|
||||||
if registry.IsRemote() {
|
if registry.IsRemote() {
|
||||||
_ = flags.MarkHidden("conmon-pidfile")
|
if cliVals.IsInfra {
|
||||||
|
_ = flags.MarkHidden("infra-conmon-pidfile")
|
||||||
|
} else {
|
||||||
|
_ = flags.MarkHidden("conmon-pidfile")
|
||||||
|
}
|
||||||
|
|
||||||
_ = flags.MarkHidden("pidfile")
|
_ = flags.MarkHidden("pidfile")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +103,8 @@ func create(cmd *cobra.Command, args []string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
cliVals.Net, err = common.NetFlagsToNetOptions(cmd, cliVals.Pod == "" && cliVals.PodIDFile == "")
|
flags := cmd.Flags()
|
||||||
|
cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, cliVals.Pod == "" && cliVals.PodIDFile == "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -113,22 +120,22 @@ func create(cmd *cobra.Command, args []string) error {
|
||||||
cliVals.InitContainerType = initctr
|
cliVals.InitContainerType = initctr
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createInit(cmd); err != nil {
|
cliVals, err = CreateInit(cmd, cliVals, false)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
imageName := args[0]
|
imageName := args[0]
|
||||||
rawImageName := ""
|
rawImageName := ""
|
||||||
if !cliVals.RootFS {
|
if !cliVals.RootFS {
|
||||||
rawImageName = args[0]
|
rawImageName = args[0]
|
||||||
name, err := pullImage(args[0])
|
name, err := PullImage(args[0], cliVals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
imageName = name
|
imageName = name
|
||||||
}
|
}
|
||||||
s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
|
s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
|
||||||
if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
|
if err := specgenutil.FillOutSpecGen(s, &cliVals, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.RawImageName = rawImageName
|
s.RawImageName = rawImageName
|
||||||
|
@ -169,100 +176,101 @@ func replaceContainer(name string) error {
|
||||||
return removeContainers([]string{name}, rmOptions, false)
|
return removeContainers([]string{name}, rmOptions, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createInit(c *cobra.Command) error {
|
func CreateInit(c *cobra.Command, vals entities.ContainerCreateOptions, isInfra bool) (entities.ContainerCreateOptions, error) {
|
||||||
cliVals.StorageOpt = registry.PodmanConfig().StorageOpts
|
vals.UserNS = c.Flag("userns").Value.String()
|
||||||
|
|
||||||
if c.Flag("shm-size").Changed {
|
|
||||||
cliVals.ShmSize = c.Flag("shm-size").Value.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.Flag("dns").Changed || c.Flag("dns-opt").Changed || c.Flag("dns-search").Changed) && (cliVals.Net.Network.NSMode == specgen.NoNetwork || cliVals.Net.Network.IsContainer()) {
|
|
||||||
return errors.Errorf("conflicting options: dns and the network mode.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed {
|
|
||||||
return errors.Errorf("--cpu-period and --cpus cannot be set together")
|
|
||||||
}
|
|
||||||
if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed {
|
|
||||||
return errors.Errorf("--cpu-quota and --cpus cannot be set together")
|
|
||||||
}
|
|
||||||
if c.Flag("pod").Changed && !strings.HasPrefix(c.Flag("pod").Value.String(), "new:") && c.Flag("userns").Changed {
|
|
||||||
return errors.Errorf("--userns and --pod cannot be set together")
|
|
||||||
}
|
|
||||||
|
|
||||||
noHosts, err := c.Flags().GetBool("no-hosts")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if noHosts && c.Flag("add-host").Changed {
|
|
||||||
return errors.Errorf("--no-hosts and --add-host cannot be set together")
|
|
||||||
}
|
|
||||||
cliVals.UserNS = c.Flag("userns").Value.String()
|
|
||||||
// if user did not modify --userns flag and did turn on
|
// if user did not modify --userns flag and did turn on
|
||||||
// uid/gid mappings, set userns flag to "private"
|
// uid/gid mappings, set userns flag to "private"
|
||||||
if !c.Flag("userns").Changed && cliVals.UserNS == "host" {
|
if !c.Flag("userns").Changed && vals.UserNS == "host" {
|
||||||
if len(cliVals.UIDMap) > 0 ||
|
if len(vals.UIDMap) > 0 ||
|
||||||
len(cliVals.GIDMap) > 0 ||
|
len(vals.GIDMap) > 0 ||
|
||||||
cliVals.SubUIDName != "" ||
|
vals.SubUIDName != "" ||
|
||||||
cliVals.SubGIDName != "" {
|
vals.SubGIDName != "" {
|
||||||
cliVals.UserNS = "private"
|
vals.UserNS = "private"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cliVals.IPC = c.Flag("ipc").Value.String()
|
if !isInfra {
|
||||||
cliVals.UTS = c.Flag("uts").Value.String()
|
if c.Flag("shm-size").Changed {
|
||||||
cliVals.PID = c.Flag("pid").Value.String()
|
vals.ShmSize = c.Flag("shm-size").Value.String()
|
||||||
cliVals.CgroupNS = c.Flag("cgroupns").Value.String()
|
}
|
||||||
if c.Flag("entrypoint").Changed {
|
if c.Flag("cpu-period").Changed && c.Flag("cpus").Changed {
|
||||||
val := c.Flag("entrypoint").Value.String()
|
return vals, errors.Errorf("--cpu-period and --cpus cannot be set together")
|
||||||
cliVals.Entrypoint = &val
|
}
|
||||||
}
|
if c.Flag("cpu-quota").Changed && c.Flag("cpus").Changed {
|
||||||
|
return vals, errors.Errorf("--cpu-quota and --cpus cannot be set together")
|
||||||
|
}
|
||||||
|
vals.IPC = c.Flag("ipc").Value.String()
|
||||||
|
vals.UTS = c.Flag("uts").Value.String()
|
||||||
|
vals.PID = c.Flag("pid").Value.String()
|
||||||
|
vals.CgroupNS = c.Flag("cgroupns").Value.String()
|
||||||
|
|
||||||
if c.Flags().Changed("group-add") {
|
if c.Flags().Changed("group-add") {
|
||||||
groups := []string{}
|
groups := []string{}
|
||||||
for _, g := range cliVals.GroupAdd {
|
for _, g := range cliVals.GroupAdd {
|
||||||
if g == "keep-groups" {
|
if g == "keep-groups" {
|
||||||
if len(cliVals.GroupAdd) > 1 {
|
if len(cliVals.GroupAdd) > 1 {
|
||||||
return errors.New("the '--group-add keep-groups' option is not allowed with any other --group-add options")
|
return vals, errors.New("the '--group-add keep-groups' option is not allowed with any other --group-add options")
|
||||||
|
}
|
||||||
|
if registry.IsRemote() {
|
||||||
|
return vals, errors.New("the '--group-add keep-groups' option is not supported in remote mode")
|
||||||
|
}
|
||||||
|
vals.Annotation = append(vals.Annotation, "run.oci.keep_original_groups=1")
|
||||||
|
} else {
|
||||||
|
groups = append(groups, g)
|
||||||
}
|
}
|
||||||
if registry.IsRemote() {
|
|
||||||
return errors.New("the '--group-add keep-groups' option is not supported in remote mode")
|
|
||||||
}
|
|
||||||
cliVals.Annotation = append(cliVals.Annotation, "run.oci.keep_original_groups=1")
|
|
||||||
} else {
|
|
||||||
groups = append(groups, g)
|
|
||||||
}
|
}
|
||||||
|
vals.GroupAdd = groups
|
||||||
}
|
}
|
||||||
cliVals.GroupAdd = groups
|
|
||||||
|
if c.Flags().Changed("pids-limit") {
|
||||||
|
val := c.Flag("pids-limit").Value.String()
|
||||||
|
pidsLimit, err := strconv.ParseInt(val, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return vals, err
|
||||||
|
}
|
||||||
|
vals.PIDsLimit = &pidsLimit
|
||||||
|
}
|
||||||
|
if c.Flags().Changed("env") {
|
||||||
|
env, err := c.Flags().GetStringArray("env")
|
||||||
|
if err != nil {
|
||||||
|
return vals, errors.Wrapf(err, "retrieve env flag")
|
||||||
|
}
|
||||||
|
vals.Env = env
|
||||||
|
}
|
||||||
|
if c.Flag("cgroups").Changed && vals.CGroupsMode == "split" && registry.IsRemote() {
|
||||||
|
return vals, errors.Errorf("the option --cgroups=%q is not supported in remote mode", vals.CGroupsMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Flag("pod").Changed && !strings.HasPrefix(c.Flag("pod").Value.String(), "new:") && c.Flag("userns").Changed {
|
||||||
|
return vals, errors.Errorf("--userns and --pod cannot be set together")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c.Flag("dns").Changed || c.Flag("dns-opt").Changed || c.Flag("dns-search").Changed) && vals.Net != nil && (vals.Net.Network.NSMode == specgen.NoNetwork || vals.Net.Network.IsContainer()) {
|
||||||
|
return vals, errors.Errorf("conflicting options: dns and the network mode: " + string(vals.Net.Network.NSMode))
|
||||||
|
}
|
||||||
|
noHosts, err := c.Flags().GetBool("no-hosts")
|
||||||
|
if err != nil {
|
||||||
|
return vals, err
|
||||||
|
}
|
||||||
|
if noHosts && c.Flag("add-host").Changed {
|
||||||
|
return vals, errors.Errorf("--no-hosts and --add-host cannot be set together")
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Flags().Changed("pids-limit") {
|
if !isInfra && c.Flag("entrypoint").Changed {
|
||||||
val := c.Flag("pids-limit").Value.String()
|
val := c.Flag("entrypoint").Value.String()
|
||||||
pidsLimit, err := strconv.ParseInt(val, 10, 32)
|
vals.Entrypoint = &val
|
||||||
if err != nil {
|
} else if isInfra && c.Flag("infra-command").Changed {
|
||||||
return err
|
|
||||||
}
|
|
||||||
cliVals.PIDsLimit = &pidsLimit
|
|
||||||
}
|
|
||||||
if c.Flags().Changed("env") {
|
|
||||||
env, err := c.Flags().GetStringArray("env")
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "retrieve env flag")
|
|
||||||
}
|
|
||||||
cliVals.Env = env
|
|
||||||
}
|
|
||||||
if c.Flag("cgroups").Changed && cliVals.CGroupsMode == "split" && registry.IsRemote() {
|
|
||||||
return errors.Errorf("the option --cgroups=%q is not supported in remote mode", cliVals.CGroupsMode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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/podman/issues/1367).
|
// the hostname (see https://github.com/containers/podman/issues/1367).
|
||||||
|
|
||||||
return nil
|
return vals, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func pullImage(imageName string) (string, error) {
|
func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (string, error) {
|
||||||
pullPolicy, err := config.ParsePullPolicy(cliVals.Pull)
|
pullPolicy, err := config.ValidatePullPolicy(cliVals.Pull)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -316,11 +324,14 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
|
||||||
return nil, errors.Errorf("new pod name must be at least one character")
|
return nil, errors.Errorf("new pod name must be at least one character")
|
||||||
}
|
}
|
||||||
|
|
||||||
userns, err := specgen.ParseUserNamespace(cliVals.UserNS)
|
var err error
|
||||||
if err != nil {
|
uns := specgen.Namespace{NSMode: specgen.Default}
|
||||||
return nil, err
|
if cliVals.UserNS != "" {
|
||||||
|
uns, err = specgen.ParseNamespace(cliVals.UserNS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createOptions := entities.PodCreateOptions{
|
createOptions := entities.PodCreateOptions{
|
||||||
Name: podName,
|
Name: podName,
|
||||||
Infra: true,
|
Infra: true,
|
||||||
|
@ -330,12 +341,36 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
|
||||||
Cpus: cliVals.CPUS,
|
Cpus: cliVals.CPUS,
|
||||||
CpusetCpus: cliVals.CPUSetCPUs,
|
CpusetCpus: cliVals.CPUSetCPUs,
|
||||||
Pid: cliVals.PID,
|
Pid: cliVals.PID,
|
||||||
Userns: userns,
|
Userns: uns,
|
||||||
}
|
}
|
||||||
// Unset config values we passed to the pod to prevent them being used twice for the container and pod.
|
// Unset config values we passed to the pod to prevent them being used twice for the container and pod.
|
||||||
s.ContainerBasicConfig.Hostname = ""
|
s.ContainerBasicConfig.Hostname = ""
|
||||||
s.ContainerNetworkConfig = specgen.ContainerNetworkConfig{}
|
s.ContainerNetworkConfig = specgen.ContainerNetworkConfig{}
|
||||||
|
|
||||||
s.Pod = podName
|
s.Pod = podName
|
||||||
return registry.ContainerEngine().PodCreate(context.Background(), createOptions)
|
podSpec := entities.PodSpec{}
|
||||||
|
podGen := specgen.NewPodSpecGenerator()
|
||||||
|
podSpec.PodSpecGen = *podGen
|
||||||
|
podGen, err = entities.ToPodSpecGen(*&podSpec.PodSpecGen, &createOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
infraOpts := entities.ContainerCreateOptions{ImageVolume: "bind", Net: netOpts, Quiet: true}
|
||||||
|
rawImageName := config.DefaultInfraImage
|
||||||
|
name, err := PullImage(rawImageName, infraOpts)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
imageName := name
|
||||||
|
podGen.InfraImage = imageName
|
||||||
|
podGen.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
|
||||||
|
podGen.InfraContainerSpec.RawImageName = rawImageName
|
||||||
|
podGen.InfraContainerSpec.NetworkOptions = podGen.NetworkOptions
|
||||||
|
err = specgenutil.FillOutSpecGen(podGen.InfraContainerSpec, &infraOpts, []string{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
podSpec.PodSpecGen = *podGen
|
||||||
|
return registry.ContainerEngine().PodCreate(context.Background(), podSpec)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/utils"
|
"github.com/containers/podman/v3/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ func prune(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pruneOptions.Filters, err = common.ParseFilters(filter)
|
pruneOptions.Filters, err = specgenutil.ParseFilters(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
"github.com/containers/podman/v3/pkg/rootless"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -106,7 +107,7 @@ func restore(cmd *cobra.Command, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(inputPorts) > 0 {
|
if len(inputPorts) > 0 {
|
||||||
restoreOptions.PublishPorts, err = common.CreatePortBindings(inputPorts)
|
restoreOptions.PublishPorts, err = specgenutil.CreatePortBindings(inputPorts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/errorhandling"
|
"github.com/containers/podman/v3/pkg/errorhandling"
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
"github.com/containers/podman/v3/pkg/rootless"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -60,7 +61,7 @@ func runFlags(cmd *cobra.Command) {
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
flags.SetInterspersed(false)
|
flags.SetInterspersed(false)
|
||||||
common.DefineCreateFlags(cmd, &cliVals)
|
common.DefineCreateFlags(cmd, &cliVals, false)
|
||||||
common.DefineNetFlags(cmd)
|
common.DefineNetFlags(cmd)
|
||||||
|
|
||||||
flags.SetNormalizeFunc(utils.AliasFlags)
|
flags.SetNormalizeFunc(utils.AliasFlags)
|
||||||
|
@ -106,10 +107,6 @@ func init() {
|
||||||
|
|
||||||
func run(cmd *cobra.Command, args []string) error {
|
func run(cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
cliVals.Net, err = common.NetFlagsToNetOptions(cmd, cliVals.Pod == "" && cliVals.PodIDFile == "")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Breaking change should be made fatal in next major Release
|
// TODO: Breaking change should be made fatal in next major Release
|
||||||
if cliVals.TTY && cliVals.Interactive && !terminal.IsTerminal(int(os.Stdin.Fd())) {
|
if cliVals.TTY && cliVals.Interactive && !terminal.IsTerminal(int(os.Stdin.Fd())) {
|
||||||
|
@ -122,11 +119,17 @@ func run(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runOpts.CIDFile = cliVals.CIDFile
|
flags := cmd.Flags()
|
||||||
runOpts.Rm = cliVals.Rm
|
cliVals.Net, err = common.NetFlagsToNetOptions(nil, *flags, cliVals.Pod == "" && cliVals.PodIDFile == "")
|
||||||
if err := createInit(cmd); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
runOpts.CIDFile = cliVals.CIDFile
|
||||||
|
runOpts.Rm = cliVals.Rm
|
||||||
|
if cliVals, err = CreateInit(cmd, cliVals, false); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for fd := 3; fd < int(3+runOpts.PreserveFDs); fd++ {
|
for fd := 3; fd < int(3+runOpts.PreserveFDs); fd++ {
|
||||||
if !rootless.IsFdInherited(fd) {
|
if !rootless.IsFdInherited(fd) {
|
||||||
return errors.Errorf("file descriptor %d is not available - the preserve-fds option requires that file descriptors must be passed", fd)
|
return errors.Errorf("file descriptor %d is not available - the preserve-fds option requires that file descriptors must be passed", fd)
|
||||||
|
@ -137,7 +140,7 @@ func run(cmd *cobra.Command, args []string) error {
|
||||||
rawImageName := ""
|
rawImageName := ""
|
||||||
if !cliVals.RootFS {
|
if !cliVals.RootFS {
|
||||||
rawImageName = args[0]
|
rawImageName = args[0]
|
||||||
name, err := pullImage(args[0])
|
name, err := PullImage(args[0], cliVals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -178,7 +181,7 @@ func run(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
cliVals.PreserveFDs = runOpts.PreserveFDs
|
cliVals.PreserveFDs = runOpts.PreserveFDs
|
||||||
s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
|
s := specgen.NewSpecGenerator(imageName, cliVals.RootFS)
|
||||||
if err := common.FillOutSpecGen(s, &cliVals, args); err != nil {
|
if err := specgenutil.FillOutSpecGen(s, &cliVals, args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.RawImageName = rawImageName
|
s.RawImageName = rawImageName
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/utils"
|
"github.com/containers/podman/v3/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,7 +60,7 @@ func prune(cmd *cobra.Command, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filterMap, err := common.ParseFilters(filter)
|
filterMap, err := specgenutil.ParseFilters(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/utils"
|
"github.com/containers/podman/v3/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
@ -67,7 +68,7 @@ func networkPrune(cmd *cobra.Command, _ []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
networkPruneOptions.Filters, err = common.ParseFilters(filter)
|
networkPruneOptions.Filters, err = specgenutil.ParseFilters(filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,17 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/completion"
|
"github.com/containers/common/pkg/completion"
|
||||||
|
"github.com/containers/common/pkg/config"
|
||||||
"github.com/containers/common/pkg/sysinfo"
|
"github.com/containers/common/pkg/sysinfo"
|
||||||
"github.com/containers/podman/v3/cmd/podman/common"
|
"github.com/containers/podman/v3/cmd/podman/common"
|
||||||
|
"github.com/containers/podman/v3/cmd/podman/containers"
|
||||||
"github.com/containers/podman/v3/cmd/podman/parse"
|
"github.com/containers/podman/v3/cmd/podman/parse"
|
||||||
"github.com/containers/podman/v3/cmd/podman/registry"
|
"github.com/containers/podman/v3/cmd/podman/registry"
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/errorhandling"
|
"github.com/containers/podman/v3/pkg/errorhandling"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -44,11 +47,11 @@ var (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
createOptions entities.PodCreateOptions
|
createOptions entities.PodCreateOptions
|
||||||
|
infraOptions entities.ContainerCreateOptions
|
||||||
labels, labelFile []string
|
labels, labelFile []string
|
||||||
podIDFile string
|
podIDFile string
|
||||||
replace bool
|
replace bool
|
||||||
share string
|
share string
|
||||||
userns string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -58,62 +61,19 @@ func init() {
|
||||||
})
|
})
|
||||||
flags := createCommand.Flags()
|
flags := createCommand.Flags()
|
||||||
flags.SetInterspersed(false)
|
flags.SetInterspersed(false)
|
||||||
|
infraOptions.IsInfra = true
|
||||||
|
common.DefineCreateFlags(createCommand, &infraOptions, true)
|
||||||
common.DefineNetFlags(createCommand)
|
common.DefineNetFlags(createCommand)
|
||||||
|
|
||||||
cpusetflagName := "cpuset-cpus"
|
|
||||||
flags.StringVar(&createOptions.CpusetCpus, cpusetflagName, "", "CPUs in which to allow execution")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(cpusetflagName, completion.AutocompleteDefault)
|
|
||||||
|
|
||||||
cpusflagName := "cpus"
|
|
||||||
flags.Float64Var(&createOptions.Cpus, cpusflagName, 0.000, "set amount of CPUs for the pod")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(cpusflagName, completion.AutocompleteDefault)
|
|
||||||
|
|
||||||
cgroupParentflagName := "cgroup-parent"
|
|
||||||
flags.StringVar(&createOptions.CGroupParent, cgroupParentflagName, "", "Set parent cgroup for the pod")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(cgroupParentflagName, completion.AutocompleteDefault)
|
|
||||||
|
|
||||||
usernsFlagName := "userns"
|
|
||||||
flags.StringVar(&userns, usernsFlagName, os.Getenv("PODMAN_USERNS"), "User namespace to use")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace)
|
|
||||||
|
|
||||||
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
|
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
|
||||||
|
|
||||||
infraConmonPidfileFlagName := "infra-conmon-pidfile"
|
|
||||||
flags.StringVar(&createOptions.InfraConmonPidFile, infraConmonPidfileFlagName, "", "Path to the file that will receive the POD of the infra container's conmon")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(infraConmonPidfileFlagName, completion.AutocompleteDefault)
|
|
||||||
|
|
||||||
infraImageFlagName := "infra-image"
|
|
||||||
flags.String(infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
|
|
||||||
|
|
||||||
infraCommandFlagName := "infra-command"
|
|
||||||
flags.String(infraCommandFlagName, containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(infraCommandFlagName, completion.AutocompleteNone)
|
|
||||||
|
|
||||||
infraNameFlagName := "infra-name"
|
|
||||||
flags.StringVarP(&createOptions.InfraName, infraNameFlagName, "", "", "The name used as infra container name")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(infraNameFlagName, completion.AutocompleteNone)
|
|
||||||
|
|
||||||
labelFileFlagName := "label-file"
|
|
||||||
flags.StringSliceVar(&labelFile, labelFileFlagName, []string{}, "Read in a line delimited file of labels")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(labelFileFlagName, completion.AutocompleteDefault)
|
|
||||||
|
|
||||||
labelFlagName := "label"
|
|
||||||
flags.StringSliceVarP(&labels, labelFlagName, "l", []string{}, "Set metadata on pod (default [])")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone)
|
|
||||||
|
|
||||||
nameFlagName := "name"
|
nameFlagName := "name"
|
||||||
flags.StringVarP(&createOptions.Name, nameFlagName, "n", "", "Assign a name to the pod")
|
flags.StringVarP(&createOptions.Name, nameFlagName, "n", "", "Assign a name to the pod")
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
|
_ = createCommand.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
hostnameFlagName := "hostname"
|
infraImageFlagName := "infra-image"
|
||||||
flags.StringVarP(&createOptions.Hostname, hostnameFlagName, "", "", "Set a hostname to the pod")
|
flags.String(infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(hostnameFlagName, completion.AutocompleteNone)
|
_ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
|
||||||
|
|
||||||
pidFlagName := "pid"
|
|
||||||
flags.StringVar(&createOptions.Pid, pidFlagName, "", "PID namespace to use")
|
|
||||||
_ = createCommand.RegisterFlagCompletionFunc(pidFlagName, common.AutocompleteNamespace)
|
|
||||||
|
|
||||||
podIDFileFlagName := "pod-id-file"
|
podIDFileFlagName := "pod-id-file"
|
||||||
flags.StringVar(&podIDFile, podIDFileFlagName, "", "Write the pod ID to the file")
|
flags.StringVar(&podIDFile, podIDFileFlagName, "", "Write the pod ID to the file")
|
||||||
|
@ -137,25 +97,30 @@ func aliasNetworkFlag(_ *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
|
||||||
func create(cmd *cobra.Command, args []string) error {
|
func create(cmd *cobra.Command, args []string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
podIDFD *os.File
|
podIDFD *os.File
|
||||||
|
imageName string
|
||||||
|
rawImageName string
|
||||||
)
|
)
|
||||||
|
labelFile = infraOptions.LabelFile
|
||||||
|
labels = infraOptions.Label
|
||||||
createOptions.Labels, err = parse.GetAllLabels(labelFile, labels)
|
createOptions.Labels, err = parse.GetAllLabels(labelFile, labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "unable to process labels")
|
return errors.Wrapf(err, "unable to process labels")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageName = config.DefaultInfraImage
|
||||||
|
img := imageName
|
||||||
if !createOptions.Infra {
|
if !createOptions.Infra {
|
||||||
|
if cmd.Flag("no-hosts").Changed {
|
||||||
|
return fmt.Errorf("cannot specify no-hosts without an infra container")
|
||||||
|
}
|
||||||
|
flags := cmd.Flags()
|
||||||
|
createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
logrus.Debugf("Not creating an infra container")
|
logrus.Debugf("Not creating an infra container")
|
||||||
if cmd.Flag("infra-conmon-pidfile").Changed {
|
|
||||||
return errors.New("cannot set infra-conmon-pid without an infra container")
|
|
||||||
}
|
|
||||||
if cmd.Flag("infra-command").Changed {
|
|
||||||
return errors.New("cannot set infra-command without an infra container")
|
|
||||||
}
|
|
||||||
if cmd.Flag("infra-image").Changed {
|
|
||||||
return errors.New("cannot set infra-image without an infra container")
|
|
||||||
}
|
|
||||||
createOptions.InfraImage = ""
|
createOptions.InfraImage = ""
|
||||||
if createOptions.InfraName != "" {
|
if createOptions.InfraName != "" {
|
||||||
return errors.New("cannot set infra-name without an infra container")
|
return errors.New("cannot set infra-name without an infra container")
|
||||||
|
@ -166,28 +131,43 @@ func create(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
createOptions.Share = nil
|
createOptions.Share = nil
|
||||||
} else {
|
} else {
|
||||||
|
// reassign certain optios for lbpod api, these need to be populated in spec
|
||||||
|
createOptions.InfraConmonPidFile = infraOptions.ConmonPIDFile
|
||||||
|
createOptions.InfraName = infraOptions.Name
|
||||||
|
createOptions.Hostname = infraOptions.Hostname
|
||||||
|
createOptions.Cpus = infraOptions.CPUS
|
||||||
|
createOptions.CpusetCpus = infraOptions.CPUSetCPUs
|
||||||
|
createOptions.Pid = infraOptions.PID
|
||||||
|
flags := cmd.Flags()
|
||||||
|
infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
infraOptions, err = containers.CreateInit(cmd, infraOptions, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createOptions.Net = infraOptions.Net
|
||||||
createOptions.Share = strings.Split(share, ",")
|
createOptions.Share = strings.Split(share, ",")
|
||||||
if cmd.Flag("infra-command").Changed {
|
if cmd.Flag("infra-command").Changed {
|
||||||
// Only send content to server side if user changed defaults
|
// Only send content to server side if user changed defaults
|
||||||
createOptions.InfraCommand, err = cmd.Flags().GetString("infra-command")
|
cmdIn, err := cmd.Flags().GetString("infra-command")
|
||||||
|
infraOptions.Entrypoint = &cmdIn
|
||||||
|
createOptions.InfraCommand = cmdIn
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if cmd.Flag("infra-image").Changed {
|
if cmd.Flag("infra-image").Changed {
|
||||||
// Only send content to server side if user changed defaults
|
// Only send content to server side if user changed defaults
|
||||||
createOptions.InfraImage, err = cmd.Flags().GetString("infra-image")
|
img, err = cmd.Flags().GetString("infra-image")
|
||||||
|
imageName = img
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createOptions.Userns, err = specgen.ParseUserNamespace(userns)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cmd.Flag("pod-id-file").Changed {
|
if cmd.Flag("pod-id-file").Changed {
|
||||||
podIDFD, err = util.OpenExclusiveFile(podIDFile)
|
podIDFD, err = util.OpenExclusiveFile(podIDFile)
|
||||||
if err != nil && os.IsExist(err) {
|
if err != nil && os.IsExist(err) {
|
||||||
|
@ -200,13 +180,6 @@ func create(cmd *cobra.Command, args []string) error {
|
||||||
defer errorhandling.SyncQuiet(podIDFD)
|
defer errorhandling.SyncQuiet(podIDFD)
|
||||||
}
|
}
|
||||||
|
|
||||||
createOptions.Pid = cmd.Flag("pid").Value.String()
|
|
||||||
|
|
||||||
createOptions.Net, err = common.NetFlagsToNetOptions(cmd, createOptions.Infra)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(createOptions.Net.PublishPorts) > 0 {
|
if len(createOptions.Net.PublishPorts) > 0 {
|
||||||
if !createOptions.Infra {
|
if !createOptions.Infra {
|
||||||
return errors.Errorf("you must have an infra container to publish port bindings to the host")
|
return errors.Errorf("you must have an infra container to publish port bindings to the host")
|
||||||
|
@ -261,10 +234,44 @@ func create(cmd *cobra.Command, args []string) error {
|
||||||
copy = "" + strconv.Itoa(core)
|
copy = "" + strconv.Itoa(core)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions)
|
podSpec := specgen.NewPodSpecGenerator()
|
||||||
|
podSpec, err = entities.ToPodSpecGen(*podSpec, &createOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if createOptions.Infra {
|
||||||
|
rawImageName = img
|
||||||
|
if !infraOptions.RootFS {
|
||||||
|
curr := infraOptions.Quiet
|
||||||
|
infraOptions.Quiet = true
|
||||||
|
name, err := containers.PullImage(imageName, infraOptions)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
imageName = name
|
||||||
|
infraOptions.Quiet = curr
|
||||||
|
}
|
||||||
|
podSpec.InfraImage = imageName
|
||||||
|
if infraOptions.Entrypoint != nil {
|
||||||
|
createOptions.InfraCommand = *infraOptions.Entrypoint
|
||||||
|
}
|
||||||
|
infraOptions.CPUS = createOptions.Cpus
|
||||||
|
infraOptions.CPUSetCPUs = createOptions.CpusetCpus
|
||||||
|
infraOptions.PID = createOptions.Pid
|
||||||
|
podSpec.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
|
||||||
|
podSpec.InfraContainerSpec.RawImageName = rawImageName
|
||||||
|
podSpec.InfraContainerSpec.NetworkOptions = podSpec.NetworkOptions
|
||||||
|
err = specgenutil.FillOutSpecGen(podSpec.InfraContainerSpec, &infraOptions, []string{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PodSpec := entities.PodSpec{PodSpecGen: *podSpec}
|
||||||
|
response, err := registry.ContainerEngine().PodCreate(context.Background(), PodSpec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if len(podIDFile) > 0 {
|
if len(podIDFile) > 0 {
|
||||||
if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil {
|
if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil {
|
||||||
return errors.Wrapf(err, "failed to write pod ID to file")
|
return errors.Wrapf(err, "failed to write pod ID to file")
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -66,7 +67,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func rm(_ *cobra.Command, args []string) error {
|
func rm(_ *cobra.Command, args []string) error {
|
||||||
ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles)
|
ids, err := specgenutil.ReadPodIDFiles(rmOptions.PodIDFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/utils"
|
"github.com/containers/podman/v3/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -64,7 +65,7 @@ func start(cmd *cobra.Command, args []string) error {
|
||||||
errs utils.OutputErrors
|
errs utils.OutputErrors
|
||||||
)
|
)
|
||||||
|
|
||||||
ids, err := common.ReadPodIDFiles(startOptions.PodIDFiles)
|
ids, err := specgenutil.ReadPodIDFiles(startOptions.PodIDFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/utils"
|
"github.com/containers/podman/v3/cmd/podman/utils"
|
||||||
"github.com/containers/podman/v3/cmd/podman/validate"
|
"github.com/containers/podman/v3/cmd/podman/validate"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ func stop(cmd *cobra.Command, args []string) error {
|
||||||
stopOptions.Timeout = int(stopOptions.TimeoutCLI)
|
stopOptions.Timeout = int(stopOptions.TimeoutCLI)
|
||||||
}
|
}
|
||||||
|
|
||||||
ids, err := common.ReadPodIDFiles(stopOptions.PodIDFiles)
|
ids, err := specgenutil.ReadPodIDFiles(stopOptions.PodIDFiles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,26 @@ Set custom DNS options in the /etc/resolv.conf file that will be shared between
|
||||||
|
|
||||||
Set custom DNS search domains in the /etc/resolv.conf file that will be shared between all containers in the pod.
|
Set custom DNS search domains in the /etc/resolv.conf file that will be shared between all containers in the pod.
|
||||||
|
|
||||||
#### **--help**
|
#### **--gidmap**=*container_gid:host_gid:amount*
|
||||||
|
|
||||||
|
GID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subgidname` flags.
|
||||||
|
|
||||||
|
#### **--uidmap**=*container_uid*:*from_uid*:*amount*
|
||||||
|
|
||||||
|
Run the container in a new user namespace using the supplied mapping. This
|
||||||
|
option conflicts with the **--userns** and **--subuidname** options. This
|
||||||
|
option provides a way to map host UIDs to container UIDs. It can be passed
|
||||||
|
several times to map different ranges.
|
||||||
|
|
||||||
|
#### **--subgidname**=*name*
|
||||||
|
|
||||||
|
Name for GID map from the `/etc/subgid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--gidmap`.
|
||||||
|
|
||||||
|
#### **--subuidname**=*name*
|
||||||
|
|
||||||
|
Name for UID map from the `/etc/subuid` file. Using this flag will run the container with user namespace enabled. This flag conflicts with `--userns` and `--uidmap`.
|
||||||
|
|
||||||
|
#### **--help**, **-h**
|
||||||
|
|
||||||
Print usage statement.
|
Print usage statement.
|
||||||
|
|
||||||
|
|
|
@ -972,11 +972,12 @@ func (c *Container) checkDependenciesRunning() ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the status
|
// Check the status
|
||||||
|
conf := depCtr.Config()
|
||||||
state, err := depCtr.State()
|
state, err := depCtr.State()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error retrieving state of dependency %s of container %s", dep, c.ID())
|
return nil, errors.Wrapf(err, "error retrieving state of dependency %s of container %s", dep, c.ID())
|
||||||
}
|
}
|
||||||
if state != define.ContainerStateRunning {
|
if state != define.ContainerStateRunning && !conf.IsInfra {
|
||||||
notRunning = append(notRunning, dep)
|
notRunning = append(notRunning, dep)
|
||||||
}
|
}
|
||||||
depCtrs[dep] = depCtr
|
depCtrs[dep] = depCtr
|
||||||
|
|
|
@ -10,6 +10,8 @@ import (
|
||||||
|
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/lookup"
|
"github.com/containers/podman/v3/pkg/lookup"
|
||||||
|
"github.com/containers/podman/v3/pkg/namespaces"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
|
@ -72,7 +74,7 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
||||||
return nil, servicePorts, err
|
return nil, servicePorts, err
|
||||||
}
|
}
|
||||||
servicePorts = containerPortsToServicePorts(ports)
|
servicePorts = containerPortsToServicePorts(ports)
|
||||||
hostNetwork = p.config.InfraContainer.HostNetwork
|
hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
|
||||||
}
|
}
|
||||||
pod, err := p.podWithContainers(allContainers, ports, hostNetwork)
|
pod, err := p.podWithContainers(allContainers, ports, hostNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -632,7 +632,6 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Re
|
||||||
}
|
}
|
||||||
|
|
||||||
podName := getCNIPodName(ctr)
|
podName := getCNIPodName(ctr)
|
||||||
|
|
||||||
networks, _, err := ctr.networks()
|
networks, _, err := ctr.networks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/containers/image/v5/types"
|
"github.com/containers/image/v5/types"
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/libpod/events"
|
"github.com/containers/podman/v3/libpod/events"
|
||||||
|
netTypes "github.com/containers/podman/v3/libpod/network/types"
|
||||||
"github.com/containers/podman/v3/pkg/namespaces"
|
"github.com/containers/podman/v3/pkg/namespaces"
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
"github.com/containers/podman/v3/pkg/rootless"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
|
@ -21,7 +22,6 @@ import (
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/idtools"
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
"github.com/opencontainers/runtime-tools/generate"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -713,7 +713,6 @@ func (r *Runtime) WithPod(pod *Pod) CtrCreateOption {
|
||||||
if pod == nil {
|
if pod == nil {
|
||||||
return define.ErrInvalidArg
|
return define.ErrInvalidArg
|
||||||
}
|
}
|
||||||
|
|
||||||
ctr.config.Pod = pod.ID()
|
ctr.config.Pod = pod.ID()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1430,20 +1429,6 @@ func WithRestartRetries(tries uint) CtrCreateOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// withIsInfra sets the container to be an infra container. This means the container will be sometimes hidden
|
|
||||||
// and expected to be the first container in the pod.
|
|
||||||
func withIsInfra() CtrCreateOption {
|
|
||||||
return func(ctr *Container) error {
|
|
||||||
if ctr.valid {
|
|
||||||
return define.ErrCtrFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr.config.IsInfra = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithNamedVolumes adds the given named volumes to the container.
|
// WithNamedVolumes adds the given named volumes to the container.
|
||||||
func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
|
func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
|
||||||
return func(ctr *Container) error {
|
return func(ctr *Container) error {
|
||||||
|
@ -1541,6 +1526,20 @@ func WithCreateCommand(cmd []string) CtrCreateOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// withIsInfra allows us to dfferentiate between infra containers and regular containers
|
||||||
|
// within the container config
|
||||||
|
func withIsInfra() CtrCreateOption {
|
||||||
|
return func(ctr *Container) error {
|
||||||
|
if ctr.valid {
|
||||||
|
return define.ErrCtrFinalized
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr.config.IsInfra = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithCreateWorkingDir tells Podman to create the container's working directory
|
// WithCreateWorkingDir tells Podman to create the container's working directory
|
||||||
// if it does not exist.
|
// if it does not exist.
|
||||||
func WithCreateWorkingDir() CtrCreateOption {
|
func WithCreateWorkingDir() CtrCreateOption {
|
||||||
|
@ -1812,45 +1811,14 @@ func WithInitCtrType(containerType string) CtrCreateOption {
|
||||||
|
|
||||||
// Pod Creation Options
|
// Pod Creation Options
|
||||||
|
|
||||||
// WithInfraImage sets the infra image for libpod.
|
// WithPodCreateCommand adds the full command plus arguments of the current
|
||||||
// An infra image is used for inter-container kernel
|
// process to the pod config.
|
||||||
// namespace sharing within a pod. Typically, an infra
|
func WithPodCreateCommand(createCmd []string) PodCreateOption {
|
||||||
// container is lightweight and is there to reap
|
|
||||||
// zombie processes within its pid namespace.
|
|
||||||
func WithInfraImage(img string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
return func(pod *Pod) error {
|
||||||
if pod.valid {
|
if pod.valid {
|
||||||
return define.ErrPodFinalized
|
return define.ErrPodFinalized
|
||||||
}
|
}
|
||||||
|
pod.config.CreateCommand = createCmd
|
||||||
pod.config.InfraContainer.InfraImage = img
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInfraCommand sets the command to
|
|
||||||
// run on pause container start up.
|
|
||||||
func WithInfraCommand(cmd []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.InfraCommand = cmd
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInfraName sets the infra container name for a single pod.
|
|
||||||
func WithInfraName(name string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.InfraName = name
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1891,26 +1859,14 @@ func WithPodHostname(hostname string) PodCreateOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithPodCreateCommand adds the full command plus arguments of the current
|
|
||||||
// process to the pod config.
|
|
||||||
func WithPodCreateCommand(createCmd []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
pod.config.CreateCommand = createCmd
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithInfraConmonPidFile sets the path to a custom conmon PID file for the
|
// WithInfraConmonPidFile sets the path to a custom conmon PID file for the
|
||||||
// infra container.
|
// infra container.
|
||||||
func WithInfraConmonPidFile(path string) PodCreateOption {
|
func WithInfraConmonPidFile(path string, infraSpec *specgen.SpecGenerator) PodCreateOption {
|
||||||
return func(pod *Pod) error {
|
return func(pod *Pod) error {
|
||||||
if pod.valid {
|
if pod.valid {
|
||||||
return define.ErrPodFinalized
|
return define.ErrPodFinalized
|
||||||
}
|
}
|
||||||
pod.config.InfraContainer.ConmonPidFile = path
|
infraSpec.ConmonPidFile = path
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2099,320 +2055,25 @@ func WithInfraContainer() PodCreateOption {
|
||||||
if pod.valid {
|
if pod.valid {
|
||||||
return define.ErrPodFinalized
|
return define.ErrPodFinalized
|
||||||
}
|
}
|
||||||
|
pod.config.HasInfra = true
|
||||||
pod.config.InfraContainer.HasInfraContainer = true
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithInfraContainerPorts tells the pod to add port bindings to the pause container
|
// WithInfraContainerPorts tells the pod to add port bindings to the pause container
|
||||||
func WithInfraContainerPorts(bindings []ocicni.PortMapping) PodCreateOption {
|
func WithInfraContainerPorts(bindings []ocicni.PortMapping, infraSpec *specgen.SpecGenerator) []netTypes.PortMapping {
|
||||||
return func(pod *Pod) error {
|
bindingSpec := []netTypes.PortMapping{}
|
||||||
if pod.valid {
|
for _, bind := range bindings {
|
||||||
return define.ErrPodFinalized
|
currBind := netTypes.PortMapping{}
|
||||||
}
|
currBind.ContainerPort = uint16(bind.ContainerPort)
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
currBind.HostIP = bind.HostIP
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set pod ports as no infra container is being created")
|
currBind.HostPort = uint16(bind.HostPort)
|
||||||
}
|
currBind.Protocol = bind.Protocol
|
||||||
pod.config.InfraContainer.PortBindings = bindings
|
bindingSpec = append(bindingSpec, currBind)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodStaticIP sets a static IP for the pod.
|
|
||||||
func WithPodStaticIP(ip net.IP) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set pod static IP as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.HostNetwork {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set static IP if host network is specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pod.config.InfraContainer.Networks) > 1 {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set a static IP if joining more than 1 CNI network")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.StaticIP = ip
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodStaticMAC sets a static MAC address for the pod.
|
|
||||||
func WithPodStaticMAC(mac net.HardwareAddr) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set pod static MAC as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.HostNetwork {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set static MAC if host network is specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pod.config.InfraContainer.Networks) > 1 {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set a static MAC if joining more than 1 CNI network")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.StaticMAC = mac
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodUseImageResolvConf sets a pod to use an image's resolv.conf and not
|
|
||||||
// create its own.
|
|
||||||
func WithPodUseImageResolvConf() PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pod.config.InfraContainer.DNSServer) != 0 ||
|
|
||||||
len(pod.config.InfraContainer.DNSSearch) != 0 ||
|
|
||||||
len(pod.config.InfraContainer.DNSOption) != 0 {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "requested use of image resolv.conf conflicts with already-configured DNS settings")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.UseImageResolvConf = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodDNS sets the DNS Servers for a pod.
|
|
||||||
func WithPodDNS(dnsServer []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.UseImageResolvConf {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS servers if pod will not create /etc/resolv.conf")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.DNSServer = dnsServer
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodDNSSearch sets the DNS Search domains for a pod.
|
|
||||||
func WithPodDNSSearch(dnsSearch []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.UseImageResolvConf {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS search domains if pod will not create /etc/resolv.conf")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.DNSSearch = dnsSearch
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodDNSOption sets DNS Options for a pod.
|
|
||||||
func WithPodDNSOption(dnsOption []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod DNS as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.UseImageResolvConf {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot add DNS options if pod will not create /etc/resolv.conf")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.DNSOption = dnsOption
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodUseImageHosts tells the pod not to create /etc/hosts and instead to
|
|
||||||
// use the one provided by the image.
|
|
||||||
func WithPodUseImageHosts() PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod hosts as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pod.config.InfraContainer.HostAdd) != 0 {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "not creating /etc/hosts conflicts with adding to the hosts file")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.UseImageHosts = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodHosts adds additional entries to the pod's /etc/hosts
|
|
||||||
func WithPodHosts(hosts []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod hosts as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.UseImageHosts {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot add to /etc/hosts if container is using image hosts")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.HostAdd = hosts
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodNetworks sets additional CNI networks for the pod to join.
|
|
||||||
func WithPodNetworks(networks []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod CNI networks as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pod.config.InfraContainer.StaticIP != nil || pod.config.InfraContainer.StaticMAC != nil) &&
|
|
||||||
len(networks) > 1 {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot join more than one CNI network if setting a static IP or MAC address")
|
|
||||||
}
|
|
||||||
|
|
||||||
if pod.config.InfraContainer.HostNetwork {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot join pod to CNI networks if host network is specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.Networks = networks
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodNoNetwork tells the pod to disable external networking.
|
|
||||||
func WithPodNoNetwork() PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod networking as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pod.config.InfraContainer.PortBindings) > 0 ||
|
|
||||||
pod.config.InfraContainer.StaticIP != nil ||
|
|
||||||
pod.config.InfraContainer.StaticMAC != nil ||
|
|
||||||
len(pod.config.InfraContainer.Networks) > 0 ||
|
|
||||||
pod.config.InfraContainer.HostNetwork {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.NoNetwork = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodHostNetwork tells the pod to use the host's network namespace.
|
|
||||||
func WithPodHostNetwork() PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod host networking as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pod.config.InfraContainer.PortBindings) > 0 ||
|
|
||||||
pod.config.InfraContainer.StaticIP != nil ||
|
|
||||||
pod.config.InfraContainer.StaticMAC != nil ||
|
|
||||||
len(pod.config.InfraContainer.Networks) > 0 ||
|
|
||||||
pod.config.InfraContainer.NoNetwork {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.HostNetwork = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodInfraExitCommand sets an exit command for the pod's infra container.
|
|
||||||
// Semantics are identical to WithExitCommand() above - the ID of the container
|
|
||||||
// will be appended to the end of the provided command (note that this will
|
|
||||||
// specifically be the ID of the infra container *and not the pod's id*.
|
|
||||||
func WithPodInfraExitCommand(exitCmd []string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod infra container exit command as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.ExitCommand = exitCmd
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodSlirp4netns tells the pod to use slirp4netns.
|
|
||||||
func WithPodSlirp4netns(networkOptions map[string][]string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod networking as no infra container is being created")
|
|
||||||
}
|
|
||||||
if pod.config.InfraContainer.HostNetwork {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot set both HostNetwork and Slirp4netns")
|
|
||||||
}
|
|
||||||
pod.config.InfraContainer.Slirp4netns = true
|
|
||||||
pod.config.InfraContainer.NetworkOptions = networkOptions
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
infraSpec.PortMappings = bindingSpec
|
||||||
|
return infraSpec.PortMappings
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithVolatile sets the volatile flag for the container storage.
|
// WithVolatile sets the volatile flag for the container storage.
|
||||||
|
@ -2428,78 +2089,3 @@ func WithVolatile() CtrCreateOption {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithPodUserns sets the userns for the infra container in a pod.
|
|
||||||
func WithPodUserns(userns specgen.Namespace) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
if !pod.config.InfraContainer.HasInfraContainer {
|
|
||||||
return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod userns as no infra container is being created")
|
|
||||||
}
|
|
||||||
|
|
||||||
pod.config.InfraContainer.Userns = userns
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodCPUPAQ takes the given cpu period and quota and inserts them in the proper place.
|
|
||||||
func WithPodCPUPAQ(period uint64, quota int64) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
if pod.CPUPeriod() != 0 && pod.CPUQuota() != 0 {
|
|
||||||
pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{
|
|
||||||
Period: &period,
|
|
||||||
Quota: "a,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pod.config.InfraContainer.ResourceLimits = &specs.LinuxResources{}
|
|
||||||
pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{
|
|
||||||
Period: &period,
|
|
||||||
Quota: "a,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithPodCPUSetCPUS computes and sets the Cpus linux resource string which determines the amount of cores, from those available, we are allowed to execute on
|
|
||||||
func WithPodCPUSetCPUs(inp string) PodCreateOption {
|
|
||||||
return func(pod *Pod) error {
|
|
||||||
if pod.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
if pod.ResourceLim().CPU.Period != nil {
|
|
||||||
pod.config.InfraContainer.ResourceLimits.CPU.Cpus = inp
|
|
||||||
} else {
|
|
||||||
pod.config.InfraContainer.ResourceLimits = &specs.LinuxResources{}
|
|
||||||
pod.config.InfraContainer.ResourceLimits.CPU = &specs.LinuxCPU{}
|
|
||||||
pod.config.InfraContainer.ResourceLimits.CPU.Cpus = inp
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithPodPidNS(inp specgen.Namespace) PodCreateOption {
|
|
||||||
return func(p *Pod) error {
|
|
||||||
if p.valid {
|
|
||||||
return define.ErrPodFinalized
|
|
||||||
}
|
|
||||||
if p.config.UsePodPID {
|
|
||||||
switch inp.NSMode {
|
|
||||||
case "container":
|
|
||||||
return errors.Wrap(define.ErrInvalidArg, "Cannot take container in a different NS as an argument")
|
|
||||||
case "host":
|
|
||||||
p.config.UsePodPID = false
|
|
||||||
}
|
|
||||||
p.config.InfraContainer.PidNS = inp
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
171
libpod/pod.go
171
libpod/pod.go
|
@ -2,14 +2,12 @@ package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/libpod/lock"
|
"github.com/containers/podman/v3/libpod/lock"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
|
||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -63,7 +61,7 @@ type PodConfig struct {
|
||||||
UsePodUTS bool `json:"sharesUts,omitempty"`
|
UsePodUTS bool `json:"sharesUts,omitempty"`
|
||||||
UsePodCgroupNS bool `json:"sharesCgroupNS,omitempty"`
|
UsePodCgroupNS bool `json:"sharesCgroupNS,omitempty"`
|
||||||
|
|
||||||
InfraContainer *InfraContainerConfig `json:"infraConfig"`
|
HasInfra bool `json:"hasInfra,omitempty"`
|
||||||
|
|
||||||
// Time pod was created
|
// Time pod was created
|
||||||
CreatedTime time.Time `json:"created"`
|
CreatedTime time.Time `json:"created"`
|
||||||
|
@ -85,41 +83,6 @@ type podState struct {
|
||||||
InfraContainerID string
|
InfraContainerID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// InfraContainerConfig is the configuration for the pod's infra container.
|
|
||||||
// Generally speaking, these are equivalent to container configuration options
|
|
||||||
// you will find in container_config.go (and even named identically), save for
|
|
||||||
// HasInfraContainer (which determines if an infra container is even created -
|
|
||||||
// if it is false, no other options in this struct will be used) and HostNetwork
|
|
||||||
// (this involves the created OCI spec, and as such is not represented directly
|
|
||||||
// in container_config.go).
|
|
||||||
// Generally speaking, aside from those two exceptions, these options will set
|
|
||||||
// the equivalent field in the container's configuration.
|
|
||||||
type InfraContainerConfig struct {
|
|
||||||
ConmonPidFile string `json:"conmonPidFile"`
|
|
||||||
HasInfraContainer bool `json:"makeInfraContainer"`
|
|
||||||
NoNetwork bool `json:"noNetwork,omitempty"`
|
|
||||||
HostNetwork bool `json:"infraHostNetwork,omitempty"`
|
|
||||||
PidNS specgen.Namespace `json:"infraPid,omitempty"`
|
|
||||||
PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
|
|
||||||
StaticIP net.IP `json:"staticIP,omitempty"`
|
|
||||||
StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"`
|
|
||||||
UseImageResolvConf bool `json:"useImageResolvConf,omitempty"`
|
|
||||||
DNSServer []string `json:"dnsServer,omitempty"`
|
|
||||||
DNSSearch []string `json:"dnsSearch,omitempty"`
|
|
||||||
DNSOption []string `json:"dnsOption,omitempty"`
|
|
||||||
UseImageHosts bool `json:"useImageHosts,omitempty"`
|
|
||||||
HostAdd []string `json:"hostsAdd,omitempty"`
|
|
||||||
Networks []string `json:"networks,omitempty"`
|
|
||||||
ExitCommand []string `json:"exitCommand,omitempty"`
|
|
||||||
InfraImage string `json:"infraImage,omitempty"`
|
|
||||||
InfraCommand []string `json:"infraCommand,omitempty"`
|
|
||||||
InfraName string `json:"infraName,omitempty"`
|
|
||||||
Slirp4netns bool `json:"slirp4netns,omitempty"`
|
|
||||||
NetworkOptions map[string][]string `json:"network_options,omitempty"`
|
|
||||||
ResourceLimits *specs.LinuxResources `json:"resource_limits,omitempty"`
|
|
||||||
Userns specgen.Namespace `json:"userns,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID retrieves the pod's ID
|
// ID retrieves the pod's ID
|
||||||
func (p *Pod) ID() string {
|
func (p *Pod) ID() string {
|
||||||
return p.config.ID
|
return p.config.ID
|
||||||
|
@ -139,45 +102,104 @@ func (p *Pod) Namespace() string {
|
||||||
// ResourceLim returns the cpuset resource limits for the pod
|
// ResourceLim returns the cpuset resource limits for the pod
|
||||||
func (p *Pod) ResourceLim() *specs.LinuxResources {
|
func (p *Pod) ResourceLim() *specs.LinuxResources {
|
||||||
resCopy := &specs.LinuxResources{}
|
resCopy := &specs.LinuxResources{}
|
||||||
if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if resCopy != nil && resCopy.CPU != nil {
|
|
||||||
return resCopy
|
|
||||||
}
|
|
||||||
empty := &specs.LinuxResources{
|
empty := &specs.LinuxResources{
|
||||||
CPU: &specs.LinuxCPU{},
|
CPU: &specs.LinuxCPU{},
|
||||||
}
|
}
|
||||||
|
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return empty
|
||||||
|
}
|
||||||
|
conf := infra.config.Spec
|
||||||
|
if err != nil {
|
||||||
|
return empty
|
||||||
|
}
|
||||||
|
if conf.Linux == nil || conf.Linux.Resources == nil {
|
||||||
|
return empty
|
||||||
|
}
|
||||||
|
if err = JSONDeepCopy(conf.Linux.Resources, resCopy); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if resCopy.CPU != nil {
|
||||||
|
return resCopy
|
||||||
|
}
|
||||||
|
|
||||||
return empty
|
return empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPUPeriod returns the pod CPU period
|
// CPUPeriod returns the pod CPU period
|
||||||
func (p *Pod) CPUPeriod() uint64 {
|
func (p *Pod) CPUPeriod() uint64 {
|
||||||
resCopy := &specs.LinuxResources{}
|
if p.state.InfraContainerID == "" {
|
||||||
if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Period != nil {
|
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
|
||||||
return *resCopy.CPU.Period
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
conf := infra.config.Spec
|
||||||
|
if conf != nil && conf.Linux != nil && conf.Linux.Resources != nil && conf.Linux.Resources.CPU != nil && conf.Linux.Resources.CPU.Period != nil {
|
||||||
|
return *conf.Linux.Resources.CPU.Period
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// CPUQuota returns the pod CPU quota
|
// CPUQuota returns the pod CPU quota
|
||||||
func (p *Pod) CPUQuota() int64 {
|
func (p *Pod) CPUQuota() int64 {
|
||||||
resCopy := &specs.LinuxResources{}
|
if p.state.InfraContainerID == "" {
|
||||||
if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Quota != nil {
|
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
|
||||||
return *resCopy.CPU.Quota
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
conf := infra.config.Spec
|
||||||
|
if conf != nil && conf.Linux != nil && conf.Linux.Resources != nil && conf.Linux.Resources.CPU != nil && conf.Linux.Resources.CPU.Quota != nil {
|
||||||
|
return *conf.Linux.Resources.CPU.Quota
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// PidMode returns the PID mode given by the user ex: pod, private...
|
// PidMode returns the PID mode given by the user ex: pod, private...
|
||||||
func (p *Pod) PidMode() string {
|
func (p *Pod) PidMode() string {
|
||||||
return string(p.config.InfraContainer.PidNS.NSMode)
|
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
conf := infra.Config()
|
||||||
|
ctrSpec := conf.Spec
|
||||||
|
if ctrSpec != nil && ctrSpec.Linux != nil {
|
||||||
|
for _, ns := range ctrSpec.Linux.Namespaces {
|
||||||
|
if ns.Type == specs.PIDNamespace {
|
||||||
|
if ns.Path != "" {
|
||||||
|
return fmt.Sprintf("ns:%s", ns.Path)
|
||||||
|
}
|
||||||
|
return "private"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "host"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// PidMode returns the PID mode given by the user ex: pod, private...
|
||||||
|
func (p *Pod) UserNSMode() string {
|
||||||
|
infra, err := p.infraContainer()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
conf := infra.Config()
|
||||||
|
ctrSpec := conf.Spec
|
||||||
|
if ctrSpec != nil && ctrSpec.Linux != nil {
|
||||||
|
for _, ns := range ctrSpec.Linux.Namespaces {
|
||||||
|
if ns.Type == specs.UserNamespace {
|
||||||
|
if ns.Path != "" {
|
||||||
|
return fmt.Sprintf("ns:%s", ns.Path)
|
||||||
|
}
|
||||||
|
return "private"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "host"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Labels returns the pod's labels
|
// Labels returns the pod's labels
|
||||||
|
@ -263,20 +285,24 @@ func (p *Pod) CgroupPath() (string, error) {
|
||||||
if p.state.CgroupPath != "" {
|
if p.state.CgroupPath != "" {
|
||||||
return p.state.CgroupPath, nil
|
return p.state.CgroupPath, nil
|
||||||
}
|
}
|
||||||
if !p.HasInfraContainer() {
|
if p.state.InfraContainerID == "" {
|
||||||
return "", errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
|
return "", errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
|
||||||
}
|
}
|
||||||
|
|
||||||
id := p.state.InfraContainerID
|
id, err := p.infraContainerID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
if id != "" {
|
if id != "" {
|
||||||
ctr, err := p.runtime.state.Container(id)
|
ctr, err := p.infraContainer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "could not get infra")
|
return "", errors.Wrapf(err, "could not get infra")
|
||||||
}
|
}
|
||||||
if ctr != nil {
|
if ctr != nil {
|
||||||
ctr.Start(context.Background(), false)
|
ctr.Start(context.Background(), true)
|
||||||
cgroupPath, err := ctr.CGroupPath()
|
cgroupPath, err := ctr.CGroupPath()
|
||||||
|
fmt.Println(cgroupPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "could not get container cgroup")
|
return "", errors.Wrapf(err, "could not get container cgroup")
|
||||||
}
|
}
|
||||||
|
@ -325,7 +351,7 @@ func (p *Pod) allContainers() ([]*Container, error) {
|
||||||
|
|
||||||
// HasInfraContainer returns whether the pod will create an infra container
|
// HasInfraContainer returns whether the pod will create an infra container
|
||||||
func (p *Pod) HasInfraContainer() bool {
|
func (p *Pod) HasInfraContainer() bool {
|
||||||
return p.config.InfraContainer.HasInfraContainer
|
return p.config.HasInfra
|
||||||
}
|
}
|
||||||
|
|
||||||
// SharesNamespaces checks if the pod has any kernel namespaces set as shared. An infra container will not be
|
// SharesNamespaces checks if the pod has any kernel namespaces set as shared. An infra container will not be
|
||||||
|
@ -350,19 +376,26 @@ func (p *Pod) InfraContainerID() (string, error) {
|
||||||
return p.infraContainerID()
|
return p.infraContainerID()
|
||||||
}
|
}
|
||||||
|
|
||||||
// InfraContainer returns the infra container.
|
// infraContainer is the unlocked versio of InfraContainer which returns the infra container
|
||||||
func (p *Pod) InfraContainer() (*Container, error) {
|
func (p *Pod) infraContainer() (*Container, error) {
|
||||||
if !p.HasInfraContainer() {
|
id, err := p.infraContainerID()
|
||||||
return nil, errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
|
|
||||||
}
|
|
||||||
id, err := p.InfraContainerID()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if id == "" {
|
||||||
|
return nil, errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
|
||||||
|
}
|
||||||
|
|
||||||
return p.runtime.state.Container(id)
|
return p.runtime.state.Container(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InfraContainer returns the infra container.
|
||||||
|
func (p *Pod) InfraContainer() (*Container, error) {
|
||||||
|
p.lock.Lock()
|
||||||
|
defer p.lock.Unlock()
|
||||||
|
return p.infraContainer()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO add pod batching
|
// TODO add pod batching
|
||||||
// Lock pod to avoid lock contention
|
// Lock pod to avoid lock contention
|
||||||
// Store and lock all containers (no RemoveContainer in batch guarantees cache will not become stale)
|
// Store and lock all containers (no RemoveContainer in batch guarantees cache will not become stale)
|
||||||
|
@ -412,13 +445,7 @@ func (p *Pod) ProcessLabel() (string, error) {
|
||||||
if !p.HasInfraContainer() {
|
if !p.HasInfraContainer() {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
ctr, err := p.infraContainer()
|
||||||
id, err := p.InfraContainerID()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr, err := p.runtime.state.Container(id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,41 +582,46 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
|
||||||
// Infra config contains detailed information on the pod's infra
|
// Infra config contains detailed information on the pod's infra
|
||||||
// container.
|
// container.
|
||||||
var infraConfig *define.InspectPodInfraConfig
|
var infraConfig *define.InspectPodInfraConfig
|
||||||
if p.config.InfraContainer != nil && p.config.InfraContainer.HasInfraContainer {
|
if p.state.InfraContainerID != "" {
|
||||||
|
infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
infraConfig = new(define.InspectPodInfraConfig)
|
infraConfig = new(define.InspectPodInfraConfig)
|
||||||
infraConfig.HostNetwork = p.config.InfraContainer.HostNetwork
|
infraConfig.HostNetwork = !infra.Config().ContainerNetworkConfig.UseImageHosts
|
||||||
infraConfig.StaticIP = p.config.InfraContainer.StaticIP
|
infraConfig.StaticIP = infra.Config().ContainerNetworkConfig.StaticIP
|
||||||
infraConfig.StaticMAC = p.config.InfraContainer.StaticMAC.String()
|
infraConfig.NoManageResolvConf = infra.Config().UseImageResolvConf
|
||||||
infraConfig.NoManageResolvConf = p.config.InfraContainer.UseImageResolvConf
|
infraConfig.NoManageHosts = infra.Config().UseImageHosts
|
||||||
infraConfig.NoManageHosts = p.config.InfraContainer.UseImageHosts
|
|
||||||
infraConfig.CPUPeriod = p.CPUPeriod()
|
infraConfig.CPUPeriod = p.CPUPeriod()
|
||||||
infraConfig.CPUQuota = p.CPUQuota()
|
infraConfig.CPUQuota = p.CPUQuota()
|
||||||
infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus
|
infraConfig.CPUSetCPUs = p.ResourceLim().CPU.Cpus
|
||||||
infraConfig.PidNS = p.PidMode()
|
infraConfig.PidNS = p.PidMode()
|
||||||
infraConfig.UserNS = p.config.InfraContainer.Userns.String()
|
infraConfig.UserNS = p.UserNSMode()
|
||||||
|
|
||||||
if len(p.config.InfraContainer.DNSServer) > 0 {
|
if len(infra.Config().ContainerNetworkConfig.DNSServer) > 0 {
|
||||||
infraConfig.DNSServer = make([]string, 0, len(p.config.InfraContainer.DNSServer))
|
infraConfig.DNSServer = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSServer))
|
||||||
infraConfig.DNSServer = append(infraConfig.DNSServer, p.config.InfraContainer.DNSServer...)
|
for _, entry := range infra.Config().ContainerNetworkConfig.DNSServer {
|
||||||
|
infraConfig.DNSServer = append(infraConfig.DNSServer, entry.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(p.config.InfraContainer.DNSSearch) > 0 {
|
if len(infra.Config().ContainerNetworkConfig.DNSSearch) > 0 {
|
||||||
infraConfig.DNSSearch = make([]string, 0, len(p.config.InfraContainer.DNSSearch))
|
infraConfig.DNSSearch = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSSearch))
|
||||||
infraConfig.DNSSearch = append(infraConfig.DNSSearch, p.config.InfraContainer.DNSSearch...)
|
infraConfig.DNSSearch = append(infraConfig.DNSSearch, infra.Config().ContainerNetworkConfig.DNSSearch...)
|
||||||
}
|
}
|
||||||
if len(p.config.InfraContainer.DNSOption) > 0 {
|
if len(infra.Config().ContainerNetworkConfig.DNSOption) > 0 {
|
||||||
infraConfig.DNSOption = make([]string, 0, len(p.config.InfraContainer.DNSOption))
|
infraConfig.DNSOption = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSOption))
|
||||||
infraConfig.DNSOption = append(infraConfig.DNSOption, p.config.InfraContainer.DNSOption...)
|
infraConfig.DNSOption = append(infraConfig.DNSOption, infra.Config().ContainerNetworkConfig.DNSOption...)
|
||||||
}
|
}
|
||||||
if len(p.config.InfraContainer.HostAdd) > 0 {
|
if len(infra.Config().HostAdd) > 0 {
|
||||||
infraConfig.HostAdd = make([]string, 0, len(p.config.InfraContainer.HostAdd))
|
infraConfig.HostAdd = make([]string, 0, len(infra.Config().HostAdd))
|
||||||
infraConfig.HostAdd = append(infraConfig.HostAdd, p.config.InfraContainer.HostAdd...)
|
infraConfig.HostAdd = append(infraConfig.HostAdd, infra.Config().HostAdd...)
|
||||||
}
|
}
|
||||||
if len(p.config.InfraContainer.Networks) > 0 {
|
if len(infra.Config().ContainerNetworkConfig.Networks) > 0 {
|
||||||
infraConfig.Networks = make([]string, 0, len(p.config.InfraContainer.Networks))
|
infraConfig.Networks = make([]string, 0, len(infra.Config().ContainerNetworkConfig.Networks))
|
||||||
infraConfig.Networks = append(infraConfig.Networks, p.config.InfraContainer.Networks...)
|
infraConfig.Networks = append(infraConfig.Networks, infra.Config().ContainerNetworkConfig.Networks...)
|
||||||
}
|
}
|
||||||
infraConfig.NetworkOptions = p.config.InfraContainer.NetworkOptions
|
infraConfig.NetworkOptions = infra.Config().ContainerNetworkConfig.NetworkOptions
|
||||||
infraConfig.PortBindings = makeInspectPortBindings(p.config.InfraContainer.PortBindings, nil)
|
infraConfig.PortBindings = makeInspectPortBindings(infra.Config().ContainerNetworkConfig.PortMappings, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
inspectData := define.InspectPodData{
|
inspectData := define.InspectPodData{
|
||||||
|
|
|
@ -20,7 +20,7 @@ func newPod(runtime *Runtime) *Pod {
|
||||||
pod.config.ID = stringid.GenerateNonCryptoID()
|
pod.config.ID = stringid.GenerateNonCryptoID()
|
||||||
pod.config.Labels = make(map[string]string)
|
pod.config.Labels = make(map[string]string)
|
||||||
pod.config.CreatedTime = time.Now()
|
pod.config.CreatedTime = time.Now()
|
||||||
pod.config.InfraContainer = new(InfraContainerConfig)
|
// pod.config.InfraContainer = new(ContainerConfig)
|
||||||
pod.state = new(podState)
|
pod.state = new(podState)
|
||||||
pod.runtime = runtime
|
pod.runtime = runtime
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/cgroups"
|
"github.com/containers/podman/v3/pkg/cgroups"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities/reports"
|
"github.com/containers/podman/v3/pkg/domain/entities/reports"
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
"github.com/containers/podman/v3/pkg/rootless"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/containers/storage/pkg/stringid"
|
"github.com/containers/storage/pkg/stringid"
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
|
@ -38,12 +39,15 @@ type CtrCreateOption func(*Container) error
|
||||||
type ContainerFilter func(*Container) bool
|
type ContainerFilter func(*Container) bool
|
||||||
|
|
||||||
// NewContainer creates a new container from a given OCI config.
|
// NewContainer creates a new container from a given OCI config.
|
||||||
func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
|
func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, spec *specgen.SpecGenerator, infra bool, options ...CtrCreateOption) (*Container, error) {
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
if !r.valid {
|
if !r.valid {
|
||||||
return nil, define.ErrRuntimeStopped
|
return nil, define.ErrRuntimeStopped
|
||||||
}
|
}
|
||||||
|
if infra {
|
||||||
|
options = append(options, withIsInfra())
|
||||||
|
}
|
||||||
return r.newContainer(ctx, rSpec, options...)
|
return r.newContainer(ctx, rSpec, options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +176,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
|
||||||
}
|
}
|
||||||
ctr.config.ShmSize = size
|
ctr.config.ShmSize = size
|
||||||
ctr.config.StopSignal = 15
|
ctr.config.StopSignal = 15
|
||||||
|
|
||||||
ctr.config.StopTimeout = r.config.Engine.StopTimeout
|
ctr.config.StopTimeout = r.config.Engine.StopTimeout
|
||||||
} else {
|
} else {
|
||||||
// This is a restore from an imported checkpoint
|
// This is a restore from an imported checkpoint
|
||||||
|
@ -211,7 +216,11 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
|
func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (*Container, error) {
|
||||||
ctr, err := r.initContainerVariables(rSpec, nil)
|
var ctr *Container
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctr, err = r.initContainerVariables(rSpec, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error initializing container variables")
|
return nil, errors.Wrapf(err, "error initializing container variables")
|
||||||
}
|
}
|
||||||
|
@ -230,7 +239,9 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
||||||
if err := ctr.validate(); err != nil {
|
if err := ctr.validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if ctr.config.IsInfra {
|
||||||
|
ctr.config.StopTimeout = 10
|
||||||
|
}
|
||||||
// normalize the networks to names
|
// normalize the networks to names
|
||||||
// ocicni only knows about cni names so we have to make
|
// ocicni only knows about cni names so we have to make
|
||||||
// sure we do not use ids internally
|
// sure we do not use ids internally
|
||||||
|
@ -327,7 +338,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
||||||
switch r.config.Engine.CgroupManager {
|
switch r.config.Engine.CgroupManager {
|
||||||
case config.CgroupfsCgroupsManager:
|
case config.CgroupfsCgroupsManager:
|
||||||
if ctr.config.CgroupParent == "" {
|
if ctr.config.CgroupParent == "" {
|
||||||
if pod != nil && pod.config.UsePodCgroup {
|
if pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra() {
|
||||||
podCgroup, err := pod.CgroupPath()
|
podCgroup, err := pod.CgroupPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
|
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
|
||||||
|
@ -348,7 +359,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
||||||
case config.SystemdCgroupsManager:
|
case config.SystemdCgroupsManager:
|
||||||
if ctr.config.CgroupParent == "" {
|
if ctr.config.CgroupParent == "" {
|
||||||
switch {
|
switch {
|
||||||
case pod != nil && pod.config.UsePodCgroup:
|
case pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra():
|
||||||
podCgroup, err := pod.CgroupPath()
|
podCgroup, err := pod.CgroupPath()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
|
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID())
|
||||||
|
@ -833,7 +844,10 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
|
||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
|
|
||||||
infraID := pod.state.InfraContainerID
|
infraID, err := pod.infraContainerID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
if c.ID() == infraID {
|
if c.ID() == infraID {
|
||||||
return id, errors.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID())
|
return id, errors.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,284 +0,0 @@
|
||||||
// +build linux
|
|
||||||
|
|
||||||
package libpod
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/containers/common/pkg/config"
|
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
|
||||||
"github.com/containers/podman/v3/pkg/namespaces"
|
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
|
||||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// IDTruncLength is the length of the pod's id that will be used to make the
|
|
||||||
// infra container name
|
|
||||||
IDTruncLength = 12
|
|
||||||
)
|
|
||||||
|
|
||||||
func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawImageName, imgID string, config *v1.ImageConfig) (*Container, error) {
|
|
||||||
// Set up generator for infra container defaults
|
|
||||||
g, err := generate.New("linux")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Pod hostname
|
|
||||||
g.Config.Hostname = p.config.Hostname
|
|
||||||
|
|
||||||
var options []CtrCreateOption
|
|
||||||
|
|
||||||
// Command: If user-specified, use that preferentially.
|
|
||||||
// If not set and the config file is set, fall back to that.
|
|
||||||
var infraCtrCommand []string
|
|
||||||
if p.config.InfraContainer.InfraCommand != nil {
|
|
||||||
logrus.Debugf("User-specified infra container entrypoint %v", p.config.InfraContainer.InfraCommand)
|
|
||||||
infraCtrCommand = p.config.InfraContainer.InfraCommand
|
|
||||||
} else if r.config.Engine.InfraCommand != "" {
|
|
||||||
logrus.Debugf("Config-specified infra container entrypoint %s", r.config.Engine.InfraCommand)
|
|
||||||
infraCtrCommand = []string{r.config.Engine.InfraCommand}
|
|
||||||
}
|
|
||||||
// Only if set by the user or containers.conf, we set entrypoint for the
|
|
||||||
// infra container.
|
|
||||||
// This is only used by commit, so it shouldn't matter... But someone
|
|
||||||
// may eventually want to commit an infra container?
|
|
||||||
// TODO: Should we actually do this if set by containers.conf?
|
|
||||||
if infraCtrCommand != nil {
|
|
||||||
// Need to duplicate the array - we are going to add Cmd later
|
|
||||||
// so the current array will be changed.
|
|
||||||
newArr := make([]string, 0, len(infraCtrCommand))
|
|
||||||
newArr = append(newArr, infraCtrCommand...)
|
|
||||||
options = append(options, WithEntrypoint(newArr))
|
|
||||||
}
|
|
||||||
|
|
||||||
isRootless := rootless.IsRootless()
|
|
||||||
|
|
||||||
// I've seen circumstances where config is being passed as nil.
|
|
||||||
// Let's err on the side of safety and make sure it's safe to use.
|
|
||||||
if config != nil {
|
|
||||||
if infraCtrCommand == nil {
|
|
||||||
// If we have no entrypoint and command from the image,
|
|
||||||
// we can't go on - the infra container has no command.
|
|
||||||
if len(config.Entrypoint) == 0 && len(config.Cmd) == 0 {
|
|
||||||
return nil, errors.Errorf("infra container has no command")
|
|
||||||
}
|
|
||||||
if len(config.Entrypoint) > 0 {
|
|
||||||
infraCtrCommand = config.Entrypoint
|
|
||||||
} else {
|
|
||||||
// Use the Docker default "/bin/sh -c"
|
|
||||||
// entrypoint, as we're overriding command.
|
|
||||||
// If an image doesn't want this, it can
|
|
||||||
// override entrypoint too.
|
|
||||||
infraCtrCommand = []string{"/bin/sh", "-c"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(config.Cmd) > 0 {
|
|
||||||
infraCtrCommand = append(infraCtrCommand, config.Cmd...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(config.Env) > 0 {
|
|
||||||
for _, nameValPair := range config.Env {
|
|
||||||
nameValSlice := strings.Split(nameValPair, "=")
|
|
||||||
if len(nameValSlice) < 2 {
|
|
||||||
return nil, errors.Errorf("Invalid environment variable structure in pause image")
|
|
||||||
}
|
|
||||||
g.AddProcessEnv(nameValSlice[0], nameValSlice[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case p.config.InfraContainer.HostNetwork:
|
|
||||||
if err := g.RemoveLinuxNamespace(string(spec.NetworkNamespace)); err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID())
|
|
||||||
}
|
|
||||||
case p.config.InfraContainer.NoNetwork:
|
|
||||||
// Do nothing - we have a network namespace by default,
|
|
||||||
// but should not configure slirp.
|
|
||||||
default:
|
|
||||||
// Since user namespace sharing is not implemented, we only need to check if it's rootless
|
|
||||||
netmode := "bridge"
|
|
||||||
if p.config.InfraContainer.Slirp4netns {
|
|
||||||
netmode = "slirp4netns"
|
|
||||||
if len(p.config.InfraContainer.NetworkOptions) != 0 {
|
|
||||||
options = append(options, WithNetworkOptions(p.config.InfraContainer.NetworkOptions))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// FIXME allow pods to have exposed ports
|
|
||||||
options = append(options, WithNetNS(p.config.InfraContainer.PortBindings, nil, !p.config.InfraContainer.Userns.IsHost(), netmode, p.config.InfraContainer.Networks))
|
|
||||||
}
|
|
||||||
|
|
||||||
// For each option in InfraContainerConfig - if set, pass into
|
|
||||||
// the infra container we're creating with the appropriate
|
|
||||||
// With... option.
|
|
||||||
if p.config.InfraContainer.StaticIP != nil {
|
|
||||||
options = append(options, WithStaticIP(p.config.InfraContainer.StaticIP))
|
|
||||||
}
|
|
||||||
if p.config.InfraContainer.StaticMAC != nil {
|
|
||||||
options = append(options, WithStaticMAC(p.config.InfraContainer.StaticMAC))
|
|
||||||
}
|
|
||||||
if p.config.InfraContainer.UseImageResolvConf {
|
|
||||||
options = append(options, WithUseImageResolvConf())
|
|
||||||
}
|
|
||||||
if len(p.config.InfraContainer.DNSServer) > 0 {
|
|
||||||
options = append(options, WithDNS(p.config.InfraContainer.DNSServer))
|
|
||||||
}
|
|
||||||
if len(p.config.InfraContainer.DNSSearch) > 0 {
|
|
||||||
options = append(options, WithDNSSearch(p.config.InfraContainer.DNSSearch))
|
|
||||||
}
|
|
||||||
if len(p.config.InfraContainer.DNSOption) > 0 {
|
|
||||||
options = append(options, WithDNSOption(p.config.InfraContainer.DNSOption))
|
|
||||||
}
|
|
||||||
if p.config.InfraContainer.UseImageHosts {
|
|
||||||
options = append(options, WithUseImageHosts())
|
|
||||||
}
|
|
||||||
if len(p.config.InfraContainer.HostAdd) > 0 {
|
|
||||||
options = append(options, WithHosts(p.config.InfraContainer.HostAdd))
|
|
||||||
}
|
|
||||||
if len(p.config.InfraContainer.ExitCommand) > 0 {
|
|
||||||
options = append(options, WithExitCommand(p.config.InfraContainer.ExitCommand))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.config.UsePodPID && p.config.InfraContainer.PidNS.NSMode != "host" {
|
|
||||||
g.AddOrReplaceLinuxNamespace(string(spec.LinuxNamespaceType("pid")), p.config.InfraContainer.PidNS.Value)
|
|
||||||
} else if p.config.InfraContainer.PidNS.NSMode == "host" {
|
|
||||||
newNS := []spec.LinuxNamespace{}
|
|
||||||
for _, entry := range g.Config.Linux.Namespaces {
|
|
||||||
if entry.Type != spec.LinuxNamespaceType("pid") {
|
|
||||||
newNS = append(newNS, entry)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.Config.Linux.Namespaces = newNS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ctl := range r.config.Containers.DefaultSysctls {
|
|
||||||
sysctl := strings.SplitN(ctl, "=", 2)
|
|
||||||
if len(sysctl) < 2 {
|
|
||||||
return nil, errors.Errorf("invalid default sysctl %s", ctl)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore net sysctls if --net=host
|
|
||||||
if p.config.InfraContainer.HostNetwork && strings.HasPrefix(sysctl[0], "net.") {
|
|
||||||
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace set to host", sysctl[0], sysctl[1])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
g.AddLinuxSysctl(sysctl[0], sysctl[1])
|
|
||||||
}
|
|
||||||
|
|
||||||
g.SetRootReadonly(true)
|
|
||||||
g.SetProcessArgs(infraCtrCommand)
|
|
||||||
|
|
||||||
logrus.Debugf("Using %q as infra container command", infraCtrCommand)
|
|
||||||
|
|
||||||
mapopt, err := util.ParseIDMapping(namespaces.UsernsMode(p.config.InfraContainer.Userns.String()), []string{}, []string{}, "", "")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
user, err := specgen.SetupUserNS(mapopt, p.config.InfraContainer.Userns, &g)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if user != "" {
|
|
||||||
options = append(options, WithUser(user))
|
|
||||||
}
|
|
||||||
|
|
||||||
g.RemoveMount("/dev/shm")
|
|
||||||
if isRootless {
|
|
||||||
g.RemoveMount("/dev/pts")
|
|
||||||
devPts := spec.Mount{
|
|
||||||
Destination: "/dev/pts",
|
|
||||||
Type: "devpts",
|
|
||||||
Source: "devpts",
|
|
||||||
Options: []string{"private", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"},
|
|
||||||
}
|
|
||||||
g.AddMount(devPts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add default sysctls from containers.conf
|
|
||||||
defaultSysctls, err := util.ValidateSysctls(r.config.Sysctls())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for sysctlKey, sysctlVal := range defaultSysctls {
|
|
||||||
// Ignore mqueue sysctls if not sharing IPC
|
|
||||||
if !p.config.UsePodIPC && strings.HasPrefix(sysctlKey, "fs.mqueue.") {
|
|
||||||
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since IPC Namespace for pod is unused", sysctlKey, sysctlVal)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore net sysctls if host network or not sharing network
|
|
||||||
if (p.config.InfraContainer.HostNetwork || !p.config.UsePodNet) && strings.HasPrefix(sysctlKey, "net.") {
|
|
||||||
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since Network Namespace for pod is unused", sysctlKey, sysctlVal)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore uts sysctls if not sharing UTS
|
|
||||||
if !p.config.UsePodUTS && (strings.HasPrefix(sysctlKey, "kernel.domainname") || strings.HasPrefix(sysctlKey, "kernel.hostname")) {
|
|
||||||
logrus.Infof("Sysctl %s=%s ignored in containers.conf, since UTS Namespace for pod is unused", sysctlKey, sysctlVal)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.AddLinuxSysctl(sysctlKey, sysctlVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
containerName := p.config.InfraContainer.InfraName
|
|
||||||
if containerName == "" {
|
|
||||||
containerName = p.ID()[:IDTruncLength] + "-infra"
|
|
||||||
}
|
|
||||||
logrus.Infof("Infra container name %s", containerName)
|
|
||||||
options = append(options, r.WithPod(p))
|
|
||||||
options = append(options, WithRootFSFromImage(imgID, imgName, rawImageName))
|
|
||||||
options = append(options, WithName(containerName))
|
|
||||||
options = append(options, withIsInfra())
|
|
||||||
options = append(options, WithIDMappings(*mapopt))
|
|
||||||
if len(p.config.InfraContainer.ConmonPidFile) > 0 {
|
|
||||||
options = append(options, WithConmonPidFile(p.config.InfraContainer.ConmonPidFile))
|
|
||||||
}
|
|
||||||
newRes := new(spec.LinuxResources)
|
|
||||||
newRes.CPU = new(spec.LinuxCPU)
|
|
||||||
newRes.CPU = p.ResourceLim().CPU
|
|
||||||
g.Config.Linux.Resources.CPU = newRes.CPU
|
|
||||||
|
|
||||||
return r.newContainer(ctx, g.Config, options...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// createInfraContainer wrap creates an infra container for a pod.
|
|
||||||
// An infra container becomes the basis for kernel namespace sharing between
|
|
||||||
// containers in the pod.
|
|
||||||
func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container, error) {
|
|
||||||
if !r.valid {
|
|
||||||
return nil, define.ErrRuntimeStopped
|
|
||||||
}
|
|
||||||
imageName := p.config.InfraContainer.InfraImage
|
|
||||||
if imageName == "" {
|
|
||||||
imageName = r.config.Engine.InfraImage
|
|
||||||
}
|
|
||||||
|
|
||||||
pulledImages, err := r.LibimageRuntime().Pull(ctx, imageName, config.PullPolicyMissing, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "error pulling infra-container image")
|
|
||||||
}
|
|
||||||
|
|
||||||
newImage := pulledImages[0]
|
|
||||||
data, err := newImage.Inspect(ctx, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
imageName = "none"
|
|
||||||
if len(newImage.Names()) > 0 {
|
|
||||||
imageName = newImage.Names()[0]
|
|
||||||
}
|
|
||||||
imageID := data.ID
|
|
||||||
|
|
||||||
return r.makeInfraContainer(ctx, p, imageName, r.config.Engine.InfraImage, imageID, data.Config)
|
|
||||||
}
|
|
|
@ -14,13 +14,14 @@ import (
|
||||||
"github.com/containers/podman/v3/libpod/events"
|
"github.com/containers/podman/v3/libpod/events"
|
||||||
"github.com/containers/podman/v3/pkg/cgroups"
|
"github.com/containers/podman/v3/pkg/cgroups"
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
"github.com/containers/podman/v3/pkg/rootless"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPod makes a new, empty pod
|
// NewPod makes a new, empty pod
|
||||||
func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Pod, deferredErr error) {
|
func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, options ...PodCreateOption) (_ *Pod, deferredErr error) {
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
|
|
||||||
|
@ -50,8 +51,8 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
|
||||||
pod.config.Name = name
|
pod.config.Name = name
|
||||||
}
|
}
|
||||||
|
|
||||||
if pod.config.Hostname == "" {
|
if p.InfraContainerSpec != nil && p.InfraContainerSpec.Hostname == "" {
|
||||||
pod.config.Hostname = pod.config.Name
|
p.InfraContainerSpec.Hostname = pod.config.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a lock for the pod
|
// Allocate a lock for the pod
|
||||||
|
@ -88,6 +89,9 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
|
||||||
// launch should do it for us
|
// launch should do it for us
|
||||||
if pod.config.UsePodCgroup {
|
if pod.config.UsePodCgroup {
|
||||||
pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
|
pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
|
||||||
|
if p.InfraContainerSpec != nil {
|
||||||
|
p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case config.SystemdCgroupsManager:
|
case config.SystemdCgroupsManager:
|
||||||
|
@ -108,6 +112,9 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
|
||||||
return nil, errors.Wrapf(err, "unable to create pod cgroup for pod %s", pod.ID())
|
return nil, errors.Wrapf(err, "unable to create pod cgroup for pod %s", pod.ID())
|
||||||
}
|
}
|
||||||
pod.state.CgroupPath = cgroupPath
|
pod.state.CgroupPath = cgroupPath
|
||||||
|
if p.InfraContainerSpec != nil {
|
||||||
|
p.InfraContainerSpec.CgroupParent = pod.state.CgroupPath
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.Engine.CgroupManager)
|
return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.Engine.CgroupManager)
|
||||||
|
@ -127,28 +134,40 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
|
||||||
if err := r.state.AddPod(pod); err != nil {
|
if err := r.state.AddPod(pod); err != nil {
|
||||||
return nil, errors.Wrapf(err, "error adding pod to state")
|
return nil, errors.Wrapf(err, "error adding pod to state")
|
||||||
}
|
}
|
||||||
defer func() {
|
return pod, nil
|
||||||
if deferredErr != nil {
|
}
|
||||||
if err := r.removePod(ctx, pod, true, true); err != nil {
|
|
||||||
logrus.Errorf("Error removing pod after pause container creation failure: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if pod.HasInfraContainer() {
|
// AddInfra adds the created infra container to the pod state
|
||||||
ctr, err := r.createInfraContainer(ctx, pod)
|
func (r *Runtime) AddInfra(ctx context.Context, pod *Pod, infraCtr *Container) (*Pod, error) {
|
||||||
if err != nil {
|
r.lock.Lock()
|
||||||
return nil, errors.Wrapf(err, "error adding Infra Container")
|
defer r.lock.Unlock()
|
||||||
}
|
|
||||||
pod.state.InfraContainerID = ctr.ID()
|
if !r.valid {
|
||||||
if err := pod.save(); err != nil {
|
return nil, define.ErrRuntimeStopped
|
||||||
return nil, err
|
}
|
||||||
}
|
pod.state.InfraContainerID = infraCtr.ID()
|
||||||
|
if err := pod.save(); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
pod.newPodEvent(events.Create)
|
pod.newPodEvent(events.Create)
|
||||||
return pod, nil
|
return pod, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SavePod is a helper function to save the pod state from outside of libpod
|
||||||
|
func (r *Runtime) SavePod(pod *Pod) error {
|
||||||
|
r.lock.Lock()
|
||||||
|
defer r.lock.Unlock()
|
||||||
|
|
||||||
|
if !r.valid {
|
||||||
|
return define.ErrRuntimeStopped
|
||||||
|
}
|
||||||
|
if err := pod.save(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pod.newPodEvent(events.Create)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) error {
|
func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) error {
|
||||||
if err := p.updatePod(); err != nil {
|
if err := p.updatePod(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/domain/infra/abi"
|
"github.com/containers/podman/v3/pkg/domain/infra/abi"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/containers/storage"
|
"github.com/containers/storage"
|
||||||
"github.com/gorilla/schema"
|
"github.com/gorilla/schema"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -80,7 +81,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
|
sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
|
||||||
if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil {
|
if err := specgenutil.FillOutSpecGen(sg, cliOpts, args); err != nil {
|
||||||
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,12 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
|
||||||
utils.InternalServerError(w, err)
|
utils.InternalServerError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctr, err := generate.MakeContainer(context.Background(), runtime, &sg)
|
rtSpec, spec, opts, err := generate.MakeContainer(context.Background(), runtime, &sg)
|
||||||
|
if err != nil {
|
||||||
|
utils.InternalServerError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctr, err := generate.ExecuteCreate(context.Background(), runtime, rtSpec, spec, false, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.InternalServerError(w, err)
|
utils.InternalServerError(w, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containers/common/libimage"
|
||||||
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/containers/image/v5/transports/alltransports"
|
||||||
"github.com/containers/podman/v3/libpod"
|
"github.com/containers/podman/v3/libpod"
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/api/handlers"
|
"github.com/containers/podman/v3/pkg/api/handlers"
|
||||||
|
@ -14,6 +18,7 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/domain/infra/abi"
|
"github.com/containers/podman/v3/pkg/domain/infra/abi"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
"github.com/containers/podman/v3/pkg/specgen/generate"
|
"github.com/containers/podman/v3/pkg/specgen/generate"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
"github.com/gorilla/schema"
|
"github.com/gorilla/schema"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -25,24 +30,70 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
|
||||||
runtime = r.Context().Value("runtime").(*libpod.Runtime)
|
runtime = r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
var psg specgen.PodSpecGenerator
|
psg := specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&psg); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&psg); err != nil {
|
||||||
utils.Error(w, "failed to decode specgen", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// parse userns so we get the valid default value of userns
|
|
||||||
psg.Userns, err = specgen.ParseUserNamespace(psg.Userns.String())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Error(w, "failed to parse userns", http.StatusInternalServerError, errors.Wrap(err, "failed to parse userns"))
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pod, err := generate.MakePod(&psg, runtime)
|
if !psg.NoInfra {
|
||||||
|
infraOptions := &entities.ContainerCreateOptions{ImageVolume: "bind", IsInfra: true, Net: &entities.NetOptions{}} // options for pulling the image and FillOutSpec
|
||||||
|
err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings)
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error filling out specgen"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
out, err := json.Marshal(psg) // marshal our spec so the matching options can be unmarshaled into infra
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tempSpec := &specgen.SpecGenerator{} // temporary spec since infra cannot be decoded into
|
||||||
|
err = json.Unmarshal(out, tempSpec) // unmarhal matching options
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to decode specgen"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
psg.InfraContainerSpec = tempSpec // set infra spec equal to temp
|
||||||
|
// a few extra that do not have the same json tags
|
||||||
|
psg.InfraContainerSpec.Name = psg.InfraName
|
||||||
|
psg.InfraContainerSpec.ConmonPidFile = psg.InfraConmonPidFile
|
||||||
|
psg.InfraContainerSpec.ContainerCreateCommand = psg.InfraCommand
|
||||||
|
imageName := psg.InfraImage
|
||||||
|
rawImageName := psg.InfraImage
|
||||||
|
if imageName == "" {
|
||||||
|
imageName = config.DefaultInfraImage
|
||||||
|
rawImageName = config.DefaultInfraImage
|
||||||
|
}
|
||||||
|
curr := infraOptions.Quiet
|
||||||
|
infraOptions.Quiet = true
|
||||||
|
pullOptions := &libimage.PullOptions{}
|
||||||
|
pulledImages, err := runtime.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, pullOptions)
|
||||||
|
if err != nil {
|
||||||
|
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "could not pull image"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, err := alltransports.ParseImageName(imageName); err == nil {
|
||||||
|
if len(pulledImages) != 0 {
|
||||||
|
imageName = pulledImages[0].ID()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infraOptions.Quiet = curr
|
||||||
|
psg.InfraImage = imageName
|
||||||
|
psg.InfraContainerSpec.Image = imageName
|
||||||
|
psg.InfraContainerSpec.RawImageName = rawImageName
|
||||||
|
}
|
||||||
|
podSpecComplete := entities.PodSpec{PodSpecGen: psg}
|
||||||
|
pod, err := generate.MakePod(&podSpecComplete, runtime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpCode := http.StatusInternalServerError
|
httpCode := http.StatusInternalServerError
|
||||||
if errors.Cause(err) == define.ErrPodExists {
|
if errors.Cause(err) == define.ErrPodExists {
|
||||||
httpCode = http.StatusConflict
|
httpCode = http.StatusConflict
|
||||||
}
|
}
|
||||||
utils.Error(w, "Something went wrong.", httpCode, err)
|
utils.Error(w, "Something went wrong.", httpCode, errors.Wrap(err, "failed to make pod"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
utils.WriteResponse(w, http.StatusCreated, handlers.IDResponse{ID: pod.ID()})
|
utils.WriteResponse(w, http.StatusCreated, handlers.IDResponse{ID: pod.ID()})
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import "github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LibpodImagesRemoveReport is the return type for image removal via the rest
|
// LibpodImagesRemoveReport is the return type for image removal via the rest
|
||||||
// api.
|
// api.
|
||||||
|
|
|
@ -9,27 +9,25 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/api/handlers"
|
"github.com/containers/podman/v3/pkg/api/handlers"
|
||||||
"github.com/containers/podman/v3/pkg/bindings"
|
"github.com/containers/podman/v3/pkg/bindings"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreatePodFromSpec(ctx context.Context, s *specgen.PodSpecGenerator, options *CreateOptions) (*entities.PodCreateReport, error) {
|
func CreatePodFromSpec(ctx context.Context, spec *entities.PodSpec) (*entities.PodCreateReport, error) {
|
||||||
var (
|
var (
|
||||||
pcr entities.PodCreateReport
|
pcr entities.PodCreateReport
|
||||||
)
|
)
|
||||||
if options == nil {
|
if spec == nil {
|
||||||
options = new(CreateOptions)
|
spec = new(entities.PodSpec)
|
||||||
}
|
}
|
||||||
_ = options
|
|
||||||
conn, err := bindings.GetClient(ctx)
|
conn, err := bindings.GetClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
specgenString, err := jsoniter.MarshalToString(s)
|
specString, err := jsoniter.MarshalToString(spec.PodSpecGen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
stringReader := strings.NewReader(specgenString)
|
stringReader := strings.NewReader(specString)
|
||||||
response, err := conn.DoRequest(stringReader, http.MethodPost, "/pods/create", nil, nil)
|
response, err := conn.DoRequest(stringReader, http.MethodPost, "/pods/create", nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/bindings"
|
"github.com/containers/podman/v3/pkg/bindings"
|
||||||
"github.com/containers/podman/v3/pkg/bindings/pods"
|
"github.com/containers/podman/v3/pkg/bindings/pods"
|
||||||
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
@ -333,9 +334,9 @@ var _ = Describe("Podman pods", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("simple create pod", func() {
|
It("simple create pod", func() {
|
||||||
ps := specgen.PodSpecGenerator{}
|
ps := entities.PodSpec{PodSpecGen: specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}}}
|
||||||
ps.Name = "foobar"
|
ps.PodSpecGen.Name = "foobar"
|
||||||
_, err := pods.CreatePodFromSpec(bt.conn, &ps, nil)
|
_, err := pods.CreatePodFromSpec(bt.conn, &ps)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
exists, err := pods.Exists(bt.conn, "foobar", nil)
|
exists, err := pods.Exists(bt.conn, "foobar", nil)
|
||||||
|
|
|
@ -68,7 +68,7 @@ type ContainerEngine interface {
|
||||||
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
|
NetworkRm(ctx context.Context, namesOrIds []string, options NetworkRmOptions) ([]*NetworkRmReport, error)
|
||||||
PlayKube(ctx context.Context, path string, opts PlayKubeOptions) (*PlayKubeReport, error)
|
PlayKube(ctx context.Context, path string, opts PlayKubeOptions) (*PlayKubeReport, error)
|
||||||
PlayKubeDown(ctx context.Context, path string, opts PlayKubeDownOptions) (*PlayKubeReport, error)
|
PlayKubeDown(ctx context.Context, path string, opts PlayKubeDownOptions) (*PlayKubeReport, error)
|
||||||
PodCreate(ctx context.Context, opts PodCreateOptions) (*PodCreateReport, error)
|
PodCreate(ctx context.Context, specg PodSpec) (*PodCreateReport, error)
|
||||||
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
|
PodExists(ctx context.Context, nameOrID string) (*BoolReport, error)
|
||||||
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
|
PodInspect(ctx context.Context, options PodInspectOptions) (*PodInspectReport, error)
|
||||||
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
|
PodKill(ctx context.Context, namesOrIds []string, options PodKillOptions) ([]*PodKillReport, error)
|
||||||
|
|
|
@ -106,6 +106,14 @@ type PodRmReport struct {
|
||||||
Id string //nolint
|
Id string //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PddSpec is an abstracted version of PodSpecGen designed to eventually accept options
|
||||||
|
// not meant to be in a specgen
|
||||||
|
type PodSpec struct {
|
||||||
|
PodSpecGen specgen.PodSpecGenerator
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodCreateOptions provides all possible options for creating a pod and its infra container
|
||||||
|
// swagger:model PodCreateOptions
|
||||||
type PodCreateOptions struct {
|
type PodCreateOptions struct {
|
||||||
CGroupParent string
|
CGroupParent string
|
||||||
CreateCommand []string
|
CreateCommand []string
|
||||||
|
@ -125,6 +133,123 @@ type PodCreateOptions struct {
|
||||||
Userns specgen.Namespace
|
Userns specgen.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ContainerCreateOptions struct {
|
||||||
|
Annotation []string
|
||||||
|
Attach []string
|
||||||
|
Authfile string
|
||||||
|
BlkIOWeight string
|
||||||
|
BlkIOWeightDevice []string
|
||||||
|
CapAdd []string
|
||||||
|
CapDrop []string
|
||||||
|
CgroupNS string
|
||||||
|
CGroupsMode string
|
||||||
|
CGroupParent string
|
||||||
|
CIDFile string
|
||||||
|
ConmonPIDFile string
|
||||||
|
CPUPeriod uint64
|
||||||
|
CPUQuota int64
|
||||||
|
CPURTPeriod uint64
|
||||||
|
CPURTRuntime int64
|
||||||
|
CPUShares uint64
|
||||||
|
CPUS float64
|
||||||
|
CPUSetCPUs string
|
||||||
|
CPUSetMems string
|
||||||
|
Devices []string
|
||||||
|
DeviceCGroupRule []string
|
||||||
|
DeviceReadBPs []string
|
||||||
|
DeviceReadIOPs []string
|
||||||
|
DeviceWriteBPs []string
|
||||||
|
DeviceWriteIOPs []string
|
||||||
|
Entrypoint *string
|
||||||
|
Env []string
|
||||||
|
EnvHost bool
|
||||||
|
EnvFile []string
|
||||||
|
Expose []string
|
||||||
|
GIDMap []string
|
||||||
|
GroupAdd []string
|
||||||
|
HealthCmd string
|
||||||
|
HealthInterval string
|
||||||
|
HealthRetries uint
|
||||||
|
HealthStartPeriod string
|
||||||
|
HealthTimeout string
|
||||||
|
Hostname string
|
||||||
|
HTTPProxy bool
|
||||||
|
ImageVolume string
|
||||||
|
Init bool
|
||||||
|
InitContainerType string
|
||||||
|
InitPath string
|
||||||
|
Interactive bool
|
||||||
|
IPC string
|
||||||
|
KernelMemory string
|
||||||
|
Label []string
|
||||||
|
LabelFile []string
|
||||||
|
LogDriver string
|
||||||
|
LogOptions []string
|
||||||
|
Memory string
|
||||||
|
MemoryReservation string
|
||||||
|
MemorySwap string
|
||||||
|
MemorySwappiness int64
|
||||||
|
Name string
|
||||||
|
NoHealthCheck bool
|
||||||
|
OOMKillDisable bool
|
||||||
|
OOMScoreAdj int
|
||||||
|
Arch string
|
||||||
|
OS string
|
||||||
|
Variant string
|
||||||
|
PID string
|
||||||
|
PIDsLimit *int64
|
||||||
|
Platform string
|
||||||
|
Pod string
|
||||||
|
PodIDFile string
|
||||||
|
Personality string
|
||||||
|
PreserveFDs uint
|
||||||
|
Privileged bool
|
||||||
|
PublishAll bool
|
||||||
|
Pull string
|
||||||
|
Quiet bool
|
||||||
|
ReadOnly bool
|
||||||
|
ReadOnlyTmpFS bool
|
||||||
|
Restart string
|
||||||
|
Replace bool
|
||||||
|
Requires []string
|
||||||
|
Rm bool
|
||||||
|
RootFS bool
|
||||||
|
Secrets []string
|
||||||
|
SecurityOpt []string
|
||||||
|
SdNotifyMode string
|
||||||
|
ShmSize string
|
||||||
|
SignaturePolicy string
|
||||||
|
StopSignal string
|
||||||
|
StopTimeout uint
|
||||||
|
StorageOpt []string
|
||||||
|
SubUIDName string
|
||||||
|
SubGIDName string
|
||||||
|
Sysctl []string
|
||||||
|
Systemd string
|
||||||
|
Timeout uint
|
||||||
|
TLSVerify bool
|
||||||
|
TmpFS []string
|
||||||
|
TTY bool
|
||||||
|
Timezone string
|
||||||
|
Umask string
|
||||||
|
UIDMap []string
|
||||||
|
Ulimit []string
|
||||||
|
User string
|
||||||
|
UserNS string
|
||||||
|
UTS string
|
||||||
|
Mount []string
|
||||||
|
Volume []string
|
||||||
|
VolumesFrom []string
|
||||||
|
Workdir string
|
||||||
|
SeccompPolicy string
|
||||||
|
PidFile string
|
||||||
|
IsInfra bool
|
||||||
|
|
||||||
|
Net *NetOptions
|
||||||
|
|
||||||
|
CgroupConf []string
|
||||||
|
}
|
||||||
|
|
||||||
type PodCreateReport struct {
|
type PodCreateReport struct {
|
||||||
Id string //nolint
|
Id string //nolint
|
||||||
}
|
}
|
||||||
|
@ -149,21 +274,15 @@ func (p *PodCreateOptions) CPULimits() *specs.LinuxCPU {
|
||||||
return cpu
|
return cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNamespaces(p *PodCreateOptions) ([4]specgen.Namespace, error) {
|
func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.PodSpecGenerator, error) {
|
||||||
allNS := [4]specgen.Namespace{}
|
|
||||||
if p.Pid != "" {
|
|
||||||
pid, err := specgen.ParseNamespace(p.Pid)
|
|
||||||
if err != nil {
|
|
||||||
return [4]specgen.Namespace{}, err
|
|
||||||
}
|
|
||||||
allNS[0] = pid
|
|
||||||
}
|
|
||||||
return allNS, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
|
|
||||||
// Basic Config
|
// Basic Config
|
||||||
s.Name = p.Name
|
s.Name = p.Name
|
||||||
|
s.InfraName = p.InfraName
|
||||||
|
out, err := specgen.ParseNamespace(p.Pid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.Pid = out
|
||||||
s.Hostname = p.Hostname
|
s.Hostname = p.Hostname
|
||||||
s.Labels = p.Labels
|
s.Labels = p.Labels
|
||||||
s.NoInfra = !p.Infra
|
s.NoInfra = !p.Infra
|
||||||
|
@ -174,32 +293,26 @@ func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
|
||||||
s.InfraConmonPidFile = p.InfraConmonPidFile
|
s.InfraConmonPidFile = p.InfraConmonPidFile
|
||||||
}
|
}
|
||||||
s.InfraImage = p.InfraImage
|
s.InfraImage = p.InfraImage
|
||||||
s.InfraName = p.InfraName
|
|
||||||
s.SharedNamespaces = p.Share
|
s.SharedNamespaces = p.Share
|
||||||
s.PodCreateCommand = p.CreateCommand
|
s.PodCreateCommand = p.CreateCommand
|
||||||
|
|
||||||
// Networking config
|
// Networking config
|
||||||
s.NetNS = p.Net.Network
|
|
||||||
s.StaticIP = p.Net.StaticIP
|
|
||||||
s.StaticMAC = p.Net.StaticMAC
|
|
||||||
s.PortMappings = p.Net.PublishPorts
|
|
||||||
s.CNINetworks = p.Net.CNINetworks
|
|
||||||
s.NetworkOptions = p.Net.NetworkOptions
|
|
||||||
if p.Net.UseImageResolvConf {
|
|
||||||
s.NoManageResolvConf = true
|
|
||||||
}
|
|
||||||
s.DNSServer = p.Net.DNSServers
|
|
||||||
s.DNSSearch = p.Net.DNSSearch
|
|
||||||
s.DNSOption = p.Net.DNSOptions
|
|
||||||
s.NoManageHosts = p.Net.NoHosts
|
|
||||||
s.HostAdd = p.Net.AddHosts
|
|
||||||
|
|
||||||
namespaces, err := setNamespaces(p)
|
if p.Net != nil {
|
||||||
if err != nil {
|
s.NetNS = p.Net.Network
|
||||||
return err
|
s.StaticIP = p.Net.StaticIP
|
||||||
}
|
s.StaticMAC = p.Net.StaticMAC
|
||||||
if !namespaces[0].IsDefault() {
|
s.PortMappings = p.Net.PublishPorts
|
||||||
s.Pid = namespaces[0]
|
s.CNINetworks = p.Net.CNINetworks
|
||||||
|
s.NetworkOptions = p.Net.NetworkOptions
|
||||||
|
if p.Net.UseImageResolvConf {
|
||||||
|
s.NoManageResolvConf = true
|
||||||
|
}
|
||||||
|
s.DNSServer = p.Net.DNSServers
|
||||||
|
s.DNSSearch = p.Net.DNSSearch
|
||||||
|
s.DNSOption = p.Net.DNSOptions
|
||||||
|
s.NoManageHosts = p.Net.NoHosts
|
||||||
|
s.HostAdd = p.Net.AddHosts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cgroup
|
// Cgroup
|
||||||
|
@ -219,7 +332,7 @@ func (p *PodCreateOptions) ToPodSpecGen(s *specgen.PodSpecGenerator) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.Userns = p.Userns
|
s.Userns = p.Userns
|
||||||
return nil
|
return &s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PodPruneOptions struct {
|
type PodPruneOptions struct {
|
||||||
|
|
|
@ -31,21 +31,33 @@ type VolumeDeleteReport struct{ Report }
|
||||||
|
|
||||||
// NetOptions reflect the shared network options between
|
// NetOptions reflect the shared network options between
|
||||||
// pods and containers
|
// pods and containers
|
||||||
|
type NetFlags struct {
|
||||||
|
AddHosts []string `json:"add-host,omitempty"`
|
||||||
|
DNS []string `json:"dns,omitempty"`
|
||||||
|
DNSOpt []string `json:"dns-opt,omitempty"`
|
||||||
|
DNDSearch []string `json:"dns-search,omitempty"`
|
||||||
|
MacAddr string `json:"mac-address,omitempty"`
|
||||||
|
Publish []string `json:"publish,omitempty"`
|
||||||
|
IP string `json:"ip,omitempty"`
|
||||||
|
NoHosts bool `json:"no-hosts,omitempty"`
|
||||||
|
Network string `json:"network,omitempty"`
|
||||||
|
NetworkAlias []string `json:"network-alias,omitempty"`
|
||||||
|
}
|
||||||
type NetOptions struct {
|
type NetOptions struct {
|
||||||
AddHosts []string
|
AddHosts []string `json:"hostadd,omitempty"`
|
||||||
Aliases []string
|
Aliases []string `json:"network_alias,omitempty"`
|
||||||
CNINetworks []string
|
CNINetworks []string `json:"cni_networks,omitempty"`
|
||||||
UseImageResolvConf bool
|
UseImageResolvConf bool `json:"no_manage_resolv_conf,omitempty"`
|
||||||
DNSOptions []string
|
DNSOptions []string `json:"dns_option,omitempty"`
|
||||||
DNSSearch []string
|
DNSSearch []string `json:"dns_search,omitempty"`
|
||||||
DNSServers []net.IP
|
DNSServers []net.IP `json:"dns_server,omitempty"`
|
||||||
Network specgen.Namespace
|
Network specgen.Namespace `json:"netns,omitempty"`
|
||||||
NoHosts bool
|
NoHosts bool `json:"no_manage_hosts,omitempty"`
|
||||||
PublishPorts []types.PortMapping
|
PublishPorts []types.PortMapping `json:"portmappings,omitempty"`
|
||||||
StaticIP *net.IP
|
StaticIP *net.IP `json:"static_ip,omitempty"`
|
||||||
StaticMAC *net.HardwareAddr
|
StaticMAC *net.HardwareAddr `json:"static_mac,omitempty"`
|
||||||
// NetworkOptions are additional options for each network
|
// NetworkOptions are additional options for each network
|
||||||
NetworkOptions map[string][]string
|
NetworkOptions map[string][]string `json:"network_options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// All CLI inspect commands and inspect sub-commands use the same options
|
// All CLI inspect commands and inspect sub-commands use the same options
|
||||||
|
|
|
@ -583,7 +583,11 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG
|
||||||
for _, w := range warn {
|
for _, w := range warn {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", w)
|
fmt.Fprintf(os.Stderr, "%s\n", w)
|
||||||
}
|
}
|
||||||
ctr, err := generate.MakeContainer(ctx, ic.Libpod, s)
|
rtSpec, spec, opts, err := generate.MakeContainer(context.Background(), ic.Libpod, s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -915,7 +919,11 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
||||||
for _, w := range warn {
|
for _, w := range warn {
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", w)
|
fmt.Fprintf(os.Stderr, "%s\n", w)
|
||||||
}
|
}
|
||||||
ctr, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec)
|
rtSpec, spec, optsN, err := generate.MakeContainer(ctx, ic.Libpod, opts.Spec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, optsN...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,9 +60,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if len(ctr.Dependencies()) > 0 {
|
// now that infra holds NS data, we need to support dependencies.
|
||||||
return nil, errors.Wrapf(define.ErrNotImplemented, "containers with dependencies")
|
|
||||||
}
|
|
||||||
// we cannot deal with ctrs already in a pod.
|
// we cannot deal with ctrs already in a pod.
|
||||||
if len(ctr.PodID()) > 0 {
|
if len(ctr.PodID()) > 0 {
|
||||||
return nil, errors.Errorf("container %s is associated with pod %s: use generate on the pod itself", ctr.ID(), ctr.PodID())
|
return nil, errors.Errorf("container %s is associated with pod %s: use generate on the pod itself", ctr.ID(), ctr.PodID())
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -22,6 +23,7 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
"github.com/containers/podman/v3/pkg/specgen/generate"
|
"github.com/containers/podman/v3/pkg/specgen/generate"
|
||||||
"github.com/containers/podman/v3/pkg/specgen/generate/kube"
|
"github.com/containers/podman/v3/pkg/specgen/generate/kube"
|
||||||
|
"github.com/containers/podman/v3/pkg/specgenutil"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -179,10 +181,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p, err := kube.ToPodGen(ctx, podName, podYAML)
|
podOpt := entities.PodCreateOptions{Infra: true, Net: &entities.NetOptions{StaticIP: &net.IP{}, StaticMAC: &net.HardwareAddr{}}}
|
||||||
|
podOpt, err = kube.ToPodOpt(ctx, podName, podOpt, podYAML)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Network != "" {
|
if options.Network != "" {
|
||||||
ns, cniNets, netOpts, err := specgen.ParseNetworkString(options.Network)
|
ns, cniNets, netOpts, err := specgen.ParseNetworkString(options.Network)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -193,42 +197,37 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||||
return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML")
|
return nil, errors.Errorf("invalid value passed to --network: bridge or host networking must be configured in YAML")
|
||||||
}
|
}
|
||||||
logrus.Debugf("Pod %q joining CNI networks: %v", podName, cniNets)
|
logrus.Debugf("Pod %q joining CNI networks: %v", podName, cniNets)
|
||||||
p.NetNS.NSMode = specgen.Bridge
|
podOpt.Net.Network.NSMode = specgen.Bridge
|
||||||
p.CNINetworks = append(p.CNINetworks, cniNets...)
|
podOpt.Net.CNINetworks = append(podOpt.Net.CNINetworks, cniNets...)
|
||||||
if len(netOpts) > 0 {
|
if len(netOpts) > 0 {
|
||||||
p.NetworkOptions = netOpts
|
podOpt.Net.NetworkOptions = netOpts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(options.StaticIPs) > *ipIndex {
|
if len(options.StaticIPs) > *ipIndex {
|
||||||
p.StaticIP = &options.StaticIPs[*ipIndex]
|
podOpt.Net.StaticIP = &options.StaticIPs[*ipIndex]
|
||||||
} else if len(options.StaticIPs) > 0 {
|
} else if len(options.StaticIPs) > 0 {
|
||||||
// only warn if the user has set at least one ip
|
// only warn if the user has set at least one ip
|
||||||
logrus.Warn("No more static ips left using a random one")
|
logrus.Warn("No more static ips left using a random one")
|
||||||
}
|
}
|
||||||
if len(options.StaticMACs) > *ipIndex {
|
if len(options.StaticMACs) > *ipIndex {
|
||||||
p.StaticMAC = &options.StaticMACs[*ipIndex]
|
podOpt.Net.StaticMAC = &options.StaticMACs[*ipIndex]
|
||||||
} else if len(options.StaticIPs) > 0 {
|
} else if len(options.StaticIPs) > 0 {
|
||||||
// only warn if the user has set at least one mac
|
// only warn if the user has set at least one mac
|
||||||
logrus.Warn("No more static macs left using a random one")
|
logrus.Warn("No more static macs left using a random one")
|
||||||
}
|
}
|
||||||
*ipIndex++
|
*ipIndex++
|
||||||
|
|
||||||
// Create the Pod
|
p := specgen.NewPodSpecGenerator()
|
||||||
pod, err := generate.MakePod(p, ic.Libpod)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
podInfraID, err := pod.InfraContainerID()
|
p, err = entities.ToPodSpecGen(*p, &podOpt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
podSpec := entities.PodSpec{PodSpecGen: *p}
|
||||||
if !options.Quiet {
|
|
||||||
writer = os.Stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes)
|
volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -267,112 +266,146 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||||
configMaps = append(configMaps, cm)
|
configMaps = append(configMaps, cm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if podOpt.Infra {
|
||||||
|
imagePull := config.DefaultInfraImage
|
||||||
|
if podOpt.InfraImage != config.DefaultInfraImage && podOpt.InfraImage != "" {
|
||||||
|
imagePull = podOpt.InfraImage
|
||||||
|
}
|
||||||
|
|
||||||
|
pulledImages, err := pullImage(ic, writer, imagePull, options, config.PullPolicyNewer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
infraOptions := entities.ContainerCreateOptions{ImageVolume: "bind"}
|
||||||
|
|
||||||
|
podSpec.PodSpecGen.InfraImage = pulledImages[0].Names()[0]
|
||||||
|
podSpec.PodSpecGen.NoInfra = false
|
||||||
|
podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(pulledImages[0].Names()[0], false)
|
||||||
|
podSpec.PodSpecGen.InfraContainerSpec.NetworkOptions = p.NetworkOptions
|
||||||
|
|
||||||
|
err = specgenutil.FillOutSpecGen(podSpec.PodSpecGen.InfraContainerSpec, &infraOptions, []string{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Pod
|
||||||
|
pod, err := generate.MakePod(&podSpec, ic.Libpod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
podInfraID, err := pod.InfraContainerID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !options.Quiet {
|
||||||
|
writer = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
containers := make([]*libpod.Container, 0, len(podYAML.Spec.Containers))
|
containers := make([]*libpod.Container, 0, len(podYAML.Spec.Containers))
|
||||||
cwd, err := os.Getwd()
|
cwd, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, container := range podYAML.Spec.Containers {
|
for _, container := range podYAML.Spec.Containers {
|
||||||
// Contains all labels obtained from kube
|
if !strings.Contains("infra", container.Name) {
|
||||||
labels := make(map[string]string)
|
// Contains all labels obtained from kube
|
||||||
var pulledImage *libimage.Image
|
labels := make(map[string]string)
|
||||||
buildFile, err := getBuildFile(container.Image, cwd)
|
var pulledImage *libimage.Image
|
||||||
if err != nil {
|
buildFile, err := getBuildFile(container.Image, cwd)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
existsLocally, err := ic.Libpod.LibimageRuntime().Exists(container.Image)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if (len(buildFile) > 0 && !existsLocally) || (len(buildFile) > 0 && options.Build) {
|
|
||||||
buildOpts := new(buildahDefine.BuildOptions)
|
|
||||||
commonOpts := new(buildahDefine.CommonBuildOptions)
|
|
||||||
buildOpts.ConfigureNetwork = buildahDefine.NetworkDefault
|
|
||||||
buildOpts.Isolation = buildahDefine.IsolationChroot
|
|
||||||
buildOpts.CommonBuildOpts = commonOpts
|
|
||||||
buildOpts.Output = container.Image
|
|
||||||
if _, _, err := ic.Libpod.Build(ctx, *buildOpts, []string{buildFile}...); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i, _, err := ic.Libpod.LibimageRuntime().LookupImage(container.Image, new(libimage.LookupImageOptions))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pulledImage = i
|
existsLocally, err := ic.Libpod.LibimageRuntime().Exists(container.Image)
|
||||||
} else {
|
if err != nil {
|
||||||
// NOTE: set the pull policy to "newer". This will cover cases
|
return nil, err
|
||||||
// where the "latest" tag requires a pull and will also
|
}
|
||||||
// transparently handle "localhost/" prefixed files which *may*
|
if (len(buildFile) > 0 && !existsLocally) || (len(buildFile) > 0 && options.Build) {
|
||||||
// refer to a locally built image OR an image running a
|
buildOpts := new(buildahDefine.BuildOptions)
|
||||||
// registry on localhost.
|
commonOpts := new(buildahDefine.CommonBuildOptions)
|
||||||
pullPolicy := config.PullPolicyNewer
|
buildOpts.ConfigureNetwork = buildahDefine.NetworkDefault
|
||||||
if len(container.ImagePullPolicy) > 0 {
|
buildOpts.Isolation = buildahDefine.IsolationChroot
|
||||||
// Make sure to lower the strings since K8s pull policy
|
buildOpts.CommonBuildOpts = commonOpts
|
||||||
// may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905).
|
buildOpts.Output = container.Image
|
||||||
rawPolicy := string(container.ImagePullPolicy)
|
if _, _, err := ic.Libpod.Build(ctx, *buildOpts, []string{buildFile}...); err != nil {
|
||||||
pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy))
|
return nil, err
|
||||||
|
}
|
||||||
|
i, _, err := ic.Libpod.LibimageRuntime().LookupImage(container.Image, new(libimage.LookupImageOptions))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
pulledImage = i
|
||||||
|
} else {
|
||||||
|
// NOTE: set the pull policy to "newer". This will cover cases
|
||||||
|
// where the "latest" tag requires a pull and will also
|
||||||
|
// transparently handle "localhost/" prefixed files which *may*
|
||||||
|
// refer to a locally built image OR an image running a
|
||||||
|
// registry on localhost.
|
||||||
|
pullPolicy := config.PullPolicyNewer
|
||||||
|
if len(container.ImagePullPolicy) > 0 {
|
||||||
|
// Make sure to lower the strings since K8s pull policy
|
||||||
|
// may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905).
|
||||||
|
rawPolicy := string(container.ImagePullPolicy)
|
||||||
|
pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pulledImages, err := pullImage(ic, writer, container.Image, options, pullPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pulledImage = pulledImages[0]
|
||||||
}
|
}
|
||||||
// This ensures the image is the image store
|
|
||||||
pullOptions := &libimage.PullOptions{}
|
|
||||||
pullOptions.AuthFilePath = options.Authfile
|
|
||||||
pullOptions.CertDirPath = options.CertDir
|
|
||||||
pullOptions.SignaturePolicyPath = options.SignaturePolicy
|
|
||||||
pullOptions.Writer = writer
|
|
||||||
pullOptions.Username = options.Username
|
|
||||||
pullOptions.Password = options.Password
|
|
||||||
pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
|
|
||||||
|
|
||||||
pulledImages, err := ic.Libpod.LibimageRuntime().Pull(ctx, container.Image, pullPolicy, pullOptions)
|
// Handle kube annotations
|
||||||
|
for k, v := range annotations {
|
||||||
|
switch k {
|
||||||
|
// Auto update annotation without container name will apply to
|
||||||
|
// all containers within the pod
|
||||||
|
case autoupdate.Label, autoupdate.AuthfileLabel:
|
||||||
|
labels[k] = v
|
||||||
|
// Auto update annotation with container name will apply only
|
||||||
|
// to the specified container
|
||||||
|
case fmt.Sprintf("%s/%s", autoupdate.Label, container.Name),
|
||||||
|
fmt.Sprintf("%s/%s", autoupdate.AuthfileLabel, container.Name):
|
||||||
|
prefixAndCtr := strings.Split(k, "/")
|
||||||
|
labels[prefixAndCtr[0]] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
specgenOpts := kube.CtrSpecGenOptions{
|
||||||
|
Container: container,
|
||||||
|
Image: pulledImage,
|
||||||
|
Volumes: volumes,
|
||||||
|
PodID: pod.ID(),
|
||||||
|
PodName: podName,
|
||||||
|
PodInfraID: podInfraID,
|
||||||
|
ConfigMaps: configMaps,
|
||||||
|
SeccompPaths: seccompPaths,
|
||||||
|
RestartPolicy: ctrRestartPolicy,
|
||||||
|
NetNSIsHost: p.NetNS.IsHost(),
|
||||||
|
SecretsManager: secretsManager,
|
||||||
|
LogDriver: options.LogDriver,
|
||||||
|
Labels: labels,
|
||||||
|
}
|
||||||
|
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pulledImage = pulledImages[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle kube annotations
|
rtSpec, spec, opts, err := generate.MakeContainer(ctx, ic.Libpod, specGen)
|
||||||
for k, v := range annotations {
|
if err != nil {
|
||||||
switch k {
|
return nil, err
|
||||||
// Auto update annotation without container name will apply to
|
|
||||||
// all containers within the pod
|
|
||||||
case autoupdate.Label, autoupdate.AuthfileLabel:
|
|
||||||
labels[k] = v
|
|
||||||
// Auto update annotation with container name will apply only
|
|
||||||
// to the specified container
|
|
||||||
case fmt.Sprintf("%s/%s", autoupdate.Label, container.Name),
|
|
||||||
fmt.Sprintf("%s/%s", autoupdate.AuthfileLabel, container.Name):
|
|
||||||
prefixAndCtr := strings.Split(k, "/")
|
|
||||||
labels[prefixAndCtr[0]] = v
|
|
||||||
}
|
}
|
||||||
|
ctr, err := generate.ExecuteCreate(ctx, ic.Libpod, rtSpec, spec, false, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
containers = append(containers, ctr)
|
||||||
}
|
}
|
||||||
|
|
||||||
specgenOpts := kube.CtrSpecGenOptions{
|
|
||||||
Container: container,
|
|
||||||
Image: pulledImage,
|
|
||||||
Volumes: volumes,
|
|
||||||
PodID: pod.ID(),
|
|
||||||
PodName: podName,
|
|
||||||
PodInfraID: podInfraID,
|
|
||||||
ConfigMaps: configMaps,
|
|
||||||
SeccompPaths: seccompPaths,
|
|
||||||
RestartPolicy: ctrRestartPolicy,
|
|
||||||
NetNSIsHost: p.NetNS.IsHost(),
|
|
||||||
SecretsManager: secretsManager,
|
|
||||||
LogDriver: options.LogDriver,
|
|
||||||
Labels: labels,
|
|
||||||
}
|
|
||||||
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr, err := generate.MakeContainer(ctx, ic.Libpod, specGen)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
containers = append(containers, ctr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.Start != types.OptionalBoolFalse {
|
if options.Start != types.OptionalBoolFalse {
|
||||||
|
@ -383,6 +416,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||||
}
|
}
|
||||||
for id, err := range podStartErrors {
|
for id, err := range podStartErrors {
|
||||||
playKubePod.ContainerErrors = append(playKubePod.ContainerErrors, errors.Wrapf(err, "error starting container %s", id).Error())
|
playKubePod.ContainerErrors = append(playKubePod.ContainerErrors, errors.Wrapf(err, "error starting container %s", id).Error())
|
||||||
|
fmt.Println(playKubePod.ContainerErrors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,3 +690,21 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, path string, _ enti
|
||||||
}
|
}
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pullImage is a helper function to set up the proper pull options and pull the image for certain containers
|
||||||
|
func pullImage(ic *ContainerEngine, writer io.Writer, imagePull string, options entities.PlayKubeOptions, pullPolicy config.PullPolicy) ([]*libimage.Image, error) {
|
||||||
|
// This ensures the image is the image store
|
||||||
|
pullOptions := &libimage.PullOptions{}
|
||||||
|
pullOptions.AuthFilePath = options.Authfile
|
||||||
|
pullOptions.CertDirPath = options.CertDir
|
||||||
|
pullOptions.SignaturePolicyPath = options.SignaturePolicy
|
||||||
|
pullOptions.Writer = writer
|
||||||
|
pullOptions.Username = options.Username
|
||||||
|
pullOptions.Password = options.Password
|
||||||
|
pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
|
||||||
|
pulledImages, err := ic.Libpod.LibimageRuntime().Pull(context.Background(), imagePull, pullPolicy, pullOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return pulledImages, nil
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
dfilters "github.com/containers/podman/v3/pkg/domain/filters"
|
dfilters "github.com/containers/podman/v3/pkg/domain/filters"
|
||||||
"github.com/containers/podman/v3/pkg/signal"
|
"github.com/containers/podman/v3/pkg/signal"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
|
||||||
"github.com/containers/podman/v3/pkg/specgen/generate"
|
"github.com/containers/podman/v3/pkg/specgen/generate"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -248,12 +247,8 @@ func (ic *ContainerEngine) prunePodHelper(ctx context.Context) ([]*entities.PodP
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
|
func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec) (*entities.PodCreateReport, error) {
|
||||||
podSpec := specgen.NewPodSpecGenerator()
|
pod, err := generate.MakePod(&specg, ic.Libpod)
|
||||||
if err := opts.ToPodSpecGen(podSpec); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pod, err := generate.MakePod(podSpec, ic.Libpod)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/containers/podman/v3/libpod/events"
|
"github.com/containers/podman/v3/libpod/events"
|
||||||
"github.com/containers/podman/v3/pkg/bindings/system"
|
"github.com/containers/podman/v3/pkg/bindings/system"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/pkg/bindings/pods"
|
"github.com/containers/podman/v3/pkg/bindings/pods"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities"
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -179,10 +178,8 @@ func (ic *ContainerEngine) PodPrune(ctx context.Context, opts entities.PodPruneO
|
||||||
return pods.Prune(ic.ClientCtx, nil)
|
return pods.Prune(ic.ClientCtx, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) PodCreate(ctx context.Context, opts entities.PodCreateOptions) (*entities.PodCreateReport, error) {
|
func (ic *ContainerEngine) PodCreate(ctx context.Context, specg entities.PodSpec) (*entities.PodCreateReport, error) {
|
||||||
podSpec := specgen.NewPodSpecGenerator()
|
return pods.CreatePodFromSpec(ic.ClientCtx, &specg)
|
||||||
opts.ToPodSpecGen(podSpec)
|
|
||||||
return pods.CreatePodFromSpec(ic.ClientCtx, podSpec, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) PodTop(ctx context.Context, opts entities.PodTopOptions) (*entities.StringSliceReport, error) {
|
func (ic *ContainerEngine) PodTop(ctx context.Context, opts entities.PodTopOptions) (*entities.StringSliceReport, error) {
|
||||||
|
|
|
@ -22,10 +22,10 @@ import (
|
||||||
// MakeContainer creates a container based on the SpecGenerator.
|
// MakeContainer creates a container based on the SpecGenerator.
|
||||||
// Returns the created, container and any warnings resulting from creating the
|
// Returns the created, container and any warnings resulting from creating the
|
||||||
// container, or an error.
|
// container, or an error.
|
||||||
func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*libpod.Container, error) {
|
func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator) (*spec.Spec, *specgen.SpecGenerator, []libpod.CtrCreateOption, error) {
|
||||||
rtc, err := rt.GetConfig()
|
rtc, err := rt.GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If joining a pod, retrieve the pod for use.
|
// If joining a pod, retrieve the pod for use.
|
||||||
|
@ -33,7 +33,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||||
if s.Pod != "" {
|
if s.Pod != "" {
|
||||||
pod, 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, nil, nil, errors.Wrapf(err, "error retrieving pod %s", s.Pod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,47 +41,48 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||||
if s.PidNS.IsDefault() {
|
if s.PidNS.IsDefault() {
|
||||||
defaultNS, err := GetDefaultNamespaceMode("pid", rtc, pod)
|
defaultNS, err := GetDefaultNamespaceMode("pid", rtc, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
s.PidNS = defaultNS
|
s.PidNS = defaultNS
|
||||||
}
|
}
|
||||||
if s.IpcNS.IsDefault() {
|
if s.IpcNS.IsDefault() {
|
||||||
defaultNS, err := GetDefaultNamespaceMode("ipc", rtc, pod)
|
defaultNS, err := GetDefaultNamespaceMode("ipc", rtc, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
s.IpcNS = defaultNS
|
s.IpcNS = defaultNS
|
||||||
}
|
}
|
||||||
if s.UtsNS.IsDefault() {
|
if s.UtsNS.IsDefault() {
|
||||||
defaultNS, err := GetDefaultNamespaceMode("uts", rtc, pod)
|
defaultNS, err := GetDefaultNamespaceMode("uts", rtc, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
s.UtsNS = defaultNS
|
s.UtsNS = defaultNS
|
||||||
}
|
}
|
||||||
if s.UserNS.IsDefault() {
|
if s.UserNS.IsDefault() {
|
||||||
defaultNS, err := GetDefaultNamespaceMode("user", rtc, pod)
|
defaultNS, err := GetDefaultNamespaceMode("user", rtc, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
s.UserNS = defaultNS
|
s.UserNS = defaultNS
|
||||||
}
|
}
|
||||||
if s.NetNS.IsDefault() {
|
if s.NetNS.IsDefault() {
|
||||||
defaultNS, err := GetDefaultNamespaceMode("net", rtc, pod)
|
defaultNS, err := GetDefaultNamespaceMode("net", rtc, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
s.NetNS = defaultNS
|
s.NetNS = defaultNS
|
||||||
}
|
}
|
||||||
if s.CgroupNS.IsDefault() {
|
if s.CgroupNS.IsDefault() {
|
||||||
defaultNS, err := GetDefaultNamespaceMode("cgroup", rtc, pod)
|
defaultNS, err := GetDefaultNamespaceMode("cgroup", rtc, pod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
s.CgroupNS = defaultNS
|
s.CgroupNS = defaultNS
|
||||||
}
|
}
|
||||||
|
|
||||||
options := []libpod.CtrCreateOption{}
|
options := []libpod.CtrCreateOption{}
|
||||||
|
|
||||||
if s.ContainerCreateCommand != nil {
|
if s.ContainerCreateCommand != nil {
|
||||||
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
|
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
|
||||||
}
|
}
|
||||||
|
@ -94,12 +95,11 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||||
var resolvedImageName string
|
var resolvedImageName string
|
||||||
newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
|
newImage, resolvedImageName, err = rt.LibimageRuntime().LookupImage(s.Image, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
imageData, err = newImage.Inspect(ctx, false)
|
imageData, err = newImage.Inspect(ctx, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// If the input name changed, we could properly resolve the
|
// If the input name changed, we could properly resolve the
|
||||||
// image. Otherwise, it must have been an ID where we're
|
// image. Otherwise, it must have been an ID where we're
|
||||||
|
@ -115,29 +115,32 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||||
options = append(options, libpod.WithRootFSFromImage(newImage.ID(), resolvedImageName, s.RawImageName))
|
options = append(options, libpod.WithRootFSFromImage(newImage.ID(), resolvedImageName, s.RawImageName))
|
||||||
}
|
}
|
||||||
if err := s.Validate(); err != nil {
|
if err := s.Validate(); err != nil {
|
||||||
return nil, errors.Wrap(err, "invalid config provided")
|
return nil, nil, nil, errors.Wrap(err, "invalid config provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
finalMounts, finalVolumes, finalOverlays, err := finalizeMounts(ctx, s, rt, rtc, newImage)
|
finalMounts, finalVolumes, finalOverlays, err := finalizeMounts(ctx, s, rt, rtc, newImage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
command, err := makeCommand(ctx, s, imageData, rtc)
|
command, err := makeCommand(ctx, s, imageData, rtc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, finalOverlays, imageData, command)
|
opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, finalOverlays, imageData, command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
options = append(options, opts...)
|
options = append(options, opts...)
|
||||||
|
|
||||||
exitCommandArgs, err := CreateExitCommandArgs(rt.StorageConfig(), rtc, logrus.IsLevelEnabled(logrus.DebugLevel), s.Remove, false)
|
var exitCommandArgs []string
|
||||||
|
|
||||||
|
exitCommandArgs, err = CreateExitCommandArgs(rt.StorageConfig(), rtc, logrus.IsLevelEnabled(logrus.DebugLevel), s.Remove, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
options = append(options, libpod.WithExitCommand(exitCommandArgs))
|
options = append(options, libpod.WithExitCommand(exitCommandArgs))
|
||||||
|
|
||||||
if len(s.Aliases) > 0 {
|
if len(s.Aliases) > 0 {
|
||||||
|
@ -147,23 +150,26 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||||
if containerType := s.InitContainerType; len(containerType) > 0 {
|
if containerType := s.InitContainerType; len(containerType) > 0 {
|
||||||
options = append(options, libpod.WithInitCtrType(containerType))
|
options = append(options, libpod.WithInitCtrType(containerType))
|
||||||
}
|
}
|
||||||
|
if len(s.Name) > 0 {
|
||||||
|
logrus.Debugf("setting container name %s", s.Name)
|
||||||
|
options = append(options, libpod.WithName(s.Name))
|
||||||
|
}
|
||||||
if len(s.Devices) > 0 {
|
if len(s.Devices) > 0 {
|
||||||
opts = extractCDIDevices(s)
|
opts = extractCDIDevices(s)
|
||||||
options = append(options, opts...)
|
options = append(options, opts...)
|
||||||
}
|
}
|
||||||
runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command)
|
runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
return runtimeSpec, s, options, err
|
||||||
ctr, err := rt.NewContainer(ctx, runtimeSpec, options...)
|
}
|
||||||
|
func ExecuteCreate(ctx context.Context, rt *libpod.Runtime, runtimeSpec *spec.Spec, s *specgen.SpecGenerator, infra bool, options ...libpod.CtrCreateOption) (*libpod.Container, error) {
|
||||||
|
ctr, err := rt.NewContainer(ctx, runtimeSpec, s, infra, options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctr, err
|
return ctr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the content from the underlying image into the newly created
|
|
||||||
// volume if configured to do so.
|
|
||||||
return ctr, rt.PrepareVolumeOnCreateContainer(ctx, ctr)
|
return ctr, rt.PrepareVolumeOnCreateContainer(ctx, ctr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,11 +262,6 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
|
||||||
if len(s.SdNotifyMode) > 0 {
|
if len(s.SdNotifyMode) > 0 {
|
||||||
options = append(options, libpod.WithSdNotifyMode(s.SdNotifyMode))
|
options = append(options, libpod.WithSdNotifyMode(s.SdNotifyMode))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(s.Name) > 0 {
|
|
||||||
logrus.Debugf("setting container name %s", s.Name)
|
|
||||||
options = append(options, libpod.WithName(s.Name))
|
|
||||||
}
|
|
||||||
if pod != nil {
|
if pod != nil {
|
||||||
logrus.Debugf("adding container to pod %s", pod.Name())
|
logrus.Debugf("adding container to pod %s", pod.Name())
|
||||||
options = append(options, rt.WithPod(pod))
|
options = append(options, rt.WithPod(pod))
|
||||||
|
@ -379,11 +380,11 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
|
||||||
options = append(options, libpod.WithPrivileged(s.Privileged))
|
options = append(options, libpod.WithPrivileged(s.Privileged))
|
||||||
|
|
||||||
// Get namespace related options
|
// Get namespace related options
|
||||||
namespaceOptions, err := namespaceOptions(ctx, s, rt, pod, imageData)
|
namespaceOpts, err := namespaceOptions(ctx, s, rt, pod, imageData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
options = append(options, namespaceOptions...)
|
options = append(options, namespaceOpts...)
|
||||||
|
|
||||||
if len(s.ConmonPidFile) > 0 {
|
if len(s.ConmonPidFile) > 0 {
|
||||||
options = append(options, libpod.WithConmonPidFile(s.ConmonPidFile))
|
options = append(options, libpod.WithConmonPidFile(s.ConmonPidFile))
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/containers/image/v5/manifest"
|
"github.com/containers/image/v5/manifest"
|
||||||
"github.com/containers/podman/v3/libpod/network/types"
|
"github.com/containers/podman/v3/libpod/network/types"
|
||||||
ann "github.com/containers/podman/v3/pkg/annotations"
|
ann "github.com/containers/podman/v3/pkg/annotations"
|
||||||
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
"github.com/containers/podman/v3/pkg/specgen/generate"
|
"github.com/containers/podman/v3/pkg/specgen/generate"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
|
@ -23,25 +24,26 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec) (*specgen.PodSpecGenerator, error) {
|
func ToPodOpt(ctx context.Context, podName string, p entities.PodCreateOptions, podYAML *v1.PodTemplateSpec) (entities.PodCreateOptions, error) {
|
||||||
p := specgen.NewPodSpecGenerator()
|
// p := specgen.NewPodSpecGenerator()
|
||||||
|
p.Net = &entities.NetOptions{}
|
||||||
p.Name = podName
|
p.Name = podName
|
||||||
p.Labels = podYAML.ObjectMeta.Labels
|
p.Labels = podYAML.ObjectMeta.Labels
|
||||||
// Kube pods must share {ipc, net, uts} by default
|
// Kube pods must share {ipc, net, uts} by default
|
||||||
p.SharedNamespaces = append(p.SharedNamespaces, "ipc")
|
p.Share = append(p.Share, "ipc")
|
||||||
p.SharedNamespaces = append(p.SharedNamespaces, "net")
|
p.Share = append(p.Share, "net")
|
||||||
p.SharedNamespaces = append(p.SharedNamespaces, "uts")
|
p.Share = append(p.Share, "uts")
|
||||||
// TODO we only configure Process namespace. We also need to account for Host{IPC,Network,PID}
|
// TODO we only configure Process namespace. We also need to account for Host{IPC,Network,PID}
|
||||||
// which is not currently possible with pod create
|
// which is not currently possible with pod create
|
||||||
if podYAML.Spec.ShareProcessNamespace != nil && *podYAML.Spec.ShareProcessNamespace {
|
if podYAML.Spec.ShareProcessNamespace != nil && *podYAML.Spec.ShareProcessNamespace {
|
||||||
p.SharedNamespaces = append(p.SharedNamespaces, "pid")
|
p.Share = append(p.Share, "pid")
|
||||||
}
|
}
|
||||||
p.Hostname = podYAML.Spec.Hostname
|
p.Hostname = podYAML.Spec.Hostname
|
||||||
if p.Hostname == "" {
|
if p.Hostname == "" {
|
||||||
p.Hostname = podName
|
p.Hostname = podName
|
||||||
}
|
}
|
||||||
if podYAML.Spec.HostNetwork {
|
if podYAML.Spec.HostNetwork {
|
||||||
p.NetNS.NSMode = specgen.Host
|
p.Net.Network = specgen.Namespace{NSMode: "host"}
|
||||||
}
|
}
|
||||||
if podYAML.Spec.HostAliases != nil {
|
if podYAML.Spec.HostAliases != nil {
|
||||||
hosts := make([]string, 0, len(podYAML.Spec.HostAliases))
|
hosts := make([]string, 0, len(podYAML.Spec.HostAliases))
|
||||||
|
@ -50,10 +52,10 @@ func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec)
|
||||||
hosts = append(hosts, host+":"+hostAlias.IP)
|
hosts = append(hosts, host+":"+hostAlias.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.HostAdd = hosts
|
p.Net.AddHosts = hosts
|
||||||
}
|
}
|
||||||
podPorts := getPodPorts(podYAML.Spec.Containers)
|
podPorts := getPodPorts(podYAML.Spec.Containers)
|
||||||
p.PortMappings = podPorts
|
p.Net.PublishPorts = podPorts
|
||||||
|
|
||||||
if dnsConfig := podYAML.Spec.DNSConfig; dnsConfig != nil {
|
if dnsConfig := podYAML.Spec.DNSConfig; dnsConfig != nil {
|
||||||
// name servers
|
// name servers
|
||||||
|
@ -62,11 +64,11 @@ func ToPodGen(ctx context.Context, podName string, podYAML *v1.PodTemplateSpec)
|
||||||
for _, server := range dnsServers {
|
for _, server := range dnsServers {
|
||||||
servers = append(servers, net.ParseIP(server))
|
servers = append(servers, net.ParseIP(server))
|
||||||
}
|
}
|
||||||
p.DNSServer = servers
|
p.Net.DNSServers = servers
|
||||||
}
|
}
|
||||||
// search domains
|
// search domains
|
||||||
if domains := dnsConfig.Searches; len(domains) > 0 {
|
if domains := dnsConfig.Searches; len(domains) > 0 {
|
||||||
p.DNSSearch = domains
|
p.Net.DNSSearch = domains
|
||||||
}
|
}
|
||||||
// dns options
|
// dns options
|
||||||
if options := dnsConfig.Options; len(options) > 0 {
|
if options := dnsConfig.Options; len(options) > 0 {
|
||||||
|
@ -110,6 +112,8 @@ type CtrSpecGenOptions struct {
|
||||||
LogDriver string
|
LogDriver string
|
||||||
// Labels define key-value pairs of metadata
|
// Labels define key-value pairs of metadata
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
|
//
|
||||||
|
IsInfra bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
|
func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
|
||||||
|
@ -216,19 +220,19 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If only the yaml.Command is specified, set it as the entrypoint and drop the image Cmd
|
// If only the yaml.Command is specified, set it as the entrypoint and drop the image Cmd
|
||||||
if len(opts.Container.Command) != 0 {
|
if !opts.IsInfra && len(opts.Container.Command) != 0 {
|
||||||
s.Entrypoint = opts.Container.Command
|
s.Entrypoint = opts.Container.Command
|
||||||
s.Command = []string{}
|
s.Command = []string{}
|
||||||
}
|
}
|
||||||
// Only override the cmd field if yaml.Args is specified
|
// Only override the cmd field if yaml.Args is specified
|
||||||
// Keep the image entrypoint, or the yaml.command if specified
|
// Keep the image entrypoint, or the yaml.command if specified
|
||||||
if len(opts.Container.Args) != 0 {
|
if !opts.IsInfra && len(opts.Container.Args) != 0 {
|
||||||
s.Command = opts.Container.Args
|
s.Command = opts.Container.Args
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME,
|
// FIXME,
|
||||||
// we are currently ignoring imageData.Config.ExposedPorts
|
// we are currently ignoring imageData.Config.ExposedPorts
|
||||||
if opts.Container.WorkingDir != "" {
|
if !opts.IsInfra && opts.Container.WorkingDir != "" {
|
||||||
s.WorkDir = opts.Container.WorkingDir
|
s.WorkDir = opts.Container.WorkingDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.
|
||||||
if s.NetNS.Value != "" {
|
if s.NetNS.Value != "" {
|
||||||
val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value)
|
val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value)
|
||||||
}
|
}
|
||||||
toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil))
|
toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, s.CNINetworks))
|
||||||
case specgen.Private:
|
case specgen.Private:
|
||||||
fallthrough
|
fallthrough
|
||||||
case specgen.Bridge:
|
case specgen.Bridge:
|
||||||
|
|
|
@ -201,7 +201,8 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
|
||||||
Options: []string{"rprivate", "nosuid", "noexec", "nodev", "rw"},
|
Options: []string{"rprivate", "nosuid", "noexec", "nodev", "rw"},
|
||||||
}
|
}
|
||||||
g.AddMount(sysMnt)
|
g.AddMount(sysMnt)
|
||||||
} else if !canMountSys {
|
}
|
||||||
|
if !canMountSys {
|
||||||
addCgroup = false
|
addCgroup = false
|
||||||
g.RemoveMount("/sys")
|
g.RemoveMount("/sys")
|
||||||
r := "ro"
|
r := "ro"
|
||||||
|
|
|
@ -2,53 +2,82 @@ package generate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/containers/common/pkg/config"
|
||||||
"github.com/containers/podman/v3/libpod"
|
"github.com/containers/podman/v3/libpod"
|
||||||
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/containers/podman/v3/pkg/rootless"
|
"github.com/containers/podman/v3/pkg/rootless"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MakePod(p *specgen.PodSpecGenerator, rt *libpod.Runtime) (*libpod.Pod, error) {
|
func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
|
||||||
if err := p.Validate(); err != nil {
|
if err := p.PodSpecGen.Validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
options, err := createPodOptions(p, rt)
|
if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil {
|
||||||
|
var err error
|
||||||
|
p.PodSpecGen.InfraContainerSpec, err = MapSpec(&p.PodSpecGen)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options, err := createPodOptions(&p.PodSpecGen, rt, p.PodSpecGen.InfraContainerSpec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return rt.NewPod(context.Background(), options...)
|
pod, err := rt.NewPod(context.Background(), p.PodSpecGen, options...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil {
|
||||||
|
p.PodSpecGen.InfraContainerSpec.ContainerCreateCommand = []string{} // we do NOT want os.Args as the command, will display the pod create cmd
|
||||||
|
if p.PodSpecGen.InfraContainerSpec.Name == "" {
|
||||||
|
p.PodSpecGen.InfraContainerSpec.Name = pod.ID()[:12] + "-infra"
|
||||||
|
}
|
||||||
|
_, err = CompleteSpec(context.Background(), rt, p.PodSpecGen.InfraContainerSpec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.PodSpecGen.InfraContainerSpec.User = "" // infraSpec user will get incorrectly assigned via the container creation process, overwrite here
|
||||||
|
rtSpec, spec, opts, err := MakeContainer(context.Background(), rt, p.PodSpecGen.InfraContainerSpec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
spec.Pod = pod.ID()
|
||||||
|
opts = append(opts, rt.WithPod(pod))
|
||||||
|
spec.CgroupParent = pod.CgroupParent()
|
||||||
|
infraCtr, err := ExecuteCreate(context.Background(), rt, rtSpec, spec, true, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pod, err = rt.AddInfra(context.Background(), pod, infraCtr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pod, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod.PodCreateOption, error) {
|
func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime, infraSpec *specgen.SpecGenerator) ([]libpod.PodCreateOption, error) {
|
||||||
var (
|
var (
|
||||||
options []libpod.PodCreateOption
|
options []libpod.PodCreateOption
|
||||||
)
|
)
|
||||||
if !p.NoInfra {
|
if !p.NoInfra { //&& infraSpec != nil {
|
||||||
options = append(options, libpod.WithInfraContainer())
|
options = append(options, libpod.WithInfraContainer())
|
||||||
nsOptions, err := GetNamespaceOptions(p.SharedNamespaces, p.NetNS.IsHost())
|
nsOptions, err := GetNamespaceOptions(p.SharedNamespaces, p.InfraContainerSpec.NetNS.IsHost())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
options = append(options, nsOptions...)
|
options = append(options, nsOptions...)
|
||||||
// Use pod user and infra userns only when --userns is not set to host
|
// Use pod user and infra userns only when --userns is not set to host
|
||||||
if !p.Userns.IsHost() {
|
if !p.InfraContainerSpec.UserNS.IsHost() && !p.InfraContainerSpec.UserNS.IsDefault() {
|
||||||
options = append(options, libpod.WithPodUser())
|
options = append(options, libpod.WithPodUser())
|
||||||
options = append(options, libpod.WithPodUserns(p.Userns))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make our exit command
|
|
||||||
storageConfig := rt.StorageConfig()
|
|
||||||
runtimeConfig, err := rt.GetConfig()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
exitCommand, err := CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), false, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "error creating infra container exit command")
|
|
||||||
}
|
|
||||||
options = append(options, libpod.WithPodInfraExitCommand(exitCommand))
|
|
||||||
}
|
}
|
||||||
if len(p.CgroupParent) > 0 {
|
if len(p.CgroupParent) > 0 {
|
||||||
options = append(options, libpod.WithPodCgroupParent(p.CgroupParent))
|
options = append(options, libpod.WithPodCgroupParent(p.CgroupParent))
|
||||||
|
@ -59,62 +88,27 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
|
||||||
if len(p.Name) > 0 {
|
if len(p.Name) > 0 {
|
||||||
options = append(options, libpod.WithPodName(p.Name))
|
options = append(options, libpod.WithPodName(p.Name))
|
||||||
}
|
}
|
||||||
if p.ResourceLimits != nil && p.ResourceLimits.CPU != nil && p.ResourceLimits.CPU.Period != nil && p.ResourceLimits.CPU.Quota != nil {
|
if p.PodCreateCommand != nil {
|
||||||
if *p.ResourceLimits.CPU.Period != 0 || *p.ResourceLimits.CPU.Quota != 0 {
|
options = append(options, libpod.WithPodCreateCommand(p.PodCreateCommand))
|
||||||
options = append(options, libpod.WithPodCPUPAQ((*p.ResourceLimits.CPU.Period), (*p.ResourceLimits.CPU.Quota)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.ResourceLimits != nil && p.ResourceLimits.CPU != nil && p.ResourceLimits.CPU.Cpus != "" {
|
|
||||||
options = append(options, libpod.WithPodCPUSetCPUs(p.ResourceLimits.CPU.Cpus))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(p.Hostname) > 0 {
|
if len(p.Hostname) > 0 {
|
||||||
options = append(options, libpod.WithPodHostname(p.Hostname))
|
options = append(options, libpod.WithPodHostname(p.Hostname))
|
||||||
}
|
}
|
||||||
if len(p.HostAdd) > 0 {
|
|
||||||
options = append(options, libpod.WithPodHosts(p.HostAdd))
|
return options, nil
|
||||||
}
|
}
|
||||||
if len(p.DNSServer) > 0 {
|
|
||||||
var dnsServers []string
|
// MapSpec modifies the already filled Infra specgenerator,
|
||||||
for _, d := range p.DNSServer {
|
// replacing necessary values with those specified in pod creation
|
||||||
dnsServers = append(dnsServers, d.String())
|
func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) {
|
||||||
|
if len(p.PortMappings) > 0 {
|
||||||
|
ports, _, _, err := ParsePortMapping(p.PortMappings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
options = append(options, libpod.WithPodDNS(dnsServers))
|
p.InfraContainerSpec.PortMappings = libpod.WithInfraContainerPorts(ports, p.InfraContainerSpec)
|
||||||
}
|
}
|
||||||
if len(p.DNSOption) > 0 {
|
|
||||||
options = append(options, libpod.WithPodDNSOption(p.DNSOption))
|
|
||||||
}
|
|
||||||
if len(p.DNSSearch) > 0 {
|
|
||||||
options = append(options, libpod.WithPodDNSSearch(p.DNSSearch))
|
|
||||||
}
|
|
||||||
if p.StaticIP != nil {
|
|
||||||
options = append(options, libpod.WithPodStaticIP(*p.StaticIP))
|
|
||||||
}
|
|
||||||
if p.StaticMAC != nil {
|
|
||||||
options = append(options, libpod.WithPodStaticMAC(*p.StaticMAC))
|
|
||||||
}
|
|
||||||
if p.NoManageResolvConf {
|
|
||||||
options = append(options, libpod.WithPodUseImageResolvConf())
|
|
||||||
}
|
|
||||||
if len(p.CNINetworks) > 0 {
|
|
||||||
options = append(options, libpod.WithPodNetworks(p.CNINetworks))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.InfraImage) > 0 {
|
|
||||||
options = append(options, libpod.WithInfraImage(p.InfraImage))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.InfraName) > 0 {
|
|
||||||
options = append(options, libpod.WithInfraName(p.InfraName))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.InfraCommand) > 0 {
|
|
||||||
options = append(options, libpod.WithInfraCommand(p.InfraCommand))
|
|
||||||
}
|
|
||||||
|
|
||||||
if !p.Pid.IsDefault() {
|
|
||||||
options = append(options, libpod.WithPodPidNS(p.Pid))
|
|
||||||
}
|
|
||||||
|
|
||||||
switch p.NetNS.NSMode {
|
switch p.NetNS.NSMode {
|
||||||
case specgen.Default, "":
|
case specgen.Default, "":
|
||||||
if p.NoInfra {
|
if p.NoInfra {
|
||||||
|
@ -123,42 +117,88 @@ func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod
|
||||||
}
|
}
|
||||||
if rootless.IsRootless() {
|
if rootless.IsRootless() {
|
||||||
logrus.Debugf("Pod will use slirp4netns")
|
logrus.Debugf("Pod will use slirp4netns")
|
||||||
options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
|
if p.InfraContainerSpec.NetNS.NSMode != "host" {
|
||||||
|
p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode = specgen.NamespaceMode("slirp4netns")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logrus.Debugf("Pod using bridge network mode")
|
logrus.Debugf("Pod using bridge network mode")
|
||||||
}
|
}
|
||||||
case specgen.Bridge:
|
case specgen.Bridge:
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode = specgen.Bridge
|
||||||
logrus.Debugf("Pod using bridge network mode")
|
logrus.Debugf("Pod using bridge network mode")
|
||||||
case specgen.Host:
|
case specgen.Host:
|
||||||
logrus.Debugf("Pod will use host networking")
|
logrus.Debugf("Pod will use host networking")
|
||||||
options = append(options, libpod.WithPodHostNetwork())
|
if len(p.InfraContainerSpec.PortMappings) > 0 ||
|
||||||
|
p.InfraContainerSpec.StaticIP != nil ||
|
||||||
|
p.InfraContainerSpec.StaticMAC != nil ||
|
||||||
|
len(p.InfraContainerSpec.CNINetworks) > 0 ||
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode == specgen.NoNetwork {
|
||||||
|
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified")
|
||||||
|
}
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode = specgen.Host
|
||||||
case specgen.Slirp:
|
case specgen.Slirp:
|
||||||
logrus.Debugf("Pod will use slirp4netns")
|
logrus.Debugf("Pod will use slirp4netns")
|
||||||
options = append(options, libpod.WithPodSlirp4netns(p.NetworkOptions))
|
if p.InfraContainerSpec.NetNS.NSMode != "host" {
|
||||||
|
p.InfraContainerSpec.NetworkOptions = p.NetworkOptions
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode = specgen.NamespaceMode("slirp4netns")
|
||||||
|
}
|
||||||
case specgen.NoNetwork:
|
case specgen.NoNetwork:
|
||||||
logrus.Debugf("Pod will not use networking")
|
logrus.Debugf("Pod will not use networking")
|
||||||
options = append(options, libpod.WithPodNoNetwork())
|
if len(p.InfraContainerSpec.PortMappings) > 0 ||
|
||||||
|
p.InfraContainerSpec.StaticIP != nil ||
|
||||||
|
p.InfraContainerSpec.StaticMAC != nil ||
|
||||||
|
len(p.InfraContainerSpec.CNINetworks) > 0 ||
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode == "host" {
|
||||||
|
return nil, errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified")
|
||||||
|
}
|
||||||
|
p.InfraContainerSpec.NetNS.NSMode = specgen.NoNetwork
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
|
return nil, errors.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.NoManageHosts {
|
libpod.WithPodCgroups()
|
||||||
options = append(options, libpod.WithPodUseImageHosts())
|
if len(p.InfraCommand) > 0 {
|
||||||
}
|
p.InfraContainerSpec.Entrypoint = p.InfraCommand
|
||||||
if len(p.PortMappings) > 0 {
|
|
||||||
ports, _, _, err := ParsePortMapping(p.PortMappings)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
options = append(options, libpod.WithInfraContainerPorts(ports))
|
|
||||||
}
|
|
||||||
options = append(options, libpod.WithPodCgroups())
|
|
||||||
if p.PodCreateCommand != nil {
|
|
||||||
options = append(options, libpod.WithPodCreateCommand(p.PodCreateCommand))
|
|
||||||
}
|
|
||||||
if len(p.InfraConmonPidFile) > 0 {
|
|
||||||
options = append(options, libpod.WithInfraConmonPidFile(p.InfraConmonPidFile))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return options, nil
|
if len(p.HostAdd) > 0 {
|
||||||
|
p.InfraContainerSpec.HostAdd = p.HostAdd
|
||||||
|
}
|
||||||
|
if len(p.DNSServer) > 0 {
|
||||||
|
var dnsServers []net.IP
|
||||||
|
dnsServers = append(dnsServers, p.DNSServer...)
|
||||||
|
|
||||||
|
p.InfraContainerSpec.DNSServers = dnsServers
|
||||||
|
}
|
||||||
|
if len(p.DNSOption) > 0 {
|
||||||
|
p.InfraContainerSpec.DNSOptions = p.DNSOption
|
||||||
|
}
|
||||||
|
if len(p.DNSSearch) > 0 {
|
||||||
|
p.InfraContainerSpec.DNSSearch = p.DNSSearch
|
||||||
|
}
|
||||||
|
if p.StaticIP != nil {
|
||||||
|
p.InfraContainerSpec.StaticIP = p.StaticIP
|
||||||
|
}
|
||||||
|
if p.StaticMAC != nil {
|
||||||
|
p.InfraContainerSpec.StaticMAC = p.StaticMAC
|
||||||
|
}
|
||||||
|
if p.NoManageResolvConf {
|
||||||
|
p.InfraContainerSpec.UseImageResolvConf = true
|
||||||
|
}
|
||||||
|
if len(p.CNINetworks) > 0 {
|
||||||
|
p.InfraContainerSpec.CNINetworks = p.CNINetworks
|
||||||
|
}
|
||||||
|
if p.NoManageHosts {
|
||||||
|
p.InfraContainerSpec.UseImageHosts = p.NoManageHosts
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(p.InfraConmonPidFile) > 0 {
|
||||||
|
p.InfraContainerSpec.ConmonPidFile = p.InfraConmonPidFile
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.InfraImage != config.DefaultInfraImage {
|
||||||
|
p.InfraContainerSpec.Image = p.InfraImage
|
||||||
|
}
|
||||||
|
return p.InfraContainerSpec, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ type PodBasicConfig struct {
|
||||||
// Pid sets the process id namespace of the pod
|
// Pid sets the process id namespace of the pod
|
||||||
// Optional (defaults to private if unset). This sets the PID namespace of the infra container
|
// Optional (defaults to private if unset). This sets the PID namespace of the infra container
|
||||||
// This configuration will then be shared with the entire pod if PID namespace sharing is enabled via --share
|
// This configuration will then be shared with the entire pod if PID namespace sharing is enabled via --share
|
||||||
Pid Namespace `json:"pid,omitempty:"`
|
Pid Namespace `json:"pidns,omitempty"`
|
||||||
// Userns is used to indicate which kind of Usernamespace to enter.
|
// Userns is used to indicate which kind of Usernamespace to enter.
|
||||||
// Any containers created within the pod will inherit the pod's userns settings.
|
// Any containers created within the pod will inherit the pod's userns settings.
|
||||||
// Optional
|
// Optional
|
||||||
|
@ -173,6 +173,7 @@ type PodSpecGenerator struct {
|
||||||
PodNetworkConfig
|
PodNetworkConfig
|
||||||
PodCgroupConfig
|
PodCgroupConfig
|
||||||
PodResourceConfig
|
PodResourceConfig
|
||||||
|
InfraContainerSpec *SpecGenerator `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PodResourceConfig struct {
|
type PodResourceConfig struct {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package common
|
package specgenutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// validate determines if the flags and values given by the user are valid. things checked
|
// validate determines if the flags and values given by the user are valid. things checked
|
||||||
// by validate must not need any state information on the flag (i.e. changed)
|
// by validate must not need any state information on the flag (i.e. changed)
|
||||||
func (c *ContainerCLIOpts) validate() error {
|
func validate(c *entities.ContainerCreateOptions) error {
|
||||||
var ()
|
var ()
|
||||||
if c.Rm && (c.Restart != "" && c.Restart != "no" && c.Restart != "on-failure") {
|
if c.Rm && (c.Restart != "" && c.Restart != "no" && c.Restart != "on-failure") {
|
||||||
return errors.Errorf(`the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"`)
|
return errors.Errorf(`the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"`)
|
||||||
|
@ -23,7 +24,11 @@ func (c *ContainerCLIOpts) validate() error {
|
||||||
"ignore": "",
|
"ignore": "",
|
||||||
}
|
}
|
||||||
if _, ok := imageVolType[c.ImageVolume]; !ok {
|
if _, ok := imageVolType[c.ImageVolume]; !ok {
|
||||||
return errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.ImageVolume)
|
if c.IsInfra {
|
||||||
|
c.ImageVolume = "bind"
|
||||||
|
} else {
|
||||||
|
return errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.ImageVolume)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package specgenutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
|
@ -1,6 +1,7 @@
|
||||||
package common
|
package specgenutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -11,8 +12,9 @@ import (
|
||||||
"github.com/containers/podman/v3/cmd/podman/parse"
|
"github.com/containers/podman/v3/cmd/podman/parse"
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
ann "github.com/containers/podman/v3/pkg/annotations"
|
ann "github.com/containers/podman/v3/pkg/annotations"
|
||||||
|
"github.com/containers/podman/v3/pkg/domain/entities"
|
||||||
envLib "github.com/containers/podman/v3/pkg/env"
|
envLib "github.com/containers/podman/v3/pkg/env"
|
||||||
ns "github.com/containers/podman/v3/pkg/namespaces"
|
"github.com/containers/podman/v3/pkg/namespaces"
|
||||||
"github.com/containers/podman/v3/pkg/specgen"
|
"github.com/containers/podman/v3/pkg/specgen"
|
||||||
systemdDefine "github.com/containers/podman/v3/pkg/systemd/define"
|
systemdDefine "github.com/containers/podman/v3/pkg/systemd/define"
|
||||||
"github.com/containers/podman/v3/pkg/util"
|
"github.com/containers/podman/v3/pkg/util"
|
||||||
|
@ -21,7 +23,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getCPULimits(c *ContainerCLIOpts) *specs.LinuxCPU {
|
func getCPULimits(c *entities.ContainerCreateOptions) *specs.LinuxCPU {
|
||||||
cpu := &specs.LinuxCPU{}
|
cpu := &specs.LinuxCPU{}
|
||||||
hasLimits := false
|
hasLimits := false
|
||||||
|
|
||||||
|
@ -67,7 +69,7 @@ func getCPULimits(c *ContainerCLIOpts) *specs.LinuxCPU {
|
||||||
return cpu
|
return cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIOLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxBlockIO, error) {
|
func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxBlockIO, error) {
|
||||||
var err error
|
var err error
|
||||||
io := &specs.LinuxBlockIO{}
|
io := &specs.LinuxBlockIO{}
|
||||||
hasLimits := false
|
hasLimits := false
|
||||||
|
@ -122,7 +124,7 @@ func getIOLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxBlo
|
||||||
return io, nil
|
return io, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.LinuxMemory, error) {
|
func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) {
|
||||||
var err error
|
var err error
|
||||||
memory := &specs.LinuxMemory{}
|
memory := &specs.LinuxMemory{}
|
||||||
hasLimits := false
|
hasLimits := false
|
||||||
|
@ -167,7 +169,7 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.Linu
|
||||||
memory.Kernel = &mk
|
memory.Kernel = &mk
|
||||||
hasLimits = true
|
hasLimits = true
|
||||||
}
|
}
|
||||||
if c.MemorySwappiness >= 0 {
|
if c.MemorySwappiness > 0 {
|
||||||
swappiness := uint64(c.MemorySwappiness)
|
swappiness := uint64(c.MemorySwappiness)
|
||||||
memory.Swappiness = &swappiness
|
memory.Swappiness = &swappiness
|
||||||
hasLimits = true
|
hasLimits = true
|
||||||
|
@ -182,7 +184,7 @@ func getMemoryLimits(s *specgen.SpecGenerator, c *ContainerCLIOpts) (*specs.Linu
|
||||||
return memory, nil
|
return memory, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setNamespaces(s *specgen.SpecGenerator, c *ContainerCLIOpts) error {
|
func setNamespaces(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if c.PID != "" {
|
if c.PID != "" {
|
||||||
|
@ -222,18 +224,22 @@ func setNamespaces(s *specgen.SpecGenerator, c *ContainerCLIOpts) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string) error {
|
func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions, args []string) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
// validate flags as needed
|
// validate flags as needed
|
||||||
if err := c.validate(); err != nil {
|
if err := validate(c); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.User = c.User
|
s.User = c.User
|
||||||
inputCommand := args[1:]
|
var inputCommand []string
|
||||||
|
if !c.IsInfra {
|
||||||
|
if len(args) > 1 {
|
||||||
|
inputCommand = args[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.HealthCmd) > 0 {
|
if len(c.HealthCmd) > 0 {
|
||||||
if c.NoHealthCheck {
|
if c.NoHealthCheck {
|
||||||
return errors.New("Cannot specify both --no-healthcheck and --health-cmd")
|
return errors.New("Cannot specify both --no-healthcheck and --health-cmd")
|
||||||
|
@ -247,12 +253,33 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
Test: []string{"NONE"},
|
Test: []string{"NONE"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := setNamespaces(s, c); err != nil {
|
||||||
userNS := ns.UsernsMode(c.UserNS)
|
return err
|
||||||
|
}
|
||||||
|
userNS := namespaces.UsernsMode(s.UserNS.NSMode)
|
||||||
|
tempIDMap, err := util.ParseIDMapping(namespaces.UsernsMode(c.UserNS), []string{}, []string{}, "", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
s.IDMappings, err = util.ParseIDMapping(userNS, c.UIDMap, c.GIDMap, c.SubUIDName, c.SubGIDName)
|
s.IDMappings, err = util.ParseIDMapping(userNS, c.UIDMap, c.GIDMap, c.SubUIDName, c.SubGIDName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if len(s.IDMappings.GIDMap) == 0 {
|
||||||
|
s.IDMappings.AutoUserNsOpts.AdditionalGIDMappings = tempIDMap.AutoUserNsOpts.AdditionalGIDMappings
|
||||||
|
if s.UserNS.NSMode == specgen.NamespaceMode("auto") {
|
||||||
|
s.IDMappings.AutoUserNs = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(s.IDMappings.UIDMap) == 0 {
|
||||||
|
s.IDMappings.AutoUserNsOpts.AdditionalUIDMappings = tempIDMap.AutoUserNsOpts.AdditionalUIDMappings
|
||||||
|
if s.UserNS.NSMode == specgen.NamespaceMode("auto") {
|
||||||
|
s.IDMappings.AutoUserNs = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tempIDMap.AutoUserNsOpts.Size != 0 {
|
||||||
|
s.IDMappings.AutoUserNsOpts.Size = tempIDMap.AutoUserNsOpts.Size
|
||||||
|
}
|
||||||
// If some mappings are specified, assume a private user namespace
|
// If some mappings are specified, assume a private user namespace
|
||||||
if userNS.IsDefaultValue() && (!s.IDMappings.HostUIDMapping || !s.IDMappings.HostGIDMapping) {
|
if userNS.IsDefaultValue() && (!s.IDMappings.HostUIDMapping || !s.IDMappings.HostGIDMapping) {
|
||||||
s.UserNS.NSMode = specgen.Private
|
s.UserNS.NSMode = specgen.Private
|
||||||
|
@ -267,7 +294,9 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
}
|
}
|
||||||
// We are not handling the Expose flag yet.
|
// We are not handling the Expose flag yet.
|
||||||
// s.PortsExpose = c.Expose
|
// s.PortsExpose = c.Expose
|
||||||
s.PortMappings = c.Net.PublishPorts
|
if c.Net != nil {
|
||||||
|
s.PortMappings = c.Net.PublishPorts
|
||||||
|
}
|
||||||
s.PublishExposedPorts = c.PublishAll
|
s.PublishExposedPorts = c.PublishAll
|
||||||
s.Pod = c.Pod
|
s.Pod = c.Pod
|
||||||
|
|
||||||
|
@ -288,10 +317,6 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
}
|
}
|
||||||
s.Expose = expose
|
s.Expose = expose
|
||||||
|
|
||||||
if err := setNamespaces(s, c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if sig := c.StopSignal; len(sig) > 0 {
|
if sig := c.StopSignal; len(sig) > 0 {
|
||||||
stopSignal, err := util.ParseSignal(sig)
|
stopSignal, err := util.ParseSignal(sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -380,6 +405,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include the command used to create the container.
|
// Include the command used to create the container.
|
||||||
|
|
||||||
s.ContainerCreateCommand = os.Args
|
s.ContainerCreateCommand = os.Args
|
||||||
|
|
||||||
if len(inputCommand) > 0 {
|
if len(inputCommand) > 0 {
|
||||||
|
@ -394,28 +420,34 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
}
|
}
|
||||||
s.ShmSize = &shmSize
|
s.ShmSize = &shmSize
|
||||||
}
|
}
|
||||||
s.CNINetworks = c.Net.CNINetworks
|
|
||||||
|
|
||||||
// Network aliases
|
if c.Net != nil {
|
||||||
if len(c.Net.Aliases) > 0 {
|
s.CNINetworks = c.Net.CNINetworks
|
||||||
// build a map of aliases where key=cniName
|
|
||||||
aliases := make(map[string][]string, len(s.CNINetworks))
|
|
||||||
for _, cniNetwork := range s.CNINetworks {
|
|
||||||
aliases[cniNetwork] = c.Net.Aliases
|
|
||||||
}
|
|
||||||
s.Aliases = aliases
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s.HostAdd = c.Net.AddHosts
|
// Network aliases
|
||||||
s.UseImageResolvConf = c.Net.UseImageResolvConf
|
if c.Net != nil {
|
||||||
s.DNSServers = c.Net.DNSServers
|
if len(c.Net.Aliases) > 0 {
|
||||||
s.DNSSearch = c.Net.DNSSearch
|
// build a map of aliases where key=cniName
|
||||||
s.DNSOptions = c.Net.DNSOptions
|
aliases := make(map[string][]string, len(s.CNINetworks))
|
||||||
s.StaticIP = c.Net.StaticIP
|
for _, cniNetwork := range s.CNINetworks {
|
||||||
s.StaticMAC = c.Net.StaticMAC
|
aliases[cniNetwork] = c.Net.Aliases
|
||||||
s.NetworkOptions = c.Net.NetworkOptions
|
}
|
||||||
s.UseImageHosts = c.Net.NoHosts
|
s.Aliases = aliases
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Net != nil {
|
||||||
|
s.HostAdd = c.Net.AddHosts
|
||||||
|
s.UseImageResolvConf = c.Net.UseImageResolvConf
|
||||||
|
s.DNSServers = c.Net.DNSServers
|
||||||
|
s.DNSSearch = c.Net.DNSSearch
|
||||||
|
s.DNSOptions = c.Net.DNSOptions
|
||||||
|
s.StaticIP = c.Net.StaticIP
|
||||||
|
s.StaticMAC = c.Net.StaticMAC
|
||||||
|
s.NetworkOptions = c.Net.NetworkOptions
|
||||||
|
s.UseImageHosts = c.Net.NoHosts
|
||||||
|
}
|
||||||
s.ImageVolumeMode = c.ImageVolume
|
s.ImageVolumeMode = c.ImageVolume
|
||||||
if s.ImageVolumeMode == "bind" {
|
if s.ImageVolumeMode == "bind" {
|
||||||
s.ImageVolumeMode = "anonymous"
|
s.ImageVolumeMode = "anonymous"
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package specgenutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
|
@ -1,4 +1,4 @@
|
||||||
package common
|
package specgenutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -559,7 +559,7 @@ ENTRYPOINT ["sleep","99999"]
|
||||||
It("podman pod create --cpuset-cpus", func() {
|
It("podman pod create --cpuset-cpus", func() {
|
||||||
podName := "testPod"
|
podName := "testPod"
|
||||||
ctrName := "testCtr"
|
ctrName := "testCtr"
|
||||||
numCPU := float64(sysinfo.NumCPU())
|
numCPU := float64(sysinfo.NumCPU()) - 1
|
||||||
numCPUStr := strconv.Itoa(int(numCPU))
|
numCPUStr := strconv.Itoa(int(numCPU))
|
||||||
in := "0-" + numCPUStr
|
in := "0-" + numCPUStr
|
||||||
podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName})
|
podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName})
|
||||||
|
@ -588,20 +588,14 @@ ENTRYPOINT ["sleep","99999"]
|
||||||
podInspect.WaitWithDefaultTimeout()
|
podInspect.WaitWithDefaultTimeout()
|
||||||
Expect(podInspect).Should(Exit(0))
|
Expect(podInspect).Should(Exit(0))
|
||||||
podJSON := podInspect.InspectPodToJSON()
|
podJSON := podInspect.InspectPodToJSON()
|
||||||
Expect(podJSON.InfraConfig.PidNS).To(Equal("path"))
|
Expect(podJSON.InfraConfig.PidNS).To(Equal(ns))
|
||||||
|
|
||||||
podName = "pidPod2"
|
podName = "pidPod2"
|
||||||
ns = "pod"
|
ns = "pod"
|
||||||
|
|
||||||
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
|
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
|
||||||
podCreate.WaitWithDefaultTimeout()
|
podCreate.WaitWithDefaultTimeout()
|
||||||
Expect(podCreate).Should(Exit(0))
|
Expect(podCreate).Should(ExitWithError())
|
||||||
|
|
||||||
podInspect = podmanTest.Podman([]string{"pod", "inspect", podName})
|
|
||||||
podInspect.WaitWithDefaultTimeout()
|
|
||||||
Expect(podInspect).Should(Exit(0))
|
|
||||||
podJSON = podInspect.InspectPodToJSON()
|
|
||||||
Expect(podJSON.InfraConfig.PidNS).To(Equal("pod"))
|
|
||||||
|
|
||||||
podName = "pidPod3"
|
podName = "pidPod3"
|
||||||
ns = "host"
|
ns = "host"
|
||||||
|
|
Loading…
Reference in New Issue