mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-10-16 19:07:45 +00:00
Merge pull request #11792 from mheon/340_final
Backports + release notes for v3.4.0 final
This commit is contained in:
commit
d8bdbf5b66
46 changed files with 464 additions and 148 deletions
|
|
@ -18,10 +18,12 @@
|
|||
- Volumes created by `podman volume create` now support setting quotas when run atop XFS. The `size` and `inode` options allow the maximum size and maximum number of inodes consumed by a volume to be limited.
|
||||
- The `podman info` command now outputs information on what log drivers, network drivers, and volume plugins are available for use ([#11265](https://github.com/containers/podman/issues/11265)).
|
||||
- The `podman info` command now outputs the current log driver in use, and the variant and codename of the distribution in use.
|
||||
- The parameters of the VM created by `podman machine init` (amount of disk space, memory, CPUs) can now be set in `containers.conf`.
|
||||
- The `podman machine ls` command now shows additional information (CPUs, memory, disk size) about VMs managed by `podman machine`.
|
||||
- The `podman ps` command now includes healthcheck status in container state for containers that have healthchecks ([#11527](https://github.com/containers/podman/issues/11527)).
|
||||
|
||||
### Changes
|
||||
- The `podman build` command has a new alias, `podman buildx`, to improve compatibility with Docker. We have already added support for many `docker buildx` flags to `podman build` and aim to continue to do so.
|
||||
- Podman commands run as root now ignore `XDG_RUNTIME_DIR` when determining where to place temporary files, which should resolve a number of issues including [#10745](https://github.com/containers/podman/issues/10745) and [#10806](https://github.com/containers/podman/issues/10806).
|
||||
- Cases where Podman is run without a user session or a writable temporary files directory will now produce better error messages.
|
||||
- The default log driver has been changed from `file` to `journald`. The `file` driver did not properly support log rotation, so this should lead to a better experience. If journald is not available on the system, Podman will automatically revert to the `file`.
|
||||
- Podman no longer depends on `ip` for removing networks ([#11403](https://github.com/containers/podman/issues/11403)).
|
||||
|
|
@ -51,6 +53,7 @@
|
|||
- Fixed a bug where the `podman logs -f` command could hang when a container exited ([#11461](https://github.com/containers/podman/issues/11461)).
|
||||
- Fixed a bug where the `podman generate systemd` command could not be used on containers that specified a restart policy ([#11438](https://github.com/containers/podman/issues/11438)).
|
||||
- Fixed a bug where the remote Podman client's `podman build` command would fail to build containers if the UID and GID on the client were higher than 65536 ([#11474](https://github.com/containers/podman/issues/11474)).
|
||||
- Fixed a bug where the remote Podman client's `podman build` command would fail to build containers if the context directory was a symlink ([#11732](https://github.com/containers/podman/issues/11732)).
|
||||
- Fixed a bug where the `--network` flag to `podman play kube` was not properly parsed when a non-bridge network configuration was specified.
|
||||
- Fixed a bug where the `podman inspect` command could error when the container being inspected was removed as it was being inspected ([#11392](https://github.com/containers/podman/issues/11392)).
|
||||
- Fixed a bug where the `podman play kube` command ignored the default pod infra image specified in `containers.conf`.
|
||||
|
|
@ -68,6 +71,11 @@
|
|||
- Fixed a bug where the `--filter` option to `podman ps` did not properly handle filtering by healthcheck status ([#11687](https://github.com/containers/podman/issues/11687)).
|
||||
- Fixed a bug where the `podman run` and `podman start --attach` commands could race when retrieving the exit code of a container that had already been removed resulting in an error (e.g. by an external `podman rm -f`) ([#11633](https://github.com/containers/podman/issues/11633)).
|
||||
- Fixed a bug where the `podman generate kube` command would add default environment variables to generated YAML.
|
||||
- Fixed a bug where the `podman generate kube` command would add the default CMD from the image to generated YAML ([#11672](https://github.com/containers/podman/issues/11672)).
|
||||
- Fixed a bug where the `podman rm --storage` command could fail to remove containers under some circumstances ([#11207](https://github.com/containers/podman/issues/11207)).
|
||||
- Fixed a bug where the `podman machine ssh` command could fail when run on Linux ([#11731](https://github.com/containers/podman/issues/11731)).
|
||||
- Fixed a bug where the `podman stop` command would error when used on a container that was already stopped ([#11740](https://github.com/containers/podman/issues/11740)).
|
||||
- Fixed a bug where renaming a container in a pod using the `podman rename` command, then removing the pod using `podman pod rm`, could cause Podman to believe the new name of the container was permanently in use, despite the container being removed ([#11750](https://github.com/containers/podman/issues/11750)).
|
||||
|
||||
### API
|
||||
- The Libpod Pull endpoint for Images now has a new query parameter, `quiet`, which (when set to true) suppresses image pull progress reports ([#10612](https://github.com/containers/podman/issues/10612)).
|
||||
|
|
|
|||
|
|
@ -193,21 +193,14 @@ func getImages(cmd *cobra.Command, toComplete string) ([]string, cobra.ShellComp
|
|||
} else {
|
||||
// suggested "registry.fedoraproject.org/f29/httpd:latest" as
|
||||
// - "registry.fedoraproject.org/f29/httpd:latest"
|
||||
// - "registry.fedoraproject.org/f29/httpd"
|
||||
// - "f29/httpd:latest"
|
||||
// - "f29/httpd"
|
||||
// - "httpd:latest"
|
||||
// - "httpd"
|
||||
paths := strings.Split(repo, "/")
|
||||
for i := range paths {
|
||||
suggestionWithTag := strings.Join(paths[i:], "/")
|
||||
if strings.HasPrefix(suggestionWithTag, toComplete) {
|
||||
suggestions = append(suggestions, suggestionWithTag)
|
||||
}
|
||||
suggestionWithoutTag := strings.SplitN(strings.SplitN(suggestionWithTag, ":", 2)[0], "@", 2)[0]
|
||||
if strings.HasPrefix(suggestionWithoutTag, toComplete) {
|
||||
suggestions = append(suggestions, suggestionWithoutTag)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -375,6 +375,10 @@ func (l psReporter) State() string {
|
|||
|
||||
// Status is a synonym for State()
|
||||
func (l psReporter) Status() string {
|
||||
hc := l.ListContainer.Status
|
||||
if hc != "" {
|
||||
return l.State() + " (" + hc + ")"
|
||||
}
|
||||
return l.State()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ var (
|
|||
// Command: podman _generate_
|
||||
generateCmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate structured data based on containers, pods or volumes.",
|
||||
Short: "Generate structured data based on containers, pods or volumes",
|
||||
Long: "Generate structured data (e.g., Kubernetes YAML or systemd units) based on containers, pods or volumes.",
|
||||
RunE: validate.SubCommandExists,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ func prune(cmd *cobra.Command, args []string) error {
|
|||
func createPruneWarningMessage(pruneOpts entities.ImagePruneOptions) string {
|
||||
question := "Are you sure you want to continue? [y/N] "
|
||||
if pruneOpts.All {
|
||||
return "WARNING! This will remove all images without at least one container associated to them.\n" + question
|
||||
return "WARNING! This command removes all images without at least one container associated with them.\n" + question
|
||||
}
|
||||
return "WARNING! This will remove all dangling images.\n" + question
|
||||
return "WARNING! This command removes all dangling images.\n" + question
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,10 +40,13 @@ type listFlagType struct {
|
|||
}
|
||||
|
||||
type machineReporter struct {
|
||||
Name string
|
||||
Created string
|
||||
LastUp string
|
||||
VMType string
|
||||
Name string
|
||||
Created string
|
||||
LastUp string
|
||||
VMType string
|
||||
CPUs uint64
|
||||
Memory string
|
||||
DiskSize string
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -54,7 +57,7 @@ func init() {
|
|||
|
||||
flags := lsCmd.Flags()
|
||||
formatFlagName := "format"
|
||||
flags.StringVar(&listFlag.format, formatFlagName, "{{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\n", "Format volume output using Go template")
|
||||
flags.StringVar(&listFlag.format, formatFlagName, "{{.Name}}\t{{.VMType}}\t{{.Created}}\t{{.LastUp}}\t{{.CPUs}}\t{{.Memory}}\t{{.DiskSize}}\n", "Format volume output using Go template")
|
||||
_ = lsCmd.RegisterFlagCompletionFunc(formatFlagName, completion.AutocompleteNone)
|
||||
flags.BoolVar(&listFlag.noHeading, "noheading", false, "Do not print headers")
|
||||
}
|
||||
|
|
@ -85,8 +88,11 @@ func list(cmd *cobra.Command, args []string) error {
|
|||
|
||||
func outputTemplate(cmd *cobra.Command, responses []*machineReporter) error {
|
||||
headers := report.Headers(machineReporter{}, map[string]string{
|
||||
"LastUp": "LAST UP",
|
||||
"VmType": "VM TYPE",
|
||||
"LastUp": "LAST UP",
|
||||
"VmType": "VM TYPE",
|
||||
"CPUs": "CPUS",
|
||||
"Memory": "MEMORY",
|
||||
"DiskSize": "DISK SIZE",
|
||||
})
|
||||
|
||||
row := report.NormalizeFormat(listFlag.format)
|
||||
|
|
@ -136,6 +142,9 @@ func toHumanFormat(vms []*machine.ListResponse) ([]*machineReporter, error) {
|
|||
}
|
||||
response.Created = units.HumanDuration(time.Since(vm.CreatedAt)) + " ago"
|
||||
response.VMType = vm.VMType
|
||||
response.CPUs = vm.CPUs
|
||||
response.Memory = units.HumanSize(float64(vm.Memory) * units.MiB)
|
||||
response.DiskSize = units.HumanSize(float64(vm.DiskSize) * units.GiB)
|
||||
|
||||
humanResponses = append(humanResponses, response)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ var (
|
|||
// Command: podman _play_
|
||||
playCmd = &cobra.Command{
|
||||
Use: "play",
|
||||
Short: "Play containers, pods or volumes from a structured file.",
|
||||
Short: "Play containers, pods or volumes from a structured file",
|
||||
Long: "Play structured data (e.g., Kubernetes YAML) based on containers, pods or volumes.",
|
||||
RunE: validate.SubCommandExists,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,12 +89,7 @@ func newPodmanConfig() {
|
|||
// use for the containers.conf configuration file.
|
||||
func setXdgDirs() error {
|
||||
if !rootless.IsRootless() {
|
||||
// unset XDG_RUNTIME_DIR for root
|
||||
// Sometimes XDG_RUNTIME_DIR is set to /run/user/0 sometimes it is unset,
|
||||
// the inconsistency is causing issues for the dnsname plugin.
|
||||
// It is already set to an empty string for conmon so lets do the same
|
||||
// for podman. see #10806 and #10745
|
||||
return os.Unsetenv("XDG_RUNTIME_DIR")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setup XDG_RUNTIME_DIR
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ func Execute() {
|
|||
if registry.GetExitCode() == 0 {
|
||||
registry.SetExitCode(define.ExecErrorCodeGeneric)
|
||||
}
|
||||
if registry.IsRemote() {
|
||||
if strings.Contains(err.Error(), "unable to connect to Podman") {
|
||||
fmt.Fprintln(os.Stderr, "Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM")
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(os.Stderr, formatError(err))
|
||||
}
|
||||
os.Exit(registry.GetExitCode())
|
||||
|
|
|
|||
|
|
@ -113,15 +113,15 @@ func prune(cmd *cobra.Command, args []string) error {
|
|||
|
||||
func createPruneWarningMessage(pruneOpts entities.SystemPruneOptions) string {
|
||||
if pruneOpts.All {
|
||||
return `WARNING! This will remove:
|
||||
return `WARNING! This command removes:
|
||||
- all stopped containers
|
||||
- all networks not used by at least one container%s
|
||||
- all images without at least one container associated to them
|
||||
- all images without at least one container associated with them
|
||||
- all build cache
|
||||
|
||||
%s`
|
||||
}
|
||||
return `WARNING! This will remove:
|
||||
return `WARNING! This command removes:
|
||||
- all stopped containers
|
||||
- all networks not used by at least one container%s
|
||||
- all dangling images
|
||||
|
|
|
|||
|
|
@ -64,8 +64,10 @@ discarded when writing images in Docker formats.
|
|||
|
||||
#### **--arch**=*arch*
|
||||
|
||||
Set the ARCH of the image to the provided value instead of the architecture of
|
||||
the host.
|
||||
Set the architecture of the image to be built, and that of the base image to be
|
||||
pulled, if the build uses one, to the provided value instead of using the
|
||||
architecture of the build host. (Examples: arm, arm64, 386, amd64, ppc64le,
|
||||
s390x)
|
||||
|
||||
#### **--authfile**=*path*
|
||||
|
||||
|
|
@ -321,7 +323,8 @@ Pass through HTTP Proxy environment variables.
|
|||
|
||||
#### **--iidfile**=*ImageIDfile*
|
||||
|
||||
Write the image ID to the file.
|
||||
Write the built image's ID to the file. When `--platform` is specified more
|
||||
than once, attempting to use this option will trigger an error.
|
||||
|
||||
#### **--ignorefile**
|
||||
|
||||
|
|
@ -389,6 +392,7 @@ Name of the manifest list to which the image will be added. Creates the manifest
|
|||
if it does not exist. This option is useful for building multi architecture images.
|
||||
|
||||
#### **--memory**, **-m**=*LIMIT*
|
||||
|
||||
Memory limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kilobytes),
|
||||
m (megabytes), or g (gigabytes))
|
||||
|
||||
|
|
@ -430,8 +434,9 @@ with a new set of cached layers.
|
|||
|
||||
#### **--os**=*string*
|
||||
|
||||
Set the OS to the provided value instead of the current operating system of the
|
||||
host.
|
||||
Set the OS of the image to be built, and that of the base image to be pulled,
|
||||
if the build uses one, instead of using the current operating system of the
|
||||
build host.
|
||||
|
||||
#### **--pid**=*pid*
|
||||
|
||||
|
|
@ -442,11 +447,28 @@ that the PID namespace in which `podman` itself is being run should be reused,
|
|||
or it can be the path to a PID namespace which is already in use by another
|
||||
process.
|
||||
|
||||
#### **--platform**="Linux"
|
||||
#### **--platform**="OS/ARCH[/VARIANT][,...]"
|
||||
|
||||
This option has no effect on the build. Other container engines use this option
|
||||
to control the execution platform for the build (e.g., Windows, Linux) which is
|
||||
not required for Buildah as it supports only Linux.
|
||||
Set the OS/ARCH of the built image (and its base image, if your build uses one)
|
||||
to the provided value instead of using the current operating system and
|
||||
architecture of the host (for example `linux/arm`). If `--platform` is set,
|
||||
then the values of the `--arch`, `--os`, and `--variant` options will be
|
||||
overridden.
|
||||
|
||||
The `--platform` flag can be specified more than once, or given a
|
||||
comma-separated list of values as its argument. When more than one platform is
|
||||
specified, the `--manifest` option should be used instead of the `--tag`
|
||||
option.
|
||||
|
||||
OS/ARCH pairs are those used by the Go Programming Language. In several cases
|
||||
the ARCH value for a platform differs from one produced by other tools such as
|
||||
the `arch` command. Valid OS and architecture name combinations are listed as
|
||||
values for $GOOS and $GOARCH at https://golang.org/doc/install/source#environment,
|
||||
and can also be found by running `go tool dist list`.
|
||||
|
||||
While `podman build` is happy to use base images and build images for any
|
||||
platform that exists, `RUN` instructions will not be able to succeed without
|
||||
the help of emulation provided by packages like `qemu-user-static`.
|
||||
|
||||
#### **--pull**
|
||||
|
||||
|
|
@ -486,7 +508,6 @@ commands specified by the **RUN** instruction.
|
|||
Note: You can also override the default runtime by setting the BUILDAH\_RUNTIME
|
||||
environment variable. `export BUILDAH_RUNTIME=/usr/local/bin/runc`
|
||||
|
||||
|
||||
#### **--secret**=**id=id,src=path**
|
||||
|
||||
Pass secret information to be used in the Containerfile for building images
|
||||
|
|
@ -497,7 +518,6 @@ To later use the secret, use the --mount flag in a `RUN` instruction within a `C
|
|||
|
||||
`RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret`
|
||||
|
||||
|
||||
#### **--security-opt**=*option*
|
||||
|
||||
Security Options
|
||||
|
|
@ -697,7 +717,9 @@ process.
|
|||
|
||||
#### **--variant**=""
|
||||
|
||||
Set the architecture variant of the image to be pulled.
|
||||
Set the architecture variant of the image to be built, and that of the base
|
||||
image to be pulled, if the build uses one, to the provided value instead of
|
||||
using the architecture variant of the build host.
|
||||
|
||||
#### **--volume**, **-v**[=*[HOST-DIR:CONTAINER-DIR[:OPTIONS]]*]
|
||||
|
||||
|
|
@ -858,7 +880,7 @@ $ podman build --layers --force-rm -t imageName .
|
|||
$ podman build --no-cache --rm=false -t imageName .
|
||||
```
|
||||
|
||||
### Building an multi-architecture image using a --manifest option (Requires emulation software)
|
||||
### Building a multi-architecture image using the --manifest option (requires emulation software)
|
||||
|
||||
```
|
||||
$ podman build --arch arm --manifest myimage /tmp/mysrc
|
||||
|
|
@ -866,6 +888,10 @@ $ podman build --arch arm --manifest myimage /tmp/mysrc
|
|||
$ podman build --arch amd64 --manifest myimage /tmp/mysrc
|
||||
|
||||
$ podman build --arch s390x --manifest myimage /tmp/mysrc
|
||||
|
||||
$ podman build --platform linux/s390x,linux/ppc64le,linux/amd64 --manifest myimage /tmp/mysrc
|
||||
|
||||
$ podman build --platform linux/arm64 --platform linux/amd64 --manifest myimage /tmp/mysrc
|
||||
```
|
||||
|
||||
### Building an image using a URL, Git repo, or archive
|
||||
|
|
|
|||
|
|
@ -1756,6 +1756,23 @@ func (s *BoltState) SafeRewriteContainerConfig(ctr *Container, oldName, newName
|
|||
if err := allCtrsBkt.Put([]byte(ctr.ID()), []byte(newName)); err != nil {
|
||||
return errors.Wrapf(err, "error renaming container %s in all containers bucket in DB", ctr.ID())
|
||||
}
|
||||
if ctr.config.Pod != "" {
|
||||
podsBkt, err := getPodBucket(tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
podBkt := podsBkt.Bucket([]byte(ctr.config.Pod))
|
||||
if podBkt == nil {
|
||||
return errors.Wrapf(define.ErrInternal, "bucket for pod %s does not exist", ctr.config.Pod)
|
||||
}
|
||||
podCtrBkt := podBkt.Bucket(containersBkt)
|
||||
if podCtrBkt == nil {
|
||||
return errors.Wrapf(define.ErrInternal, "pod %s does not have a containers bucket", ctr.config.Pod)
|
||||
}
|
||||
if err := podCtrBkt.Put([]byte(ctr.ID()), []byte(newName)); err != nil {
|
||||
return errors.Wrapf(err, "error renaming container %s in pod %s members bucket", ctr.ID(), ctr.config.Pod)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ func (c *Container) copyToArchive(ctx context.Context, path string, writer io.Wr
|
|||
|
||||
// getContainerUser returns the specs.User and ID mappings of the container.
|
||||
func getContainerUser(container *Container, mountPoint string) (specs.User, error) {
|
||||
userspec := container.Config().User
|
||||
userspec := container.config.User
|
||||
|
||||
uid, gid, _, err := chrootuser.GetUser(mountPoint, userspec)
|
||||
u := specs.User{
|
||||
|
|
|
|||
|
|
@ -982,12 +982,11 @@ func (c *Container) checkDependenciesRunning() ([]string, error) {
|
|||
}
|
||||
|
||||
// Check the status
|
||||
conf := depCtr.Config()
|
||||
state, err := depCtr.State()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error retrieving state of dependency %s of container %s", dep, c.ID())
|
||||
}
|
||||
if state != define.ContainerStateRunning && !conf.IsInfra {
|
||||
if state != define.ContainerStateRunning && !depCtr.config.IsInfra {
|
||||
notRunning = append(notRunning, dep)
|
||||
}
|
||||
depCtrs[dep] = depCtr
|
||||
|
|
@ -1063,7 +1062,7 @@ func (c *Container) cniHosts() string {
|
|||
var hosts string
|
||||
if len(c.state.NetworkStatus) > 0 && len(c.state.NetworkStatus[0].IPs) > 0 {
|
||||
ipAddress := strings.Split(c.state.NetworkStatus[0].IPs[0].Address.String(), "/")[0]
|
||||
hosts += fmt.Sprintf("%s\t%s %s\n", ipAddress, c.Hostname(), c.Config().Name)
|
||||
hosts += fmt.Sprintf("%s\t%s %s\n", ipAddress, c.Hostname(), c.config.Name)
|
||||
}
|
||||
return hosts
|
||||
}
|
||||
|
|
@ -2127,7 +2126,7 @@ func (c *Container) canWithPrevious() error {
|
|||
// JSON files for later export
|
||||
func (c *Container) prepareCheckpointExport() error {
|
||||
// save live config
|
||||
if _, err := metadata.WriteJSONFile(c.Config(), c.bundlePath(), metadata.ConfigDumpFile); err != nil {
|
||||
if _, err := metadata.WriteJSONFile(c.config, c.bundlePath(), metadata.ConfigDumpFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ func (c *Container) resolvePath(mountPoint string, containerPath string) (string
|
|||
func findVolume(c *Container, containerPath string) (*Volume, error) {
|
||||
runtime := c.Runtime()
|
||||
cleanedContainerPath := filepath.Clean(containerPath)
|
||||
for _, vol := range c.Config().NamedVolumes {
|
||||
for _, vol := range c.config.NamedVolumes {
|
||||
if cleanedContainerPath == filepath.Clean(vol.Dest) {
|
||||
return runtime.GetVolume(vol.Name)
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ func findVolume(c *Container, containerPath string) (*Volume, error) {
|
|||
// Volume's destination.
|
||||
func isPathOnVolume(c *Container, containerPath string) bool {
|
||||
cleanedContainerPath := filepath.Clean(containerPath)
|
||||
for _, vol := range c.Config().NamedVolumes {
|
||||
for _, vol := range c.config.NamedVolumes {
|
||||
if cleanedContainerPath == filepath.Clean(vol.Dest) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ func isPathOnVolume(c *Container, containerPath string) bool {
|
|||
// path of a Mount. Returns a matching Mount or nil.
|
||||
func findBindMount(c *Container, containerPath string) *specs.Mount {
|
||||
cleanedPath := filepath.Clean(containerPath)
|
||||
for _, m := range c.Config().Spec.Mounts {
|
||||
for _, m := range c.config.Spec.Mounts {
|
||||
if m.Type != "bind" {
|
||||
continue
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ func findBindMount(c *Container, containerPath string) *specs.Mount {
|
|||
// Mount's destination.
|
||||
func isPathOnBindMount(c *Container, containerPath string) bool {
|
||||
cleanedContainerPath := filepath.Clean(containerPath)
|
||||
for _, m := range c.Config().Spec.Mounts {
|
||||
for _, m := range c.config.Spec.Mounts {
|
||||
if cleanedContainerPath == filepath.Clean(m.Destination) {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package libpod
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -27,14 +29,14 @@ import (
|
|||
|
||||
// GenerateForKube takes a slice of libpod containers and generates
|
||||
// one v1.Pod description that includes just a single container.
|
||||
func GenerateForKube(ctrs []*Container) (*v1.Pod, error) {
|
||||
func GenerateForKube(ctx context.Context, ctrs []*Container) (*v1.Pod, error) {
|
||||
// Generate the v1.Pod yaml description
|
||||
return simplePodWithV1Containers(ctrs)
|
||||
return simplePodWithV1Containers(ctx, ctrs)
|
||||
}
|
||||
|
||||
// GenerateForKube takes a slice of libpod containers and generates
|
||||
// one v1.Pod description
|
||||
func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
||||
func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, error) {
|
||||
// Generate the v1.Pod yaml description
|
||||
var (
|
||||
ports []v1.ContainerPort //nolint
|
||||
|
|
@ -78,7 +80,7 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
|||
servicePorts = containerPortsToServicePorts(ports)
|
||||
hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
|
||||
}
|
||||
pod, err := p.podWithContainers(allContainers, ports, hostNetwork)
|
||||
pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork)
|
||||
if err != nil {
|
||||
return nil, servicePorts, err
|
||||
}
|
||||
|
|
@ -88,7 +90,7 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
|||
// so set it at here
|
||||
for _, ctr := range allContainers {
|
||||
if !ctr.IsInfra() {
|
||||
switch ctr.Config().RestartPolicy {
|
||||
switch ctr.config.RestartPolicy {
|
||||
case define.RestartPolicyAlways:
|
||||
pod.Spec.RestartPolicy = v1.RestartPolicyAlways
|
||||
case define.RestartPolicyOnFailure:
|
||||
|
|
@ -218,7 +220,7 @@ func containersToServicePorts(containers []v1.Container) []v1.ServicePort {
|
|||
return sps
|
||||
}
|
||||
|
||||
func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPort, hostNetwork bool) (*v1.Pod, error) {
|
||||
func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork bool) (*v1.Pod, error) {
|
||||
deDupPodVolumes := make(map[string]*v1.Volume)
|
||||
first := true
|
||||
podContainers := make([]v1.Container, 0, len(containers))
|
||||
|
|
@ -239,7 +241,7 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
|
|||
|
||||
isInit := ctr.IsInitCtr()
|
||||
|
||||
ctr, volumes, _, err := containerToV1Container(ctr)
|
||||
ctr, volumes, _, err := containerToV1Container(ctx, ctr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -251,7 +253,9 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
|
|||
// We add the original port declarations from the libpod infra container
|
||||
// to the first kubernetes container description because otherwise we loose
|
||||
// the original container/port bindings.
|
||||
if first && len(ports) > 0 {
|
||||
// Add the port configuration to the first regular container or the first
|
||||
// init container if only init containers have been created in the pod.
|
||||
if first && len(ports) > 0 && (!isInit || len(containers) == 2) {
|
||||
ctr.Ports = ports
|
||||
first = false
|
||||
}
|
||||
|
|
@ -267,7 +271,7 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
|
|||
deDupPodVolumes[vol.Name] = &vol
|
||||
}
|
||||
} else {
|
||||
_, _, infraDNS, err := containerToV1Container(ctr)
|
||||
_, _, infraDNS, err := containerToV1Container(ctx, ctr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -337,7 +341,7 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta
|
|||
|
||||
// simplePodWithV1Containers is a function used by inspect when kube yaml needs to be generated
|
||||
// for a single container. we "insert" that container description in a pod.
|
||||
func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
|
||||
func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, error) {
|
||||
kubeCtrs := make([]v1.Container, 0, len(ctrs))
|
||||
kubeInitCtrs := []v1.Container{}
|
||||
kubeVolumes := make([]v1.Volume, 0)
|
||||
|
|
@ -355,7 +359,7 @@ func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
|
|||
if !ctr.HostNetwork() {
|
||||
hostNetwork = false
|
||||
}
|
||||
kubeCtr, kubeVols, ctrDNS, err := containerToV1Container(ctr)
|
||||
kubeCtr, kubeVols, ctrDNS, err := containerToV1Container(ctx, ctr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -411,7 +415,7 @@ func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
|
|||
|
||||
// containerToV1Container converts information we know about a libpod container
|
||||
// to a V1.Container specification.
|
||||
func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, error) {
|
||||
func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, error) {
|
||||
kubeContainer := v1.Container{}
|
||||
kubeVolumes := []v1.Volume{}
|
||||
kubeSec, err := generateKubeSecurityContext(c)
|
||||
|
|
@ -463,6 +467,17 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNS
|
|||
_, image := c.Image()
|
||||
kubeContainer.Image = image
|
||||
kubeContainer.Stdin = c.Stdin()
|
||||
img, _, err := c.runtime.libimageRuntime.LookupImage(image, nil)
|
||||
if err != nil {
|
||||
return kubeContainer, kubeVolumes, nil, err
|
||||
}
|
||||
imgData, err := img.Inspect(ctx, false)
|
||||
if err != nil {
|
||||
return kubeContainer, kubeVolumes, nil, err
|
||||
}
|
||||
if reflect.DeepEqual(imgData.Config.Cmd, kubeContainer.Command) {
|
||||
kubeContainer.Command = nil
|
||||
}
|
||||
|
||||
kubeContainer.WorkingDir = c.WorkingDir()
|
||||
kubeContainer.Ports = ports
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
"github.com/containernetworking/cni/pkg/version"
|
||||
"github.com/containers/podman/v3/pkg/rootless"
|
||||
)
|
||||
|
||||
type cniExec struct {
|
||||
|
|
@ -67,6 +68,17 @@ func (e *cniExec) ExecPlugin(ctx context.Context, pluginPath string, stdinData [
|
|||
c.Stdout = stdout
|
||||
c.Stderr = stderr
|
||||
|
||||
// The dnsname plugin tries to use XDG_RUNTIME_DIR to store files.
|
||||
// podman run will have XDG_RUNTIME_DIR set and thus the cni plugin can use
|
||||
// it. The problem is that XDG_RUNTIME_DIR is unset for the conmon process
|
||||
// for rootful users. This causes issues since the cleanup process is spawned
|
||||
// by conmon and thus not have XDG_RUNTIME_DIR set to same value as podman run.
|
||||
// Because of it dnsname will not find the config files and cannot correctly cleanup.
|
||||
// To fix this we should also unset XDG_RUNTIME_DIR for the cni plugins as rootful.
|
||||
if !rootless.IsRootless() {
|
||||
c.Env = append(c.Env, "XDG_RUNTIME_DIR=")
|
||||
}
|
||||
|
||||
err := c.Run()
|
||||
if err != nil {
|
||||
return nil, annotatePluginError(err, pluginPath, stdout.Bytes(), stderr.Bytes())
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
|
|||
defer errorhandling.CloseQuiet(syncR)
|
||||
defer errorhandling.CloseQuiet(syncW)
|
||||
|
||||
havePortMapping := len(ctr.Config().PortMappings) > 0
|
||||
havePortMapping := len(ctr.config.PortMappings) > 0
|
||||
logPath := filepath.Join(ctr.runtime.config.Engine.TmpDir, fmt.Sprintf("slirp4netns-%s.log", ctr.config.ID))
|
||||
|
||||
ctrNetworkSlipOpts := []string{}
|
||||
|
|
|
|||
|
|
@ -1148,7 +1148,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
|
|||
|
||||
if ctr.config.NetMode.IsSlirp4netns() || rootless.IsRootless() {
|
||||
if ctr.config.PostConfigureNetNS {
|
||||
havePortMapping := len(ctr.Config().PortMappings) > 0
|
||||
havePortMapping := len(ctr.config.PortMappings) > 0
|
||||
if havePortMapping {
|
||||
ctr.rootlessPortSyncR, ctr.rootlessPortSyncW, err = os.Pipe()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -104,8 +104,7 @@ func (p *Pod) PidMode() string {
|
|||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
conf := infra.Config()
|
||||
ctrSpec := conf.Spec
|
||||
ctrSpec := infra.config.Spec
|
||||
if ctrSpec != nil && ctrSpec.Linux != nil {
|
||||
for _, ns := range ctrSpec.Linux.Namespaces {
|
||||
if ns.Type == specs.PIDNamespace {
|
||||
|
|
@ -126,8 +125,7 @@ func (p *Pod) UserNSMode() string {
|
|||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
conf := infra.Config()
|
||||
ctrSpec := conf.Spec
|
||||
ctrSpec := infra.config.Spec
|
||||
if ctrSpec != nil && ctrSpec.Linux != nil {
|
||||
for _, ns := range ctrSpec.Linux.Namespaces {
|
||||
if ns.Type == specs.UserNamespace {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func (p *Pod) startInitContainers(ctx context.Context) error {
|
|||
}
|
||||
// If the container is a once init container, we need to remove it
|
||||
// after it runs
|
||||
if initCon.Config().InitContainerType == define.OneShotInitContainer {
|
||||
if initCon.config.InitContainerType == define.OneShotInitContainer {
|
||||
icLock := initCon.lock
|
||||
icLock.Lock()
|
||||
if err := p.runtime.removeContainer(ctx, initCon, false, false, true); err != nil {
|
||||
|
|
@ -588,37 +588,37 @@ func (p *Pod) Inspect() (*define.InspectPodData, error) {
|
|||
return nil, err
|
||||
}
|
||||
infraConfig = new(define.InspectPodInfraConfig)
|
||||
infraConfig.HostNetwork = !infra.Config().ContainerNetworkConfig.UseImageHosts
|
||||
infraConfig.StaticIP = infra.Config().ContainerNetworkConfig.StaticIP
|
||||
infraConfig.NoManageResolvConf = infra.Config().UseImageResolvConf
|
||||
infraConfig.NoManageHosts = infra.Config().UseImageHosts
|
||||
infraConfig.HostNetwork = !infra.config.ContainerNetworkConfig.UseImageHosts
|
||||
infraConfig.StaticIP = infra.config.ContainerNetworkConfig.StaticIP
|
||||
infraConfig.NoManageResolvConf = infra.config.UseImageResolvConf
|
||||
infraConfig.NoManageHosts = infra.config.UseImageHosts
|
||||
infraConfig.PidNS = p.PidMode()
|
||||
infraConfig.UserNS = p.UserNSMode()
|
||||
|
||||
if len(infra.Config().ContainerNetworkConfig.DNSServer) > 0 {
|
||||
infraConfig.DNSServer = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSServer))
|
||||
for _, entry := range infra.Config().ContainerNetworkConfig.DNSServer {
|
||||
if len(infra.config.ContainerNetworkConfig.DNSServer) > 0 {
|
||||
infraConfig.DNSServer = make([]string, 0, len(infra.config.ContainerNetworkConfig.DNSServer))
|
||||
for _, entry := range infra.config.ContainerNetworkConfig.DNSServer {
|
||||
infraConfig.DNSServer = append(infraConfig.DNSServer, entry.String())
|
||||
}
|
||||
}
|
||||
if len(infra.Config().ContainerNetworkConfig.DNSSearch) > 0 {
|
||||
infraConfig.DNSSearch = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSSearch))
|
||||
infraConfig.DNSSearch = append(infraConfig.DNSSearch, infra.Config().ContainerNetworkConfig.DNSSearch...)
|
||||
if len(infra.config.ContainerNetworkConfig.DNSSearch) > 0 {
|
||||
infraConfig.DNSSearch = make([]string, 0, len(infra.config.ContainerNetworkConfig.DNSSearch))
|
||||
infraConfig.DNSSearch = append(infraConfig.DNSSearch, infra.config.ContainerNetworkConfig.DNSSearch...)
|
||||
}
|
||||
if len(infra.Config().ContainerNetworkConfig.DNSOption) > 0 {
|
||||
infraConfig.DNSOption = make([]string, 0, len(infra.Config().ContainerNetworkConfig.DNSOption))
|
||||
infraConfig.DNSOption = append(infraConfig.DNSOption, infra.Config().ContainerNetworkConfig.DNSOption...)
|
||||
if len(infra.config.ContainerNetworkConfig.DNSOption) > 0 {
|
||||
infraConfig.DNSOption = make([]string, 0, len(infra.config.ContainerNetworkConfig.DNSOption))
|
||||
infraConfig.DNSOption = append(infraConfig.DNSOption, infra.config.ContainerNetworkConfig.DNSOption...)
|
||||
}
|
||||
if len(infra.Config().HostAdd) > 0 {
|
||||
infraConfig.HostAdd = make([]string, 0, len(infra.Config().HostAdd))
|
||||
infraConfig.HostAdd = append(infraConfig.HostAdd, infra.Config().HostAdd...)
|
||||
if len(infra.config.HostAdd) > 0 {
|
||||
infraConfig.HostAdd = make([]string, 0, len(infra.config.HostAdd))
|
||||
infraConfig.HostAdd = append(infraConfig.HostAdd, infra.config.HostAdd...)
|
||||
}
|
||||
if len(infra.Config().ContainerNetworkConfig.Networks) > 0 {
|
||||
infraConfig.Networks = make([]string, 0, len(infra.Config().ContainerNetworkConfig.Networks))
|
||||
infraConfig.Networks = append(infraConfig.Networks, infra.Config().ContainerNetworkConfig.Networks...)
|
||||
if len(infra.config.ContainerNetworkConfig.Networks) > 0 {
|
||||
infraConfig.Networks = make([]string, 0, len(infra.config.ContainerNetworkConfig.Networks))
|
||||
infraConfig.Networks = append(infraConfig.Networks, infra.config.ContainerNetworkConfig.Networks...)
|
||||
}
|
||||
infraConfig.NetworkOptions = infra.Config().ContainerNetworkConfig.NetworkOptions
|
||||
infraConfig.PortBindings = makeInspectPortBindings(infra.Config().ContainerNetworkConfig.PortMappings, nil)
|
||||
infraConfig.NetworkOptions = infra.config.ContainerNetworkConfig.NetworkOptions
|
||||
infraConfig.PortBindings = makeInspectPortBindings(infra.config.ContainerNetworkConfig.PortMappings, nil)
|
||||
}
|
||||
|
||||
inspectData := define.InspectPodData{
|
||||
|
|
|
|||
|
|
@ -106,18 +106,18 @@ func (r *Runtime) removeStorageContainer(idOrName string, force bool) error {
|
|||
logrus.Infof("Storage for container %s already removed", ctr.ID)
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "error looking up container %q mounts", idOrName)
|
||||
logrus.Warnf("Checking if container %q is mounted, attempting to delete: %v", idOrName, err)
|
||||
}
|
||||
if timesMounted > 0 {
|
||||
return errors.Wrapf(define.ErrCtrStateInvalid, "container %q is mounted and cannot be removed without using force", idOrName)
|
||||
}
|
||||
} else if _, err := r.store.Unmount(ctr.ID, true); err != nil {
|
||||
if errors.Cause(err) == storage.ErrContainerUnknown {
|
||||
if errors.Is(err, storage.ErrContainerUnknown) {
|
||||
// Container again gone, no error
|
||||
logrus.Infof("Storage for container %s already removed", ctr.ID)
|
||||
return nil
|
||||
}
|
||||
return errors.Wrapf(err, "error unmounting container %q", idOrName)
|
||||
logrus.Warnf("Unmounting container %q while attempting to delete storage: %v", idOrName, err)
|
||||
}
|
||||
|
||||
if err := r.store.DeleteContainer(ctr.ID); err != nil {
|
||||
|
|
|
|||
|
|
@ -112,12 +112,12 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string)
|
|||
return nil, errors.Errorf("unable to create connection. %q is not a supported schema", _url.Scheme)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to create %sClient", _url.Scheme)
|
||||
return nil, errors.Wrapf(err, "unable to connect to Podman. failed to create %sClient", _url.Scheme)
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, clientKey, &connection)
|
||||
if err := pingNewConnection(ctx); err != nil {
|
||||
return nil, errors.Wrap(err, "cannot connect to the Podman socket, please verify the connection to the Linux system, or use `podman machine` to create/start a Linux VM.")
|
||||
return nil, errors.Wrap(err, "unable to connect to Podman socket")
|
||||
}
|
||||
return ctx, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,6 +230,9 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO
|
|||
params.Add("platform", platform)
|
||||
}
|
||||
}
|
||||
if contextDir, err := filepath.EvalSymlinks(options.ContextDirectory); err == nil {
|
||||
options.ContextDirectory = contextDir
|
||||
}
|
||||
|
||||
params.Set("pullpolicy", options.PullPolicy.String())
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,10 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
|||
logrus.Debugf("Container %s is already stopped", c.ID())
|
||||
case options.All && errors.Cause(err) == define.ErrCtrStateInvalid:
|
||||
logrus.Debugf("Container %s is not running, could not stop", c.ID())
|
||||
// container never created in OCI runtime
|
||||
// docker parity: do nothing just return container id
|
||||
case errors.Cause(err) == define.ErrCtrStateInvalid:
|
||||
logrus.Debugf("Container %s is either not created on runtime or is in a invalid state", c.ID())
|
||||
default:
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
|||
|
||||
// Generate kube pods and services from pods.
|
||||
if len(pods) >= 1 {
|
||||
pos, svcs, err := getKubePods(pods, options.Service)
|
||||
pos, svcs, err := getKubePods(ctx, pods, options.Service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
|||
|
||||
// Generate the kube pods from containers.
|
||||
if len(ctrs) >= 1 {
|
||||
po, err := libpod.GenerateForKube(ctrs)
|
||||
po, err := libpod.GenerateForKube(ctx, ctrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -153,12 +153,12 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
|||
}
|
||||
|
||||
// getKubePods returns kube pod and service YAML files from podman pods.
|
||||
func getKubePods(pods []*libpod.Pod, getService bool) ([][]byte, [][]byte, error) {
|
||||
func getKubePods(ctx context.Context, pods []*libpod.Pod, getService bool) ([][]byte, [][]byte, error) {
|
||||
pos := [][]byte{}
|
||||
svcs := [][]byte{}
|
||||
|
||||
for _, p := range pods {
|
||||
po, sp, err := p.GenerateForKube()
|
||||
po, sp, err := p.GenerateForKube(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ type ListResponse struct {
|
|||
LastUp time.Time
|
||||
Running bool
|
||||
VMType string
|
||||
CPUs uint64
|
||||
Memory uint64
|
||||
DiskSize uint64
|
||||
}
|
||||
|
||||
type SSHOptions struct {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
/*
|
||||
|
|
@ -80,6 +81,7 @@ func NewIgnitionFile(ign DynamicIgnition) error {
|
|||
// so a listening host knows it can being interacting with it
|
||||
ready := `[Unit]
|
||||
Requires=dev-virtio\\x2dports-%s.device
|
||||
After=remove-moby.service
|
||||
OnFailure=emergency.target
|
||||
OnFailureJobMode=isolate
|
||||
[Service]
|
||||
|
|
@ -89,6 +91,23 @@ ExecStart=/bin/sh -c '/usr/bin/echo Ready >/dev/%s'
|
|||
[Install]
|
||||
RequiredBy=multi-user.target
|
||||
`
|
||||
deMoby := `[Unit]
|
||||
Description=Remove moby-engine
|
||||
# Run once for the machine
|
||||
After=systemd-machine-id-commit.service
|
||||
Before=zincati.service
|
||||
ConditionPathExists=!/var/lib/%N.stamp
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/rpm-ostree override remove moby-engine
|
||||
ExecStart=/usr/bin/rpm-ostree ex apply-live --allow-replacement
|
||||
ExecStartPost=/bin/touch /var/lib/%N.stamp
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
`
|
||||
_ = ready
|
||||
ignSystemd := Systemd{
|
||||
Units: []Unit{
|
||||
|
|
@ -101,6 +120,21 @@ RequiredBy=multi-user.target
|
|||
Name: "ready.service",
|
||||
Contents: strToPtr(fmt.Sprintf(ready, "vport1p1", "vport1p1")),
|
||||
},
|
||||
{
|
||||
Enabled: boolToPtr(false),
|
||||
Name: "docker.service",
|
||||
Mask: boolToPtr(true),
|
||||
},
|
||||
{
|
||||
Enabled: boolToPtr(false),
|
||||
Name: "docker.socket",
|
||||
Mask: boolToPtr(true),
|
||||
},
|
||||
{
|
||||
Enabled: boolToPtr(true),
|
||||
Name: "remove-moby.service",
|
||||
Contents: &deMoby,
|
||||
},
|
||||
}}
|
||||
ignConfig := Config{
|
||||
Ignition: ignVersion,
|
||||
|
|
@ -161,6 +195,22 @@ func getFiles(usrName string) []File {
|
|||
var (
|
||||
files []File
|
||||
)
|
||||
|
||||
lingerExample := `[Unit]
|
||||
Description=A systemd user unit demo
|
||||
After=network-online.target
|
||||
Wants=network-online.target podman.socket
|
||||
[Service]
|
||||
ExecStart=/usr/bin/sleep infinity
|
||||
`
|
||||
containers := `[containers]
|
||||
netns="bridge"
|
||||
rootless_networking="cni"
|
||||
`
|
||||
rootContainers := `[engine]
|
||||
machine_enabled=true
|
||||
`
|
||||
|
||||
// Add a fake systemd service to get the user socket rolling
|
||||
files = append(files, File{
|
||||
Node: Node{
|
||||
|
|
@ -171,7 +221,7 @@ func getFiles(usrName string) []File {
|
|||
FileEmbedded1: FileEmbedded1{
|
||||
Append: nil,
|
||||
Contents: Resource{
|
||||
Source: strToPtr("data:,%5BUnit%5D%0ADescription%3DA%20systemd%20user%20unit%20demo%0AAfter%3Dnetwork-online.target%0AWants%3Dnetwork-online.target%20podman.socket%0A%5BService%5D%0AExecStart%3D%2Fusr%2Fbin%2Fsleep%20infinity%0A"),
|
||||
Source: encodeDataURLPtr(lingerExample),
|
||||
},
|
||||
Mode: intToPtr(0744),
|
||||
},
|
||||
|
|
@ -188,7 +238,7 @@ func getFiles(usrName string) []File {
|
|||
FileEmbedded1: FileEmbedded1{
|
||||
Append: nil,
|
||||
Contents: Resource{
|
||||
Source: strToPtr("data:,%5Bcontainers%5D%0D%0Anetns%3D%22bridge%22%0D%0Arootless_networking%3D%22cni%22"),
|
||||
Source: encodeDataURLPtr(containers),
|
||||
},
|
||||
Mode: intToPtr(0744),
|
||||
},
|
||||
|
|
@ -213,7 +263,7 @@ func getFiles(usrName string) []File {
|
|||
FileEmbedded1: FileEmbedded1{
|
||||
Append: nil,
|
||||
Contents: Resource{
|
||||
Source: strToPtr("data:,%5Bengine%5D%0Amachine_enabled%3Dtrue%0A"),
|
||||
Source: encodeDataURLPtr(rootContainers),
|
||||
},
|
||||
Mode: intToPtr(0644),
|
||||
},
|
||||
|
|
@ -233,7 +283,22 @@ func getFiles(usrName string) []File {
|
|||
FileEmbedded1: FileEmbedded1{
|
||||
Append: nil,
|
||||
Contents: Resource{
|
||||
Source: strToPtr("data:,unqualified-search-registries%3D%5B%22docker.io%22%5D"),
|
||||
Source: encodeDataURLPtr("unqualified-search-registries=[\"docker.io\"]\n"),
|
||||
},
|
||||
Mode: intToPtr(0644),
|
||||
},
|
||||
})
|
||||
|
||||
files = append(files, File{
|
||||
Node: Node{
|
||||
Path: "/etc/tmpfiles.d/podman-docker.conf",
|
||||
},
|
||||
FileEmbedded1: FileEmbedded1{
|
||||
Append: nil,
|
||||
// Create a symlink from the docker socket to the podman socket.
|
||||
// Taken from https://github.com/containers/podman/blob/main/contrib/systemd/system/podman-docker.conf
|
||||
Contents: Resource{
|
||||
Source: encodeDataURLPtr("L+ /run/docker.sock - - - - /run/podman/podman.sock\n"),
|
||||
},
|
||||
Mode: intToPtr(0644),
|
||||
},
|
||||
|
|
@ -253,5 +318,20 @@ func getLinks(usrName string) []Link {
|
|||
Hard: boolToPtr(false),
|
||||
Target: "/home/" + usrName + "/.config/systemd/user/linger-example.service",
|
||||
},
|
||||
}, {
|
||||
Node: Node{
|
||||
Group: getNodeGrp("root"),
|
||||
Path: "/usr/local/bin/docker",
|
||||
Overwrite: boolToPtr(true),
|
||||
User: getNodeUsr("root"),
|
||||
},
|
||||
LinkEmbedded1: LinkEmbedded1{
|
||||
Hard: boolToPtr(false),
|
||||
Target: "/usr/bin/podman",
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
func encodeDataURLPtr(contents string) *string {
|
||||
return strToPtr(fmt.Sprintf("data:,%s", url.PathEscape(contents)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ type MachineVM struct {
|
|||
ImagePath string
|
||||
// Memory in megabytes assigned to the vm
|
||||
Memory uint64
|
||||
// Disk size in gigabytes assigned to the vm
|
||||
DiskSize uint64
|
||||
// Name of the vm
|
||||
Name string
|
||||
// SSH port for user networking
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ func NewMachine(opts machine.InitOptions) (machine.VM, error) {
|
|||
|
||||
vm.CPUs = opts.CPUS
|
||||
vm.Memory = opts.Memory
|
||||
vm.DiskSize = opts.DiskSize
|
||||
|
||||
// Look up the executable
|
||||
execPath, err := exec.LookPath(QemuCommand)
|
||||
|
|
@ -574,6 +575,9 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
|
|||
|
||||
listEntry.Name = vm.Name
|
||||
listEntry.VMType = "qemu"
|
||||
listEntry.CPUs = vm.CPUs
|
||||
listEntry.Memory = vm.Memory
|
||||
listEntry.DiskSize = vm.DiskSize
|
||||
fi, err := os.Stat(fullPath)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -241,6 +241,13 @@ func ListContainerBatch(rt *libpod.Runtime, ctr *libpod.Container, opts entities
|
|||
UTS: uts,
|
||||
}
|
||||
}
|
||||
|
||||
if hc, err := ctr.HealthCheckStatus(); err == nil {
|
||||
ps.Status = hc
|
||||
} else {
|
||||
logrus.Debug(err)
|
||||
}
|
||||
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ can_use_shortcut ()
|
|||
continue;
|
||||
|
||||
if (strcmp (argv[argc], "mount") == 0
|
||||
|| strcmp (argv[argc], "machine") == 0
|
||||
|| strcmp (argv[argc], "search") == 0
|
||||
|| (strcmp (argv[argc], "system") == 0 && argv[argc+1] && strcmp (argv[argc+1], "service") != 0))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -792,6 +792,45 @@ var _ = Describe("Podman generate kube", func() {
|
|||
Expect(containers[0].Args).To(Equal([]string{"10s"}))
|
||||
})
|
||||
|
||||
It("podman generate kube - no command", func() {
|
||||
session := podmanTest.Podman([]string{"create", "--name", "test", ALPINE})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
kube := podmanTest.Podman([]string{"generate", "kube", "test"})
|
||||
kube.WaitWithDefaultTimeout()
|
||||
Expect(kube).Should(Exit(0))
|
||||
|
||||
// Now make sure that the container's command is not set to the
|
||||
// entrypoint and it's arguments to "10s".
|
||||
pod := new(v1.Pod)
|
||||
err := yaml.Unmarshal(kube.Out.Contents(), pod)
|
||||
Expect(err).To(BeNil())
|
||||
|
||||
containers := pod.Spec.Containers
|
||||
Expect(len(containers)).To(Equal(1))
|
||||
Expect(len(containers[0].Command)).To(Equal(0))
|
||||
|
||||
cmd := []string{"echo", "hi"}
|
||||
session = podmanTest.Podman(append([]string{"create", "--name", "test1", ALPINE}, cmd...))
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session).Should(Exit(0))
|
||||
|
||||
kube = podmanTest.Podman([]string{"generate", "kube", "test1"})
|
||||
kube.WaitWithDefaultTimeout()
|
||||
Expect(kube).Should(Exit(0))
|
||||
|
||||
// Now make sure that the container's command is not set to the
|
||||
// entrypoint and it's arguments to "10s".
|
||||
pod = new(v1.Pod)
|
||||
err = yaml.Unmarshal(kube.Out.Contents(), pod)
|
||||
Expect(err).To(BeNil())
|
||||
|
||||
containers = pod.Spec.Containers
|
||||
Expect(len(containers)).To(Equal(1))
|
||||
Expect(containers[0].Command).To(Equal(cmd))
|
||||
})
|
||||
|
||||
It("podman generate kube - use entrypoint from image", func() {
|
||||
// Build an image with an entrypoint.
|
||||
containerfile := `FROM quay.io/libpod/alpine:latest
|
||||
|
|
|
|||
|
|
@ -80,6 +80,11 @@ var _ = Describe("Podman healthcheck run", func() {
|
|||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
Expect(exitCode).To(Equal(0))
|
||||
|
||||
ps := podmanTest.Podman([]string{"ps"})
|
||||
ps.WaitWithDefaultTimeout()
|
||||
Expect(ps).Should(Exit(0))
|
||||
Expect(ps.OutputToString()).To(ContainSubstring("(healthy)"))
|
||||
})
|
||||
|
||||
It("podman healthcheck that should fail", func() {
|
||||
|
|
|
|||
|
|
@ -111,4 +111,29 @@ var _ = Describe("podman rename", func() {
|
|||
Expect(ps).Should(Exit(0))
|
||||
Expect(ps.OutputToString()).To(ContainSubstring(newName))
|
||||
})
|
||||
|
||||
It("Rename a container that is part of a pod", func() {
|
||||
podName := "testPod"
|
||||
infraName := "infra1"
|
||||
pod := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--infra-name", infraName})
|
||||
pod.WaitWithDefaultTimeout()
|
||||
Expect(pod).Should(Exit(0))
|
||||
|
||||
infraName2 := "infra2"
|
||||
rename := podmanTest.Podman([]string{"rename", infraName, infraName2})
|
||||
rename.WaitWithDefaultTimeout()
|
||||
Expect(rename).Should(Exit(0))
|
||||
|
||||
remove := podmanTest.Podman([]string{"pod", "rm", "-f", podName})
|
||||
remove.WaitWithDefaultTimeout()
|
||||
Expect(remove).Should(Exit(0))
|
||||
|
||||
create := podmanTest.Podman([]string{"create", "--name", infraName2, ALPINE, "top"})
|
||||
create.WaitWithDefaultTimeout()
|
||||
Expect(create).Should(Exit(0))
|
||||
|
||||
create2 := podmanTest.Podman([]string{"create", "--name", infraName, ALPINE, "top"})
|
||||
create2.WaitWithDefaultTimeout()
|
||||
Expect(create2).Should(Exit(0))
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -234,6 +234,17 @@ var _ = Describe("Podman stop", func() {
|
|||
Expect(strings.TrimSpace(finalCtrs.OutputToString())).To(Equal(""))
|
||||
})
|
||||
|
||||
It("podman stop should return silent success on stopping configured containers", func() {
|
||||
// following container is not created on OCI runtime
|
||||
// so we return success and assume that is is stopped
|
||||
session2 := podmanTest.Podman([]string{"create", "--name", "stopctr", ALPINE, "/bin/sh"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
Expect(session2).Should(Exit(0))
|
||||
session3 := podmanTest.Podman([]string{"stop", "stopctr"})
|
||||
session3.WaitWithDefaultTimeout()
|
||||
Expect(session3).Should(Exit(0))
|
||||
})
|
||||
|
||||
It("podman stop --cidfile", func() {
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "")
|
||||
|
|
|
|||
|
|
@ -135,31 +135,38 @@ function _log_test_until() {
|
|||
s_after="after_$(random_string)_${driver}"
|
||||
|
||||
before=$(date --iso-8601=seconds)
|
||||
sleep 5
|
||||
sleep 1
|
||||
run_podman run --log-driver=$driver -d --name test $IMAGE sh -c \
|
||||
"echo $s_before; trap 'echo $s_after; exit' SIGTERM; while :; do sleep 1; done"
|
||||
|
||||
# sleep a second to make sure the date is after the first echo
|
||||
sleep 1
|
||||
run_podman stop test
|
||||
# sleep for 20 seconds to get the proper after time
|
||||
sleep 20
|
||||
run_podman wait test
|
||||
|
||||
run_podman logs test
|
||||
is "$output" \
|
||||
"$s_before
|
||||
# Sigh. Stupid journald has a lag. Wait a few seconds for it to catch up.
|
||||
retries=20
|
||||
s_both="$s_before
|
||||
$s_after"
|
||||
while [[ $retries -gt 0 ]]; do
|
||||
run_podman logs test
|
||||
if [[ "$output" = "$s_both" ]]; then
|
||||
break
|
||||
fi
|
||||
retries=$((retries - 1))
|
||||
sleep 0.1
|
||||
done
|
||||
if [[ $retries -eq 0 ]]; then
|
||||
die "Timed out waiting for before&after in podman logs: $output"
|
||||
fi
|
||||
|
||||
run_podman logs --until $before test
|
||||
is "$output" \
|
||||
""
|
||||
is "$output" "" "podman logs --until before"
|
||||
|
||||
after=$(date --iso-8601=seconds)
|
||||
after=$(date --date='+1 second' --iso-8601=seconds)
|
||||
|
||||
run_podman logs --until $after test
|
||||
is "$output" \
|
||||
"$s_before
|
||||
$s_after"
|
||||
is "$output" "$s_both" "podman logs --until after"
|
||||
run_podman rm -f test
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,10 +90,18 @@ load helpers
|
|||
is "${#lines[@]}" "1" "setup check: no storage containers at start of test"
|
||||
|
||||
# Force a buildah timeout; this leaves a buildah container behind
|
||||
local t0=$SECONDS
|
||||
PODMAN_TIMEOUT=5 run_podman 124 build -t thiswillneverexist - <<EOF
|
||||
FROM $IMAGE
|
||||
RUN sleep 30
|
||||
EOF
|
||||
local t1=$SECONDS
|
||||
local delta_t=$((t1 - t0))
|
||||
if [[ $delta_t -gt 10 ]]; then
|
||||
# FIXME FIXME FIXME: when buildah issue 3544 gets fixed and vendored,
|
||||
# change 'echo' to 'die'
|
||||
echo "podman build did not get killed within 10 seconds (actual time: $delta_t seconds)"
|
||||
fi
|
||||
|
||||
run_podman ps -a
|
||||
is "${#lines[@]}" "1" "podman ps -a does not see buildah container"
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ load helpers
|
|||
run_podman exec $cid find /image-mount/etc/
|
||||
|
||||
# Clean up
|
||||
run_podman stop -t 0 $cid
|
||||
run_podman rm -f $cid
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +148,7 @@ load helpers
|
|||
run_podman inspect --format "{{(index .Mounts 0).RW}}" $cid
|
||||
is "$output" "true" "inspect data includes image mount source"
|
||||
|
||||
run_podman stop -t 0 $cid
|
||||
run_podman rm -f $cid
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ load helpers
|
|||
"
|
||||
|
||||
# From RUNNING container
|
||||
local -a destcontainers=()
|
||||
while read id src dest dest_fullname description; do
|
||||
# dest may be "''" for empty table cells
|
||||
if [[ $dest == "''" ]];then
|
||||
|
|
@ -265,26 +266,25 @@ load helpers
|
|||
# To RUNNING container
|
||||
run_podman run -d $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman exec $destcontainer cat "/$dest_fullname"
|
||||
is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
|
||||
# To CREATED container
|
||||
run_podman create $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman start $destcontainer
|
||||
run_podman exec $destcontainer cat "/$dest_fullname"
|
||||
is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
done < <(parse_table "$tests")
|
||||
run_podman kill cpcontainer
|
||||
run_podman rm -f cpcontainer
|
||||
run_podman kill cpcontainer ${destcontainers[@]}
|
||||
run_podman rm -f cpcontainer ${destcontainers[@]}
|
||||
|
||||
# From CREATED container
|
||||
destcontainers=()
|
||||
run_podman create --name cpcontainer --workdir=/srv $cpimage
|
||||
while read id src dest dest_fullname description; do
|
||||
# dest may be "''" for empty table cells
|
||||
|
|
@ -295,23 +295,21 @@ load helpers
|
|||
# To RUNNING container
|
||||
run_podman run -d $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman exec $destcontainer cat "/$dest_fullname"
|
||||
is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
|
||||
# To CREATED container
|
||||
run_podman create $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman start $destcontainer
|
||||
run_podman exec $destcontainer cat "/$dest_fullname"
|
||||
is "$output" "${randomcontent[$id]}" "$description (cp ctr:$src to /$dest)"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
done < <(parse_table "$tests")
|
||||
run_podman rm -f cpcontainer
|
||||
run_podman kill ${destcontainers[@]}
|
||||
run_podman rm -f cpcontainer ${destcontainers[@]}
|
||||
|
||||
run_podman rmi -f $cpimage
|
||||
}
|
||||
|
|
@ -496,6 +494,7 @@ load helpers
|
|||
"
|
||||
|
||||
# From RUNNING container
|
||||
local -a destcontainers=()
|
||||
while read src dest dest_fullname description; do
|
||||
if [[ $src == "''" ]];then
|
||||
unset src
|
||||
|
|
@ -510,28 +509,27 @@ load helpers
|
|||
# To RUNNING container
|
||||
run_podman run -d $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1"
|
||||
is "$output" "${randomcontent[0]}
|
||||
${randomcontent[1]}" "$description"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
|
||||
# To CREATED container
|
||||
run_podman create $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman start $destcontainer
|
||||
run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1"
|
||||
is "$output" "${randomcontent[0]}
|
||||
${randomcontent[1]}" "$description"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
done < <(parse_table "$tests")
|
||||
run_podman kill cpcontainer
|
||||
run_podman rm -f cpcontainer
|
||||
run_podman kill cpcontainer ${destcontainers[@]}
|
||||
run_podman rm -f cpcontainer ${destcontainers[@]}
|
||||
|
||||
# From CREATED container
|
||||
destcontainers=()
|
||||
run_podman create --name cpcontainer --workdir=/srv $cpimage
|
||||
while read src dest dest_fullname description; do
|
||||
if [[ $src == "''" ]];then
|
||||
|
|
@ -547,26 +545,25 @@ ${randomcontent[1]}" "$description"
|
|||
# To RUNNING container
|
||||
run_podman run -d $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1"
|
||||
is "$output" "${randomcontent[0]}
|
||||
${randomcontent[1]}" "$description"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
|
||||
# To CREATED container
|
||||
run_podman create $IMAGE sleep infinity
|
||||
destcontainer="$output"
|
||||
destcontainers+=($destcontainer)
|
||||
run_podman start $destcontainer
|
||||
run_podman cp cpcontainer:$src $destcontainer:"/$dest"
|
||||
run_podman exec $destcontainer cat "/$dest_fullname/containerfile0" "/$dest_fullname/containerfile1"
|
||||
is "$output" "${randomcontent[0]}
|
||||
${randomcontent[1]}" "$description"
|
||||
run_podman kill $destcontainer
|
||||
run_podman rm -f $destcontainer
|
||||
done < <(parse_table "$tests")
|
||||
|
||||
run_podman rm -f cpcontainer
|
||||
run_podman kill ${destcontainers[@]}
|
||||
run_podman rm -f cpcontainer ${destcontainers[@]}
|
||||
run_podman rmi -f $cpimage
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -956,6 +956,15 @@ EOF
|
|||
run_podman build -t build_test $tmpdir
|
||||
}
|
||||
|
||||
@test "podman build build context is a symlink to a directory" {
|
||||
tmpdir=$PODMAN_TMPDIR/build-test
|
||||
mkdir -p $tmpdir/target
|
||||
ln -s target $tmpdir/link
|
||||
echo FROM $IMAGE > $tmpdir/link/Dockerfile
|
||||
echo RUN echo hello >> $tmpdir/link/Dockerfile
|
||||
run_podman build -t build_test $tmpdir/link
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
# A timeout or other error in 'build' can leave behind stale images
|
||||
# that podman can't even see and which will cascade into subsequent
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ load helpers
|
|||
# would imply that the container never paused.
|
||||
is "$max_delta" "[3456]" "delta t between paused and restarted"
|
||||
|
||||
run_podman stop -t 0 $cname
|
||||
run_podman rm -f $cname
|
||||
|
||||
# Pause/unpause on nonexistent name or id - these should all fail
|
||||
|
|
@ -73,6 +74,7 @@ load helpers
|
|||
is "$output" "$cid" "podman unpause output"
|
||||
run_podman ps --format '{{.ID}} {{.Names}} {{.Status}}'
|
||||
is "$output" "${cid:0:12} $cname Up.*" "podman ps on resumed container"
|
||||
run_podman stop -t 0 $cname
|
||||
run_podman rm -f $cname
|
||||
run_podman rm -f notrunning
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ Log[-1].Output |
|
|||
is "$output" "unhealthy" "output from 'podman healthcheck run'"
|
||||
|
||||
# Clean up
|
||||
run_podman stop -t 0 healthcheck_c
|
||||
run_podman rm -f healthcheck_c
|
||||
run_podman rmi healthcheck_i
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,26 +69,36 @@ function teardown() {
|
|||
|
||||
@test "podman system service - socket activation - no container" {
|
||||
run curl -s --max-time 3 --unix-socket $SERVICE_SOCK_ADDR http://podman/libpod/_ping
|
||||
is "$output" "OK" "podman service responses normally"
|
||||
is "$output" "OK" "podman service responds normally"
|
||||
}
|
||||
|
||||
@test "podman system service - socket activation - exist container " {
|
||||
run_podman run $IMAGE sleep 90
|
||||
@test "podman system service - socket activation - existing container" {
|
||||
run_podman run -d $IMAGE sleep 90
|
||||
cid="$output"
|
||||
|
||||
run curl -s --max-time 3 --unix-socket $SERVICE_SOCK_ADDR http://podman/libpod/_ping
|
||||
is "$output" "OK" "podman service responses normally"
|
||||
is "$output" "OK" "podman service responds normally"
|
||||
|
||||
run_podman stop -t 0 $cid
|
||||
run_podman rm -f $cid
|
||||
}
|
||||
|
||||
@test "podman system service - socket activation - kill rootless pause " {
|
||||
@test "podman system service - socket activation - kill rootless pause" {
|
||||
if ! is_rootless; then
|
||||
skip "root podman no need pause process"
|
||||
fi
|
||||
run_podman run $IMAGE sleep 90
|
||||
run_podman run -d $IMAGE sleep 90
|
||||
cid="$output"
|
||||
|
||||
local pause_pid="$XDG_RUNTIME_DIR/libpod/tmp/pause.pid"
|
||||
if [ -f $pause_pid ]; then
|
||||
kill -9 $(cat $pause_pid) 2> /dev/null
|
||||
fi
|
||||
run curl -s --max-time 3 --unix-socket $SERVICE_SOCK_ADDR http://podman/libpod/_ping
|
||||
is "$output" "OK" "podman service responses normally"
|
||||
is "$output" "OK" "podman service responds normally"
|
||||
|
||||
run_podman stop -t 0 $cid
|
||||
run_podman rm -f $cid
|
||||
}
|
||||
|
||||
# vim: filetype=sh
|
||||
|
|
|
|||
|
|
@ -110,12 +110,10 @@ function check_shell_completion() {
|
|||
is "$output" ".*localhost/$random_image_name:$random_image_tag${nl}" \
|
||||
"$* $cmd: actual image listed in suggestions"
|
||||
|
||||
# check that we complete the image with and without tag after at least one char is typed
|
||||
# check that we complete the image with tag after at least one char is typed
|
||||
run_completion "$@" $cmd "${extra_args[@]}" "${random_image_name:0:1}"
|
||||
is "$output" ".*$random_image_name:$random_image_tag${nl}" \
|
||||
"$* $cmd: image name:tag included in suggestions"
|
||||
is "$output" ".*$random_image_name${nl}" \
|
||||
"$* $cmd: image name(w/o tag) included in suggestions"
|
||||
|
||||
# check that we complete the image id after at least two chars are typed
|
||||
run_completion "$@" $cmd "${extra_args[@]}" "${random_image_id:0:2}"
|
||||
|
|
|
|||
|
|
@ -69,11 +69,15 @@ RELABEL="system_u:object_r:container_file_t:s0"
|
|||
TESTDIR=$PODMAN_TMPDIR/testdir
|
||||
mkdir -p $TESTDIR
|
||||
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
|
||||
|
||||
run_podman play kube - < $PODMAN_TMPDIR/test.yaml
|
||||
if [ -e /usr/sbin/selinuxenabled -a /usr/sbin/selinuxenabled ]; then
|
||||
run ls -Zd $TESTDIR
|
||||
is "$output" ${RELABEL} "selinux relabel should have happened"
|
||||
fi
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod stop test_pod
|
||||
run_podman pod rm -f test_pod
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +90,9 @@ RELABEL="system_u:object_r:container_file_t:s0"
|
|||
run ls -Zd $TESTDIR
|
||||
is "$output" ${RELABEL} "selinux relabel should have happened"
|
||||
fi
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod stop test_pod
|
||||
run_podman pod rm -f test_pod
|
||||
}
|
||||
|
||||
|
|
@ -102,12 +109,19 @@ RELABEL="system_u:object_r:container_file_t:s0"
|
|||
infraID="$output"
|
||||
run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
|
||||
is "$output" "slirp4netns" "network mode slirp4netns is set for the container"
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod stop test_pod
|
||||
run_podman pod rm -f test_pod
|
||||
|
||||
run_podman play kube --network none $PODMAN_TMPDIR/test.yaml
|
||||
run_podman pod inspect --format {{.InfraContainerID}} "${lines[1]}"
|
||||
infraID="$output"
|
||||
run_podman container inspect --format "{{.HostConfig.NetworkMode}}" $infraID
|
||||
is "$output" "none" "network mode none is set for the container"
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod stop test_pod
|
||||
run_podman pod rm -f test_pod
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +163,9 @@ _EOF
|
|||
run_podman play kube --start=false $PODMAN_TMPDIR/test.yaml
|
||||
run_podman inspect --format "{{ .Config.User }}" test_pod-test
|
||||
is "$output" bin "expect container within pod to run as the bin user"
|
||||
|
||||
run_podman stop -a -t 0
|
||||
run_podman pod stop test_pod
|
||||
run_podman pod rm -f test_pod
|
||||
run_podman rmi -f userimage:latest
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue