diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/containers_create.go | 12 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_stats.go | 12 | ||||
-rw-r--r-- | pkg/api/handlers/compat/images_build.go | 2 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 22 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/manifests.go | 16 | ||||
-rw-r--r-- | pkg/bindings/containers/types.go | 3 | ||||
-rw-r--r-- | pkg/bindings/containers/types_copy_options.go | 15 | ||||
-rw-r--r-- | pkg/bindings/images/build.go | 5 | ||||
-rw-r--r-- | pkg/bindings/images/types.go | 2 | ||||
-rw-r--r-- | pkg/bindings/images/types_push_options.go | 15 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 3 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/images.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/manifest.go | 2 | ||||
-rw-r--r-- | pkg/machine/config.go | 7 | ||||
-rw-r--r-- | pkg/machine/qemu/machine.go | 9 | ||||
-rw-r--r-- | pkg/machine/qemu/options_darwin_arm64.go | 23 | ||||
-rw-r--r-- | pkg/machine/wsl/machine.go | 1 | ||||
-rw-r--r-- | pkg/specgen/generate/namespaces.go | 32 |
20 files changed, 137 insertions, 49 deletions
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index b9b7f6708..67ec52047 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -261,8 +261,13 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C } } - // netMode - nsmode, networks, netOpts, err := specgen.ParseNetworkFlag([]string{string(cc.HostConfig.NetworkMode)}) + // special case for NetworkMode, the podman default is slirp4netns for + // rootless but for better docker compat we want bridge. + netmode := string(cc.HostConfig.NetworkMode) + if netmode == "" || netmode == "default" { + netmode = "bridge" + } + nsmode, networks, netOpts, err := specgen.ParseNetworkFlag([]string{netmode}) if err != nil { return nil, nil, err } @@ -278,6 +283,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C Network: nsmode, PublishPorts: specPorts, NetworkOptions: netOpts, + NoHosts: rtc.Containers.NoHosts, } // network names @@ -438,7 +444,7 @@ func cliOpts(cc handlers.CreateContainerConfig, rtc *config.Config) (*entities.C cliOpts.Volume = append(cliOpts.Volume, vol) // Extract the destination so we don't add duplicate mounts in // the volumes phase. - splitVol := strings.SplitN(vol, ":", 3) + splitVol := specgen.SplitVolumeString(vol) switch len(splitVol) { case 1: volDestinations[vol] = true diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index 77b16b03e..6855e369b 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -44,18 +44,6 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { return } - // If the container isn't running, then let's not bother and return - // immediately. - state, err := ctnr.State() - if err != nil { - utils.InternalServerError(w, err) - return - } - if state != define.ContainerStateRunning { - utils.Error(w, http.StatusConflict, define.ErrCtrStateInvalid) - return - } - stats, err := ctnr.GetContainerStats(nil) if err != nil { utils.InternalServerError(w, errors.Wrapf(err, "failed to obtain Container %s stats", name)) diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index fe17aa1d4..7e599f4d3 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -111,6 +111,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { Memory int64 `schema:"memory"` NamespaceOptions string `schema:"nsoptions"` NoCache bool `schema:"nocache"` + OmitHistory bool `schema:"omithistory"` OSFeatures []string `schema:"osfeature"` OSVersion string `schema:"osversion"` OutputFormat string `schema:"outputformat"` @@ -595,6 +596,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { LabelOpts: labelOpts, Memory: query.Memory, MemorySwap: query.MemSwap, + OmitHistory: query.OmitHistory, SeccompProfilePath: seccomp, ShmSize: strconv.Itoa(query.ShmSize), Ulimit: ulimits, diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index efcbe9d77..60ed5feb3 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -422,10 +422,11 @@ func PushImage(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) query := struct { - Destination string `schema:"destination"` - TLSVerify bool `schema:"tlsVerify"` - Format string `schema:"format"` - All bool `schema:"all"` + All bool `schema:"all"` + Destination string `schema:"destination"` + Format string `schema:"format"` + RemoveSignatures bool `schema:"removeSignatures"` + TLSVerify bool `schema:"tlsVerify"` }{ // This is where you can override the golang default value for one of fields } @@ -462,12 +463,13 @@ func PushImage(w http.ResponseWriter, r *http.Request) { password = authconf.Password } options := entities.ImagePushOptions{ - Authfile: authfile, - Username: username, - Password: password, - Format: query.Format, - All: query.All, - Quiet: true, + All: query.All, + Authfile: authfile, + Format: query.Format, + Password: password, + Quiet: true, + RemoveSignatures: query.RemoveSignatures, + Username: username, } if _, found := r.URL.Query()["tlsVerify"]; found { options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify) diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index d9ed1c265..bdf0162c7 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -247,9 +247,10 @@ func ManifestPushV3(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) query := struct { - All bool `schema:"all"` - Destination string `schema:"destination"` - TLSVerify bool `schema:"tlsVerify"` + All bool `schema:"all"` + Destination string `schema:"destination"` + RemoveSignatures bool `schema:"removeSignatures"` + TLSVerify bool `schema:"tlsVerify"` }{ // Add defaults here once needed. } @@ -276,10 +277,11 @@ func ManifestPushV3(w http.ResponseWriter, r *http.Request) { password = authconf.Password } options := entities.ImagePushOptions{ - Authfile: authfile, - Username: username, - Password: password, - All: query.All, + All: query.All, + Authfile: authfile, + Password: password, + RemoveSignatures: query.RemoveSignatures, + Username: username, } if sys := runtime.SystemContext(); sys != nil { options.CertDir = sys.DockerCertPath diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go index 81d491bb7..f640ba756 100644 --- a/pkg/bindings/containers/types.go +++ b/pkg/bindings/containers/types.go @@ -287,4 +287,7 @@ type CopyOptions struct { Chown *bool `schema:"copyUIDGID"` // Map to translate path names. Rename map[string]string + // NoOverwriteDirNonDir when true prevents an existing directory or file from being overwritten + // by the other type. + NoOverwriteDirNonDir *bool } diff --git a/pkg/bindings/containers/types_copy_options.go b/pkg/bindings/containers/types_copy_options.go index 8fcfe71a6..e43d79752 100644 --- a/pkg/bindings/containers/types_copy_options.go +++ b/pkg/bindings/containers/types_copy_options.go @@ -46,3 +46,18 @@ func (o *CopyOptions) GetRename() map[string]string { } return o.Rename } + +// WithNoOverwriteDirNonDir set field NoOverwriteDirNonDir to given value +func (o *CopyOptions) WithNoOverwriteDirNonDir(value bool) *CopyOptions { + o.NoOverwriteDirNonDir = &value + return o +} + +// GetNoOverwriteDirNonDir returns value of field NoOverwriteDirNonDir +func (o *CopyOptions) GetNoOverwriteDirNonDir() bool { + if o.NoOverwriteDirNonDir == nil { + var z bool + return z + } + return *o.NoOverwriteDirNonDir +} diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index fe81dc662..72fed6bd5 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -170,6 +170,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO } else { params.Set("rm", "0") } + if options.CommonBuildOpts.OmitHistory { + params.Set("omithistory", "1") + } else { + params.Set("omithistory", "0") + } if len(options.From) > 0 { params.Set("from", options.From) } diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go index 8e5e7ee92..16dbad380 100644 --- a/pkg/bindings/images/types.go +++ b/pkg/bindings/images/types.go @@ -127,6 +127,8 @@ type PushOptions struct { Password *string // SkipTLSVerify to skip HTTPS and certificate verification. SkipTLSVerify *bool + // RemoveSignatures Discard any pre-existing signatures in the image. + RemoveSignatures *bool // Username for authenticating against the registry. Username *string } diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go index 4985c9451..25f6c5546 100644 --- a/pkg/bindings/images/types_push_options.go +++ b/pkg/bindings/images/types_push_options.go @@ -107,6 +107,21 @@ func (o *PushOptions) GetSkipTLSVerify() bool { return *o.SkipTLSVerify } +// WithRemoveSignatures set field RemoveSignatures to given value +func (o *PushOptions) WithRemoveSignatures(value bool) *PushOptions { + o.RemoveSignatures = &value + return o +} + +// GetRemoveSignatures returns value of field RemoveSignatures +func (o *PushOptions) GetRemoveSignatures() bool { + if o.RemoveSignatures == nil { + var z bool + return z + } + return *o.RemoveSignatures +} + // WithUsername set field Username to given value func (o *PushOptions) WithUsername(value string) *PushOptions { o.Username = &value diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 37711ca58..750f49590 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -443,6 +443,9 @@ type ContainerCpOptions struct { Pause bool // Extract the tarfile into the destination directory. Extract bool + // OverwriteDirNonDir allows for overwriting a directory with a + // non-directory and vice versa. + OverwriteDirNonDir bool } // ContainerStatsOptions describes input options for getting diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index d2fafccb1..8bd84a310 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -616,6 +616,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st ImportPrevious: options.ImportPrevious, Pod: options.Pod, PrintStats: options.PrintStats, + FileLocks: options.FileLocks, } filterFuncs := []libpod.ContainerFilter{ diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 82e8fbb5b..b68bc46d4 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -949,7 +949,7 @@ func (ic *ContainerEngine) ContainerPort(ctx context.Context, nameOrID string, o } func (ic *ContainerEngine) ContainerCopyFromArchive(ctx context.Context, nameOrID, path string, reader io.Reader, options entities.CopyOptions) (entities.ContainerCopyFunc, error) { - copyOptions := new(containers.CopyOptions).WithChown(options.Chown).WithRename(options.Rename) + copyOptions := new(containers.CopyOptions).WithChown(options.Chown).WithRename(options.Rename).WithNoOverwriteDirNonDir(options.NoOverwriteDirNonDir) return containers.CopyFromArchiveWithOptions(ic.ClientCtx, nameOrID, path, reader, copyOptions) } diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 18e10e8dd..97838d596 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -244,7 +244,7 @@ func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOpti func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, opts entities.ImagePushOptions) error { options := new(images.PushOptions) - options.WithAll(opts.All).WithCompress(opts.Compress).WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithFormat(opts.Format) + options.WithAll(opts.All).WithCompress(opts.Compress).WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithFormat(opts.Format).WithRemoveSignatures(opts.RemoveSignatures) if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined { if s == types.OptionalBoolTrue { diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go index 9ac3fdb83..09c37b896 100644 --- a/pkg/domain/infra/tunnel/manifest.go +++ b/pkg/domain/infra/tunnel/manifest.go @@ -99,7 +99,7 @@ func (ir *ImageEngine) ManifestRm(ctx context.Context, names []string) (*entitie // ManifestPush pushes a manifest list or image index to the destination func (ir *ImageEngine) ManifestPush(ctx context.Context, name, destination string, opts entities.ImagePushOptions) (string, error) { options := new(images.PushOptions) - options.WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile) + options.WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithRemoveSignatures(opts.RemoveSignatures) options.WithAll(opts.All) if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined { diff --git a/pkg/machine/config.go b/pkg/machine/config.go index abbebc9f9..fcc129338 100644 --- a/pkg/machine/config.go +++ b/pkg/machine/config.go @@ -42,7 +42,9 @@ const ( // Running indicates the qemu vm is running. Running Status = "running" // Stopped indicates the vm has stopped. - Stopped Status = "stopped" + Stopped Status = "stopped" + // Starting indicated the vm is in the process of starting + Starting Status = "starting" DefaultMachineName string = "podman-machine-default" ) @@ -62,7 +64,7 @@ var ( DefaultIgnitionUserName = "core" ErrNoSuchVM = errors.New("VM does not exist") ErrVMAlreadyExists = errors.New("VM already exists") - ErrVMAlreadyRunning = errors.New("VM already running") + ErrVMAlreadyRunning = errors.New("VM already running or starting") ErrMultipleActiveVM = errors.New("only one VM can be active at a time") ForwarderBinaryName = "gvproxy" ) @@ -88,6 +90,7 @@ type ListResponse struct { CreatedAt time.Time LastUp time.Time Running bool + Starting bool Stream string VMType string CPUs uint64 diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 0a85ff5ce..1b0d63986 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -910,7 +910,7 @@ func (v *MachineVM) State(bypass bool) (machine.Status, error) { } // Check if we can dial it if v.Starting && !bypass { - return "", nil + return machine.Starting, nil } monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address.GetPath(), v.QMPMonitor.Timeout) if err != nil { @@ -1081,8 +1081,11 @@ func getVMInfos() ([]*machine.ListResponse, error) { return err } } - if state == machine.Running { + switch state { + case machine.Running: listEntry.Running = true + case machine.Starting: + listEntry.Starting = true } listed = append(listed, listEntry) @@ -1115,7 +1118,7 @@ func (p *Provider) CheckExclusiveActiveVM() (bool, string, error) { return false, "", errors.Wrap(err, "error checking VM active") } for _, vm := range vms { - if vm.Running { + if vm.Running || vm.Starting { return true, vm.Name, nil } } diff --git a/pkg/machine/qemu/options_darwin_arm64.go b/pkg/machine/qemu/options_darwin_arm64.go index 4c954af00..d75237938 100644 --- a/pkg/machine/qemu/options_darwin_arm64.go +++ b/pkg/machine/qemu/options_darwin_arm64.go @@ -4,6 +4,8 @@ import ( "os" "os/exec" "path/filepath" + + "github.com/containers/common/pkg/config" ) var ( @@ -15,8 +17,8 @@ func (v *MachineVM) addArchOptions() []string { opts := []string{ "-accel", "hvf", "-accel", "tcg", - "-cpu", "cortex-a57", - "-M", "virt,highmem=off", + "-cpu", "host", + "-M", "virt,highmem=on", "-drive", "file=" + getEdk2CodeFd("edk2-aarch64-code.fd") + ",if=pflash,format=raw,readonly=on", "-drive", "file=" + ovmfDir + ",if=pflash,format=raw"} return opts @@ -38,6 +40,22 @@ func getOvmfDir(imagePath, vmName string) string { } /* + * When QEmu is installed in a non-default location in the system + * we can use the qemu-system-* binary path to figure the install + * location for Qemu and use it to look for edk2-code-fd + */ +func getEdk2CodeFdPathFromQemuBinaryPath() string { + cfg, err := config.Default() + if err == nil { + execPath, err := cfg.FindHelperBinary(QemuCommand, true) + if err == nil { + return filepath.Clean(filepath.Join(filepath.Dir(execPath), "..", "share", "qemu")) + } + } + return "" +} + +/* * QEmu can be installed in multiple locations on MacOS, especially on * Apple Silicon systems. A build from source will likely install it in * /usr/local/bin, whereas Homebrew package management standard is to @@ -45,6 +63,7 @@ func getOvmfDir(imagePath, vmName string) string { */ func getEdk2CodeFd(name string) string { dirs := []string{ + getEdk2CodeFdPathFromQemuBinaryPath(), "/opt/homebrew/opt/podman/libexec/share/qemu", "/usr/local/share/qemu", "/opt/homebrew/share/qemu", diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 06020aded..075f42cb2 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -1312,6 +1312,7 @@ func GetVMInfos() ([]*machine.ListResponse, error) { listEntry.RemoteUsername = vm.RemoteUsername listEntry.Port = vm.Port listEntry.IdentityPath = vm.IdentityPath + listEntry.Starting = false running := vm.isRunning() listEntry.CreatedAt, listEntry.LastUp, _ = vm.updateTimeStamps(running) diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 4735111c8..4224d16ce 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -19,6 +19,8 @@ import ( "github.com/sirupsen/logrus" ) +const host = "host" + // Get the default namespace mode for any given namespace type. func GetDefaultNamespaceMode(nsType string, cfg *config.Config, pod *libpod.Pod) (specgen.Namespace, error) { // The default for most is private @@ -33,19 +35,38 @@ func GetDefaultNamespaceMode(nsType string, cfg *config.Config, pod *libpod.Pod) podMode := false switch { case nsType == "pid" && pod.SharesPID(): + if pod.NamespaceMode(spec.PIDNamespace) == host { + toReturn.NSMode = specgen.Host + return toReturn, nil + } podMode = true case nsType == "ipc" && pod.SharesIPC(): + if pod.NamespaceMode(spec.IPCNamespace) == host { + toReturn.NSMode = specgen.Host + return toReturn, nil + } podMode = true case nsType == "uts" && pod.SharesUTS(): + if pod.NamespaceMode(spec.UTSNamespace) == host { + toReturn.NSMode = specgen.Host + return toReturn, nil + } podMode = true case nsType == "user" && pod.SharesUser(): + // user does not need a special check for host, this is already validated on pod creation + // if --userns=host then pod.SharesUser == false podMode = true case nsType == "net" && pod.SharesNet(): + if pod.NetworkMode() == host { + toReturn.NSMode = specgen.Host + return toReturn, nil + } podMode = true - case nsType == "net" && pod.NetworkMode() == "host": - toReturn.NSMode = specgen.Host - return toReturn, nil case nsType == "cgroup" && pod.SharesCgroup(): + if pod.NamespaceMode(spec.CgroupNamespace) == host { + toReturn.NSMode = specgen.Host + return toReturn, nil + } podMode = true } if podMode { @@ -491,10 +512,7 @@ func GetNamespaceOptions(ns []string, netnsIsHost bool) ([]libpod.PodCreateOptio case "cgroup": options = append(options, libpod.WithPodCgroup()) case "net": - // share the netns setting with other containers in the pod only when it is not set to host - if !netnsIsHost { - options = append(options, libpod.WithPodNet()) - } + options = append(options, libpod.WithPodNet()) case "mnt": return erroredOptions, errors.Errorf("Mount sharing functionality not supported on pod level") case "pid": |