summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml75
-rw-r--r--cmd/podman/images/history.go8
-rw-r--r--cmd/podman/images/search.go6
-rw-r--r--cmd/podman/machine/set.go60
-rw-r--r--contrib/cirrus/lib.sh53
-rwxr-xr-xcontrib/cirrus/logcollector.sh43
-rwxr-xr-xcontrib/cirrus/runner.sh9
-rwxr-xr-xcontrib/cirrus/setup_environment.sh74
-rw-r--r--docs/source/markdown/podman-history.1.md9
-rw-r--r--docs/source/markdown/podman-machine-set.1.md20
-rw-r--r--docs/source/markdown/podman-search.1.md2
-rw-r--r--pkg/machine/config.go7
-rw-r--r--pkg/machine/e2e/config_set.go43
-rw-r--r--pkg/machine/e2e/init_test.go6
-rw-r--r--pkg/machine/e2e/inspect_test.go9
-rw-r--r--pkg/machine/e2e/rm_test.go11
-rw-r--r--pkg/machine/e2e/set_test.go134
-rw-r--r--pkg/machine/e2e/ssh_test.go11
-rw-r--r--pkg/machine/e2e/start_test.go5
-rw-r--r--pkg/machine/e2e/stop_test.go9
-rw-r--r--pkg/machine/qemu/machine.go138
-rw-r--r--pkg/machine/qemu/machine_test.go17
-rw-r--r--pkg/machine/wsl/machine.go57
-rw-r--r--test/e2e/run_networking_test.go2
-rw-r--r--test/system/110-history.bats13
25 files changed, 566 insertions, 255 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index cf97f4467..958c6b0c7 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -7,10 +7,6 @@ env:
####
# Name of the ultimate destination branch for this CI run, PR or post-merge.
DEST_BRANCH: "main"
- # Netavark branch to use when TEST_ENVIRON=host-netavark
- NETAVARK_BRANCH: "main"
- # Aardvark branch to use
- AARDVARK_BRANCH: "main"
# Overrides default location (/tmp/cirrus) for repo clone
GOPATH: &gopath "/var/tmp/go"
GOBIN: "${GOPATH}/bin"
@@ -24,21 +20,16 @@ env:
# Runner statistics log file path/name
STATS_LOGFILE_SFX: 'runner_stats.log'
STATS_LOGFILE: '$GOSRC/${CIRRUS_TASK_NAME}-${STATS_LOGFILE_SFX}'
- # Netavark/aardvark location/options when TEST_ENVIRON=host-netavark
- NETAVARK_URL: "https://api.cirrus-ci.com/v1/artifact/github/containers/netavark/success/binary.zip?branch=${NETAVARK_BRANCH}"
- NETAVARK_DEBUG: 0 # set non-zero to use the debug-mode binary
- AARDVARK_URL: "https://api.cirrus-ci.com/v1/artifact/github/containers/aardvark-dns/success/binary.zip?branch=${AARDVARK_BRANCH}"
- AARDVARK_DEBUG: 0 # set non-zero to use the debug-mode binary
####
#### Cache-image names to test with (double-quotes around names are critical)
####
- FEDORA_NAME: "fedora-35"
- PRIOR_FEDORA_NAME: "fedora-34"
+ FEDORA_NAME: "fedora-36"
+ PRIOR_FEDORA_NAME: "fedora-35"
UBUNTU_NAME: "ubuntu-2110"
# Google-cloud VM Images
- IMAGE_SUFFIX: "c4831699639992320"
+ IMAGE_SUFFIX: "c4955393725038592"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
@@ -53,7 +44,7 @@ env:
#### N/B: Required ALL of these are set for every single task.
####
TEST_FLAVOR: # int, sys, ext_svc, validate, automation, etc.
- TEST_ENVIRON: host # 'host', 'host-netavark', or 'container'
+ TEST_ENVIRON: host # 'host', or 'container'
PODBIN_NAME: podman # 'podman' or 'remote'
PRIV_NAME: root # 'root' or 'rootless'
DISTRO_NV: # any {PRIOR_,}{FEDORA,UBUNTU}_NAME value
@@ -161,11 +152,11 @@ build_task:
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
# ID for re-use of build output
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- #- env: &priorfedora_envvars
- # DISTRO_NV: ${PRIOR_FEDORA_NAME}
- # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
- # _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ - env: &priorfedora_envvars
+ DISTRO_NV: ${PRIOR_FEDORA_NAME}
+ VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
+ _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- env: &ubuntu_envvars
DISTRO_NV: ${UBUNTU_NAME}
VM_IMAGE_NAME: ${UBUNTU_CACHE_IMAGE_NAME}
@@ -394,7 +385,7 @@ unit_test_task:
- validate
matrix:
- env: *stdenvars
- #- env: *priorfedora_envvars
+ - env: *priorfedora_envvars
- env: *ubuntu_envvars
# Special-case: Rootless on latest Fedora (standard) VM
- name: "Rootless unit on $DISTRO_NV"
@@ -515,11 +506,11 @@ container_integration_test_task:
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
- #- env:
- # DISTRO_NV: ${PRIOR_FEDORA_NAME}
- # _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
+ - env:
+ DISTRO_NV: ${PRIOR_FEDORA_NAME}
+ _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
gce_instance: *standardvm
timeout_in: 90m
env:
@@ -553,41 +544,6 @@ rootless_integration_test_task:
always: *int_logs_artifacts
-# Run various scenarios using upstream netavark/aardvark-dns binaries
-netavark_task:
- name: "Netavark $TEST_FLAVOR $PODBIN_NAME $PRIV_NAME"
- alias: netavark
- only_if: *not_build
- skip: *branches_and_tags
- depends_on:
- - unit_test
- gce_instance: *standardvm
- matrix:
- - env: &nenv
- DISTRO_NV: ${FEDORA_NAME}
- _BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
- CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
- TEST_FLAVOR: int
- TEST_ENVIRON: host-netavark
- - env:
- <<: *nenv
- TEST_FLAVOR: int
- PRIV_NAME: rootless
- - env:
- <<: *nenv
- TEST_FLAVOR: sys
- - env:
- <<: *nenv
- TEST_FLAVOR: sys
- PRIV_NAME: rootless
- clone_script: *noop # Comes from cache
- gopath_cache: *ro_gopath_cache
- setup_script: *setup
- main_script: *main
- always: *int_logs_artifacts
-
-
# Always run subsequent to integration tests. While parallelism is lost
# with runtime, debugging system-test failures can be more challenging
# for some golang developers. Otherwise the following tasks run across
@@ -841,7 +797,6 @@ success_task:
- remote_integration_test
- container_integration_test
- rootless_integration_test
- - netavark
- local_system_test
- remote_system_test
- rootless_system_test
diff --git a/cmd/podman/images/history.go b/cmd/podman/images/history.go
index c05d3475b..26a4b6c3b 100644
--- a/cmd/podman/images/history.go
+++ b/cmd/podman/images/history.go
@@ -168,3 +168,11 @@ func (h historyReporter) ID() string {
}
return h.ImageHistoryLayer.ID
}
+
+func (h historyReporter) CreatedAt() string {
+ return time.Unix(h.ImageHistoryLayer.Created.Unix(), 0).UTC().String()
+}
+
+func (h historyReporter) CreatedSince() string {
+ return h.Created()
+}
diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go
index aa11cf254..7f202cb6a 100644
--- a/cmd/podman/images/search.go
+++ b/cmd/podman/images/search.go
@@ -23,6 +23,7 @@ type searchOptionsWrapper struct {
Compatible bool // Docker compat
TLSVerifyCLI bool // Used to convert to an optional bool later
Format string // For go templating
+ NoTrunc bool
}
// listEntryTag is a utility structure used for json serialization.
@@ -92,7 +93,7 @@ func searchFlags(cmd *cobra.Command) {
flags.IntVar(&searchOptions.Limit, limitFlagName, 0, "Limit the number of results")
_ = cmd.RegisterFlagCompletionFunc(limitFlagName, completion.AutocompleteNone)
- flags.Bool("no-trunc", true, "Do not truncate the output. Default: true")
+ flags.BoolVar(&searchOptions.NoTrunc, "no-trunc", false, "Do not truncate the output")
flags.BoolVar(&searchOptions.Compatible, "compatible", false, "List stars, official and automated columns (Docker compatibility)")
authfileFlagName := "authfile"
@@ -139,11 +140,10 @@ func imageSearch(cmd *cobra.Command, args []string) error {
return nil
}
- noTrunc, _ := cmd.Flags().GetBool("no-trunc")
isJSON := report.IsJSON(searchOptions.Format)
for i, element := range searchReport {
d := strings.ReplaceAll(element.Description, "\n", " ")
- if len(d) > 44 && !(noTrunc || isJSON) {
+ if len(d) > 44 && !(searchOptions.NoTrunc || isJSON) {
d = strings.TrimSpace(d[:44]) + "..."
}
searchReport[i].Description = d
diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go
index 4c15f1de1..a994c981b 100644
--- a/cmd/podman/machine/set.go
+++ b/cmd/podman/machine/set.go
@@ -4,6 +4,9 @@
package machine
import (
+ "fmt"
+ "os"
+
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/machine"
@@ -23,9 +26,17 @@ var (
)
var (
- setOpts = machine.SetOptions{}
+ setFlags = SetFlags{}
+ setOpts = machine.SetOptions{}
)
+type SetFlags struct {
+ CPUs uint64
+ DiskSize uint64
+ Memory uint64
+ Rootful bool
+}
+
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: setCmd,
@@ -34,7 +45,32 @@ func init() {
flags := setCmd.Flags()
rootfulFlagName := "rootful"
- flags.BoolVar(&setOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ flags.BoolVar(&setFlags.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+
+ cpusFlagName := "cpus"
+ flags.Uint64Var(
+ &setFlags.CPUs,
+ cpusFlagName, 0,
+ "Number of CPUs",
+ )
+ _ = setCmd.RegisterFlagCompletionFunc(cpusFlagName, completion.AutocompleteNone)
+
+ diskSizeFlagName := "disk-size"
+ flags.Uint64Var(
+ &setFlags.DiskSize,
+ diskSizeFlagName, 0,
+ "Disk size in GB",
+ )
+
+ _ = setCmd.RegisterFlagCompletionFunc(diskSizeFlagName, completion.AutocompleteNone)
+
+ memoryFlagName := "memory"
+ flags.Uint64VarP(
+ &setFlags.Memory,
+ memoryFlagName, "m", 0,
+ "Memory in MB",
+ )
+ _ = setCmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
}
func setMachine(cmd *cobra.Command, args []string) error {
@@ -53,5 +89,23 @@ func setMachine(cmd *cobra.Command, args []string) error {
return err
}
- return vm.Set(vmName, setOpts)
+ if cmd.Flags().Changed("rootful") {
+ setOpts.Rootful = &setFlags.Rootful
+ }
+ if cmd.Flags().Changed("cpus") {
+ setOpts.CPUs = &setFlags.CPUs
+ }
+ if cmd.Flags().Changed("memory") {
+ setOpts.Memory = &setFlags.Memory
+ }
+ if cmd.Flags().Changed("disk-size") {
+ setOpts.DiskSize = &setFlags.DiskSize
+ }
+
+ setErrs, lasterr := vm.Set(vmName, setOpts)
+ for _, err := range setErrs {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ }
+
+ return lasterr
}
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index 09a255e6f..0f02c166f 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -97,7 +97,7 @@ EPOCH_TEST_COMMIT="$CIRRUS_BASE_SHA"
# testing operations on all platforms and versions. This is necessary
# to avoid needlessly passing through global/system values across
# contexts, such as host->container or root->rootless user
-PASSTHROUGH_ENV_RE='(^CI.*)|(^CIRRUS)|(^DISTRO_NV)|(^GOPATH)|(^GOCACHE)|(^GOSRC)|(^SCRIPT_BASE)|(CGROUP_MANAGER)|(OCI_RUNTIME)|(^TEST.*)|(^PODBIN_NAME)|(^PRIV_NAME)|(^ALT_NAME)|(^ROOTLESS_USER)|(SKIP_USERNS)|(.*_NAME)|(.*_FQIN)'
+PASSTHROUGH_ENV_RE='(^CI.*)|(^CIRRUS)|(^DISTRO_NV)|(^GOPATH)|(^GOCACHE)|(^GOSRC)|(^SCRIPT_BASE)|(CGROUP_MANAGER)|(OCI_RUNTIME)|(^TEST.*)|(^PODBIN_NAME)|(^PRIV_NAME)|(^ALT_NAME)|(^ROOTLESS_USER)|(SKIP_USERNS)|(.*_NAME)|(.*_FQIN)|(NETWORK_BACKEND)'
# Unsafe env. vars for display
SECRET_ENV_RE='(ACCOUNT)|(GC[EP]..+)|(SSH)|(PASSWORD)|(TOKEN)'
@@ -169,10 +169,6 @@ setup_rootless() {
groupadd -g $rootless_gid $ROOTLESS_USER
useradd -g $rootless_gid -u $rootless_uid --no-user-group --create-home $ROOTLESS_USER
- # We also set up rootless user for image-scp tests (running as root)
- if [[ $PRIV_NAME = "rootless" ]]; then
- chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
- fi
echo "$ROOTLESS_USER ALL=(root) NOPASSWD: ALL" > /etc/sudoers.d/ci-rootless
mkdir -p "$HOME/.ssh" "/home/$ROOTLESS_USER/.ssh"
@@ -216,20 +212,39 @@ setup_rootless() {
install_test_configs() {
msg "Installing ./test/registries.conf system-wide."
install -v -D -m 644 ./test/registries.conf /etc/containers/
- if [[ "$TEST_ENVIRON" =~ netavark ]]; then
- # belt-and-suspenders: any pre-existing CNI config. will spoil
- # default use tof netavark (when both are installed).
- rm -rf /etc/cni/net.d/*
- else
- echo "Installing cni config, policy and registry config"
- req_env_vars GOSRC SCRIPT_BASE
- cd $GOSRC || exit 1
- install -v -D -m 644 ./cni/87-podman-bridge.conflist /etc/cni/net.d/
- # This config must always sort last in the list of networks (podman picks first one
- # as the default). This config prevents allocation of network address space used
- # by default in google cloud. https://cloud.google.com/vpc/docs/vpc#ip-ranges
- install -v -D -m 644 $SCRIPT_BASE/99-do-not-use-google-subnets.conflist /etc/cni/net.d/
- fi
+}
+
+use_cni() {
+ msg "Unsetting NETWORK_BACKEND for all subsequent environments."
+ echo "export -n NETWORK_BACKEND" >> /etc/ci_environment
+ echo "unset NETWORK_BACKEND" >> /etc/ci_environment
+ export -n NETWORK_BACKEND
+ unset NETWORK_BACKEND
+ msg "Installing default CNI configuration"
+ cd $GOSRC || exit 1
+ rm -rvf /etc/cni/net.d
+ mkdir -p /etc/cni/net.d
+ install -v -D -m 644 ./cni/87-podman-bridge.conflist \
+ /etc/cni/net.d/
+ # This config must always sort last in the list of networks (podman picks
+ # first one as the default). This config prevents allocation of network
+ # address space used by default in google cloud.
+ # https://cloud.google.com/vpc/docs/vpc#ip-ranges
+ install -v -D -m 644 $SCRIPT_BASE/99-do-not-use-google-subnets.conflist \
+ /etc/cni/net.d/
+}
+
+use_netavark() {
+ msg "Forcing NETWORK_BACKEND=netavark for all subsequent environments."
+ echo "NETWORK_BACKEND=netavark" >> /etc/ci_environment
+ export NETWORK_BACKEND=netavark # needed for install_test_configs()
+ msg "Removing any/all CNI configuration"
+ rm -rvf /etc/cni/net.d/*
+
+ # TODO: Remove this when netavark/aardvark-dns development slows down
+ warn "Updating netavark/aardvark-dns to avoid frequent VM image rebuilds"
+ # N/B: This is coming from updates-testing repo in F36
+ lilto dnf update -y netavark aardvark-dns
}
# Remove all files provided by the distro version of podman.
diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh
index 0cfbf7135..d712713b4 100755
--- a/contrib/cirrus/logcollector.sh
+++ b/contrib/cirrus/logcollector.sh
@@ -40,32 +40,34 @@ case $1 in
packages)
# These names are common to Fedora and Ubuntu
PKG_NAMES=(\
- conmon \
- containernetworking-plugins \
- containers-common \
- criu \
- crun \
- golang \
- podman \
- runc \
- skopeo \
- slirp4netns \
+ conmon
+ containernetworking-plugins
+ containers-common
+ criu
+ crun
+ golang
+ podman
+ runc
+ skopeo
+ slirp4netns
)
case $OS_RELEASE_ID in
fedora)
cat /etc/fedora-release
PKG_LST_CMD='rpm -q --qf=%{N}-%{V}-%{R}-%{ARCH}\n'
PKG_NAMES+=(\
- container-selinux \
- libseccomp \
+ aardvark
+ container-selinux
+ libseccomp
+ netavark
)
;;
ubuntu)
cat /etc/issue
PKG_LST_CMD='dpkg-query --show --showformat=${Package}-${Version}-${Architecture}\n'
PKG_NAMES+=(\
- cri-o-runc \
- libseccomp2 \
+ cri-o-runc
+ libseccomp2
)
;;
*) bad_os_id_ver ;;
@@ -74,19 +76,6 @@ case $1 in
echo "Cgroups: " $(stat -f -c %T /sys/fs/cgroup)
# Any not-present packages will be listed as such
$PKG_LST_CMD "${PKG_NAMES[@]}" | sort -u
-
- # TODO: Remove this once netavark/aardvark-dns packages are used
- if [[ "$TEST_ENVIRON" =~ netavark ]]; then
- _npath=/usr/local/libexec/podman/
- for name in netavark aardvark-dns; do
- echo "$name binary details:"
- if [[ -r "$_npath/${name}.info" ]]; then
- cat "$_npath/${name}.info"
- else
- echo "WARNING: $_npath/${name}.info not found."
- fi
- done
- fi
;;
time)
# Assumed to be empty/undefined outside of Cirrus-CI (.cirrus.yml)
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index 5d6ba9921..101270703 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -12,7 +12,7 @@ set -eo pipefail
# most notably:
#
# PODBIN_NAME : "podman" (i.e. local) or "remote"
-# TEST_ENVIRON : 'host', 'host-netavark', or 'container'; desired environment in which to run
+# TEST_ENVIRON : 'host', or 'container'; desired environment in which to run
# CONTAINER : 1 if *currently* running inside a container, 0 if host
#
@@ -449,6 +449,13 @@ if [[ "$PRIV_NAME" == "rootless" ]] && [[ "$UID" -eq 0 ]]; then
# https://github.com/containers/podman/issues/10857
rm -rf /var/lib/cni
+ # This must be done at the last second, otherwise `make` calls
+ # in setup_environment (as root) will balk about ownership.
+ msg "Recursively chowning \$GOPATH and \$GOSRC to $ROOTLESS_USER"
+ if [[ $PRIV_NAME = "rootless" ]]; then
+ chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
+ fi
+
req_env_vars ROOTLESS_USER
msg "Re-executing runner through ssh as user '$ROOTLESS_USER'"
msg "************************************************************"
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 742289733..e3eb46783 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -38,13 +38,12 @@ done
cp hack/podman-registry /bin
-# Make sure cni network plugins directory exists
-mkdir -p /etc/cni/net.d
-
# Some test operations & checks require a git "identity"
_gc='git config --file /root/.gitconfig'
$_gc user.email "TMcTestFace@example.com"
$_gc user.name "Testy McTestface"
+# Bypass git safety/security checks when operating in a throwaway environment
+git config --system --add safe.directory $GOSRC
# Ensure that all lower-level contexts and child-processes have
# ready access to higher level orchestration (e.g Cirrus-CI)
@@ -84,13 +83,6 @@ case "$CG_FS_TYPE" in
else
echo "OCI_RUNTIME=runc" >> /etc/ci_environment
fi
-
- # As a general policy CGv1 + runc should coincide with the "older"
- # VM Images in CI. Verify this is the case.
- if [[ -n "$VM_IMAGE_NAME" ]] && [[ ! "$VM_IMAGE_NAME" =~ prior ]]
- then
- die "Most recent distro. version should never run with CGv1"
- fi
fi
;;
cgroup2fs)
@@ -99,13 +91,6 @@ case "$CG_FS_TYPE" in
# which uses runc as the default.
warn "Forcing testing with crun instead of runc"
echo "OCI_RUNTIME=crun" >> /etc/ci_environment
-
- # As a general policy CGv2 + crun should coincide with the "newer"
- # VM Images in CI. Verify this is the case.
- if [[ -n "$VM_IMAGE_NAME" ]] && [[ "$VM_IMAGE_NAME" =~ prior ]]
- then
- die "Least recent distro. version should never run with CGv2"
- fi
fi
;;
*) die_unknown CG_FS_TYPE
@@ -130,6 +115,19 @@ case "$OS_RELEASE_ID" in
msg "Enabling container_manage_cgroup"
setsebool container_manage_cgroup true
fi
+
+ # For release 36 and later, netavark/aardvark is the default
+ # networking stack for podman. All previous releases only have
+ # CNI networking available. Upgrading from one to the other is
+ # not supported at this time. Support execution of the upgrade
+ # tests in F36 and later, by disabling Netavark and enabling CNI.
+ if [[ "$OS_RELEASE_VER" -ge 36 ]] && \
+ [[ "$TEST_FLAVOR" != "upgrade_test" ]];
+ then
+ use_netavark
+ else # Fedora < 36, or upgrade testing.
+ use_cni
+ fi
;;
*) die_unknown OS_RELEASE_ID
esac
@@ -137,7 +135,7 @@ esac
# Required to be defined by caller: The environment where primary testing happens
# shellcheck disable=SC2154
case "$TEST_ENVIRON" in
- host*)
+ host)
# The e2e tests wrongly guess `--cgroup-manager` option
# shellcheck disable=SC2154
if [[ "$CG_FS_TYPE" == "cgroup2fs" ]] || [[ "$PRIV_NAME" == "root" ]]
@@ -148,43 +146,6 @@ case "$TEST_ENVIRON" in
warn "Forcing CGROUP_MANAGER=cgroupfs"
echo "CGROUP_MANAGER=cgroupfs" >> /etc/ci_environment
fi
- # TODO: For the foreseeable future, need to support running tests
- # with and without the latest netavark/aardvark. Once they're more
- # stable and widely supported in Fedora, they can be pre-installed
- # from its RPM at VM image build-time.
- if [[ "$TEST_ENVIRON" =~ netavark ]]; then
- for info in "netavark $NETAVARK_BRANCH $NETAVARK_URL $NETAVARK_DEBUG" \
- "aardvark-dns $AARDVARK_BRANCH $AARDVARK_URL $AARDVARK_DEBUG"; do
-
- read _name _branch _url _debug <<<"$info"
- req_env_vars _name _branch _url _debug
- msg "Downloading latest $_name from upstream branch '$_branch'"
- # Use identifiable archive filename in of a get_ci_env.sh environment
- curl --fail --location -o /tmp/$_name.zip "$_url"
-
- # Needs to be in a specific location
- # ref: https://github.com/containers/common/blob/main/pkg/config/config_linux.go#L39
- _pdir=/usr/local/libexec/podman
- mkdir -p $_pdir
- cd $_pdir
- msg "$PWD"
- unzip /tmp/$_name.zip
- if ((_debug)); then
- warn "Using debug $_name binary"
- mv $_name.debug $_name
- else
- rm $_name.debug
- fi
- chmod 0755 $_pdir/$_name
- cd -
- done
-
- restorecon -F -v $_nvdir
- # This is critical, it signals to all tests that netavark
- # use is expected.
- msg "Forcing NETWORK_BACKEND=netavark in all subsequent environments."
- echo "NETWORK_BACKEND=netavark" >> /etc/ci_environment
- fi
;;
container)
if ((CONTAINER==0)); then # not yet inside a container
@@ -345,6 +306,9 @@ case "$TEST_FLAVOR" in
# Guarantee the docker daemon can't be started, even by accident
rm -vf $(type -P dockerd)
+ msg "Recursively chowning source to $ROOTLESS_USER"
+ chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC"
+
msg "Obtaining necessary gitlab-runner testing bits"
slug="gitlab.com/gitlab-org/gitlab-runner"
helper_fqin="registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest-pwsh"
diff --git a/docs/source/markdown/podman-history.1.md b/docs/source/markdown/podman-history.1.md
index af35814c2..16f1e48e6 100644
--- a/docs/source/markdown/podman-history.1.md
+++ b/docs/source/markdown/podman-history.1.md
@@ -23,10 +23,11 @@ Valid placeholders for the Go template are listed below:
| --------------- | ----------------------------------------------------------------------------- |
| .ID | Image ID |
| .Created | if --human, time elapsed since creation, otherwise time stamp of creation |
-| .CreatedBy | Command used to create the layer |
-| .Size | Size of layer on disk |
-| .Comment | Comment for the layer |
-
+| .CreatedAt | Time when the image layer was created |
+| .CreatedBy | Command used to create the layer |
+| .CreatedSince | Elapsed time since the image layer was created |
+| .Size | Size of layer on disk |
+| .Comment | Comment for the layer |
## OPTIONS
Print the numeric IDs only (default *false*).
diff --git a/docs/source/markdown/podman-machine-set.1.md b/docs/source/markdown/podman-machine-set.1.md
index a4918eacf..de90ee4b0 100644
--- a/docs/source/markdown/podman-machine-set.1.md
+++ b/docs/source/markdown/podman-machine-set.1.md
@@ -8,17 +8,29 @@ podman\-machine\-set - Sets a virtual machine setting
## DESCRIPTION
-Sets an updatable virtual machine setting.
-
-Options mirror values passed to `podman machine init`. Only a limited
-subset can be changed after machine initialization.
+Change a machine setting.
## OPTIONS
+#### **--cpus**=*number*
+
+Number of CPUs.
+Only supported for QEMU machines.
+
+#### **--disk-size**=*number*
+
+Size of the disk for the guest VM in GB.
+Can only be increased. Only supported for QEMU machines.
+
#### **--help**
Print usage statement.
+#### **--memory**, **-m**=*number*
+
+Memory (in MB).
+Only supported for QEMU machines.
+
#### **--rootful**=*true|false*
Whether this machine should prefer rootful (`true`) or rootless (`false`)
diff --git a/docs/source/markdown/podman-search.1.md b/docs/source/markdown/podman-search.1.md
index 81a67d762..5b49d7f8e 100644
--- a/docs/source/markdown/podman-search.1.md
+++ b/docs/source/markdown/podman-search.1.md
@@ -90,7 +90,7 @@ The result contains the Image name and its tag, one line for every tag associate
#### **--no-trunc**
-Do not truncate the output (default *true*).
+Do not truncate the output (default *false*).
#### **--tls-verify**
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 5bbaf8c51..833f9cba8 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -95,7 +95,10 @@ type ListResponse struct {
}
type SetOptions struct {
- Rootful bool
+ CPUs *uint64
+ DiskSize *uint64
+ Memory *uint64
+ Rootful *bool
}
type SSHOptions struct {
@@ -118,7 +121,7 @@ type InspectOptions struct{}
type VM interface {
Init(opts InitOptions) (bool, error)
Remove(name string, opts RemoveOptions) (string, func() error, error)
- Set(name string, opts SetOptions) error
+ Set(name string, opts SetOptions) ([]error, error)
SSH(name string, opts SSHOptions) error
Start(name string, opts StartOptions) error
State(bypass bool) (Status, error)
diff --git a/pkg/machine/e2e/config_set.go b/pkg/machine/e2e/config_set.go
new file mode 100644
index 000000000..b310ab1b9
--- /dev/null
+++ b/pkg/machine/e2e/config_set.go
@@ -0,0 +1,43 @@
+package e2e
+
+import (
+ "strconv"
+)
+
+type setMachine struct {
+ cpus *uint
+ diskSize *uint
+ memory *uint
+
+ cmd []string
+}
+
+func (i *setMachine) buildCmd(m *machineTestBuilder) []string {
+ cmd := []string{"machine", "set"}
+ if i.cpus != nil {
+ cmd = append(cmd, "--cpus", strconv.Itoa(int(*i.cpus)))
+ }
+ if i.diskSize != nil {
+ cmd = append(cmd, "--disk-size", strconv.Itoa(int(*i.diskSize)))
+ }
+ if i.memory != nil {
+ cmd = append(cmd, "--memory", strconv.Itoa(int(*i.memory)))
+ }
+ cmd = append(cmd, m.name)
+ i.cmd = cmd
+ return cmd
+}
+
+func (i *setMachine) withCPUs(num uint) *setMachine {
+ i.cpus = &num
+ return i
+}
+func (i *setMachine) withDiskSize(size uint) *setMachine {
+ i.diskSize = &size
+ return i
+}
+
+func (i *setMachine) withMemory(num uint) *setMachine {
+ i.memory = &num
+ return i
+}
diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go
index 309d460a9..304122738 100644
--- a/pkg/machine/e2e/init_test.go
+++ b/pkg/machine/e2e/init_test.go
@@ -28,13 +28,13 @@ var _ = Describe("podman machine init", func() {
reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
session, err := mb.setName(reallyLongName).setCmd(&i).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(125))
+ Expect(session).To(Exit(125))
})
It("simple init", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
inspectBefore, ec, err := mb.toQemuInspectInfo()
Expect(err).To(BeNil())
@@ -52,7 +52,7 @@ var _ = Describe("podman machine init", func() {
i := initMachine{}
session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
inspectBefore, ec, err := mb.toQemuInspectInfo()
Expect(ec).To(BeZero())
diff --git a/pkg/machine/e2e/inspect_test.go b/pkg/machine/e2e/inspect_test.go
index 30d810b8f..e282dd21d 100644
--- a/pkg/machine/e2e/inspect_test.go
+++ b/pkg/machine/e2e/inspect_test.go
@@ -7,6 +7,7 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine stop", func() {
@@ -27,24 +28,24 @@ var _ = Describe("podman machine stop", func() {
reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
session, err := mb.setName(reallyLongName).setCmd(&i).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(125))
+ Expect(session).To(Exit(125))
})
It("inspect two machines", func() {
i := new(initMachine)
foo1, err := mb.setName("foo1").setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(foo1.ExitCode()).To(Equal(0))
+ Expect(foo1).To(Exit(0))
ii := new(initMachine)
foo2, err := mb.setName("foo2").setCmd(ii.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(foo2.ExitCode()).To(Equal(0))
+ Expect(foo2).To(Exit(0))
inspect := new(inspectMachine)
inspectSession, err := mb.setName("foo1").setCmd(inspect).run()
Expect(err).To(BeNil())
- Expect(inspectSession.ExitCode()).To(Equal(0))
+ Expect(inspectSession).To(Exit(0))
type fakeInfos struct {
Status string
diff --git a/pkg/machine/e2e/rm_test.go b/pkg/machine/e2e/rm_test.go
index 011da5dde..43b8c594c 100644
--- a/pkg/machine/e2e/rm_test.go
+++ b/pkg/machine/e2e/rm_test.go
@@ -3,6 +3,7 @@ package e2e
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine rm", func() {
@@ -23,14 +24,14 @@ var _ = Describe("podman machine rm", func() {
reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
session, err := mb.setName(reallyLongName).setCmd(&i).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(125))
+ Expect(session).To(Exit(125))
})
It("Remove machine", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
rm := rmMachine{}
_, err = mb.setCmd(rm.withForce()).run()
Expect(err).To(BeNil())
@@ -46,18 +47,18 @@ var _ = Describe("podman machine rm", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImagePath(mb.imagePath).withNow()).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
rm := new(rmMachine)
// Removing a running machine should fail
stop, err := mb.setCmd(rm).run()
Expect(err).To(BeNil())
- Expect(stop.ExitCode()).To(Equal(125))
+ Expect(stop).To(Exit(125))
// Removing again with force
stopAgain, err := mb.setCmd(rm.withForce()).run()
Expect(err).To(BeNil())
- Expect(stopAgain.ExitCode()).To(BeZero())
+ Expect(stopAgain).To(Exit(0))
// Inspect to be dead sure
_, ec, err := mb.toQemuInspectInfo()
diff --git a/pkg/machine/e2e/set_test.go b/pkg/machine/e2e/set_test.go
new file mode 100644
index 000000000..9af29c560
--- /dev/null
+++ b/pkg/machine/e2e/set_test.go
@@ -0,0 +1,134 @@
+package e2e
+
+import (
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("podman machine set", func() {
+ var (
+ mb *machineTestBuilder
+ testDir string
+ )
+
+ BeforeEach(func() {
+ testDir, mb = setup()
+ })
+ AfterEach(func() {
+ teardown(originalHomeDir, testDir, mb)
+ })
+
+ It("set machine cpus", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ set := setMachine{}
+ setSession, err := mb.setName(name).setCmd(set.withCPUs(2)).run()
+ Expect(err).To(BeNil())
+ Expect(setSession).To(Exit(0))
+
+ s := new(startMachine)
+ startSession, err := mb.setCmd(s).run()
+ Expect(err).To(BeNil())
+ Expect(startSession).To(Exit(0))
+
+ ssh2 := sshMachine{}
+ sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run()
+ Expect(err).To(BeNil())
+ Expect(sshSession2).To(Exit(0))
+ Expect(sshSession2.outputToString()).To(ContainSubstring("2"))
+
+ // Setting a running machine results in 125
+ runner, err := mb.setName(name).setCmd(set.withCPUs(4)).run()
+ Expect(err).To(BeNil())
+ Expect(runner).To(Exit(125))
+ })
+
+ It("increase machine disk size", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ set := setMachine{}
+ setSession, err := mb.setName(name).setCmd(set.withDiskSize(102)).run()
+ Expect(err).To(BeNil())
+ Expect(setSession).To(Exit(0))
+
+ // shrinking disk size iss verboten
+ shrink, err := mb.setName(name).setCmd(set.withDiskSize(5)).run()
+ Expect(err).To(BeNil())
+ Expect(shrink).To(Exit(125))
+
+ s := new(startMachine)
+ startSession, err := mb.setCmd(s).run()
+ Expect(err).To(BeNil())
+ Expect(startSession).To(Exit(0))
+
+ ssh2 := sshMachine{}
+ sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run()
+ Expect(err).To(BeNil())
+ Expect(sshSession2).To(Exit(0))
+ Expect(sshSession2.outputToString()).To(ContainSubstring("102 GiB"))
+ })
+
+ It("set machine ram", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ set := setMachine{}
+ setSession, err := mb.setName(name).setCmd(set.withMemory(4000)).run()
+ Expect(err).To(BeNil())
+ Expect(setSession).To(Exit(0))
+
+ s := new(startMachine)
+ startSession, err := mb.setCmd(s).run()
+ Expect(err).To(BeNil())
+ Expect(startSession).To(Exit(0))
+
+ ssh2 := sshMachine{}
+ sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"cat", "/proc/meminfo", "|", "numfmt", "--field", "2", "--from-unit=Ki", "--to-unit=Mi", "|", "sed", "'s/ kB/M/g'", "|", "grep", "MemTotal"})).run()
+ Expect(err).To(BeNil())
+ Expect(sshSession2).To(Exit(0))
+ Expect(sshSession2.outputToString()).To(ContainSubstring("3824"))
+ })
+
+ It("no settings should change if no flags", func() {
+ name := randomString(12)
+ i := new(initMachine)
+ session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
+ Expect(err).To(BeNil())
+ Expect(session).To(Exit(0))
+
+ set := setMachine{}
+ setSession, err := mb.setName(name).setCmd(&set).run()
+ Expect(err).To(BeNil())
+ Expect(setSession).To(Exit(0))
+
+ s := new(startMachine)
+ startSession, err := mb.setCmd(s).run()
+ Expect(err).To(BeNil())
+ Expect(startSession).To(Exit(0))
+
+ ssh2 := sshMachine{}
+ sshSession2, err := mb.setName(name).setCmd(ssh2.withSSHComand([]string{"lscpu", "|", "grep", "\"CPU(s):\"", "|", "head", "-1"})).run()
+ Expect(err).To(BeNil())
+ Expect(sshSession2).To(Exit(0))
+ Expect(sshSession2.outputToString()).To(ContainSubstring("1"))
+
+ ssh3 := sshMachine{}
+ sshSession3, err := mb.setName(name).setCmd(ssh3.withSSHComand([]string{"sudo", "fdisk", "-l", "|", "grep", "Disk"})).run()
+ Expect(err).To(BeNil())
+ Expect(sshSession3).To(Exit(0))
+ Expect(sshSession3.outputToString()).To(ContainSubstring("100 GiB"))
+ })
+
+})
diff --git a/pkg/machine/e2e/ssh_test.go b/pkg/machine/e2e/ssh_test.go
index 90296fa10..155d39a64 100644
--- a/pkg/machine/e2e/ssh_test.go
+++ b/pkg/machine/e2e/ssh_test.go
@@ -3,6 +3,7 @@ package e2e
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine ssh", func() {
@@ -23,7 +24,7 @@ var _ = Describe("podman machine ssh", func() {
ssh := sshMachine{}
session, err := mb.setName(name).setCmd(ssh).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(125))
+ Expect(session).To(Exit(125))
// TODO seems like stderr is not being returned; re-enabled when fixed
//Expect(session.outputToString()).To(ContainSubstring("not exist"))
})
@@ -33,14 +34,14 @@ var _ = Describe("podman machine ssh", func() {
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
ssh := sshMachine{}
sshSession, err := mb.setName(name).setCmd(ssh).run()
Expect(err).To(BeNil())
// TODO seems like stderr is not being returned; re-enabled when fixed
//Expect(sshSession.outputToString()).To(ContainSubstring("is not running"))
- Expect(sshSession.ExitCode()).To(Equal(125))
+ Expect(sshSession).To(Exit(125))
})
It("ssh to running machine and check os-type", func() {
@@ -48,12 +49,12 @@ var _ = Describe("podman machine ssh", func() {
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withNow()).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
ssh := sshMachine{}
sshSession, err := mb.setName(name).setCmd(ssh.withSSHComand([]string{"cat", "/etc/os-release"})).run()
Expect(err).To(BeNil())
- Expect(sshSession.ExitCode()).To(Equal(0))
+ Expect(sshSession).To(Exit(0))
Expect(sshSession.outputToString()).To(ContainSubstring("Fedora CoreOS"))
})
})
diff --git a/pkg/machine/e2e/start_test.go b/pkg/machine/e2e/start_test.go
index 1cda0e8f1..1de66eb9a 100644
--- a/pkg/machine/e2e/start_test.go
+++ b/pkg/machine/e2e/start_test.go
@@ -4,6 +4,7 @@ import (
"github.com/containers/podman/v4/pkg/machine"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine start", func() {
@@ -22,11 +23,11 @@ var _ = Describe("podman machine start", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
s := new(startMachine)
startSession, err := mb.setCmd(s).run()
Expect(err).To(BeNil())
- Expect(startSession.ExitCode()).To(Equal(0))
+ Expect(startSession).To(Exit(0))
info, ec, err := mb.toQemuInspectInfo()
Expect(err).To(BeNil())
diff --git a/pkg/machine/e2e/stop_test.go b/pkg/machine/e2e/stop_test.go
index 5dee6a345..0c27045a6 100644
--- a/pkg/machine/e2e/stop_test.go
+++ b/pkg/machine/e2e/stop_test.go
@@ -3,6 +3,7 @@ package e2e
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
)
var _ = Describe("podman machine stop", func() {
@@ -23,24 +24,24 @@ var _ = Describe("podman machine stop", func() {
reallyLongName := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
session, err := mb.setName(reallyLongName).setCmd(&i).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(125))
+ Expect(session).To(Exit(125))
})
It("Stop running machine", func() {
i := new(initMachine)
session, err := mb.setCmd(i.withImagePath(mb.imagePath).withNow()).run()
Expect(err).To(BeNil())
- Expect(session.ExitCode()).To(Equal(0))
+ Expect(session).To(Exit(0))
stop := new(stopMachine)
// Removing a running machine should fail
stopSession, err := mb.setCmd(stop).run()
Expect(err).To(BeNil())
- Expect(stopSession.ExitCode()).To(Equal(0))
+ Expect(stopSession).To(Exit(0))
// Stopping it again should not result in an error
stopAgain, err := mb.setCmd(stop).run()
Expect(err).To(BeNil())
- Expect(stopAgain.ExitCode()).To(BeZero())
+ Expect(stopAgain).To(Exit((0)))
})
})
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 5481bad29..ccfad90f7 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -390,25 +390,9 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
if err != nil {
return false, err
}
- // Resize the disk image to input disk size
- // only if the virtualdisk size is less than
- // the given disk size
- if opts.DiskSize<<(10*3) > originalDiskSize {
- // Find the qemu executable
- cfg, err := config.Default()
- if err != nil {
- return false, err
- }
- resizePath, err := cfg.FindHelperBinary("qemu-img", true)
- if err != nil {
- return false, err
- }
- resize := exec.Command(resizePath, []string{"resize", v.getImageFile(), strconv.Itoa(int(opts.DiskSize)) + "G"}...)
- resize.Stdout = os.Stdout
- resize.Stderr = os.Stderr
- if err := resize.Run(); err != nil {
- return false, errors.Errorf("resizing image: %q", err)
- }
+
+ if err := v.resizeDisk(opts.DiskSize, originalDiskSize>>(10*3)); err != nil {
+ return false, err
}
// If the user provides an ignition file, we need to
// copy it into the conf dir
@@ -432,14 +416,14 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
return err == nil, err
}
-func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
- return nil
- }
+func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
+ // If one setting fails to be applied, the others settings will not fail and still be applied.
+ // The setting(s) that failed to be applied will have its errors returned in setErrors
+ var setErrors []error
state, err := v.State(false)
if err != nil {
- return err
+ return setErrors, err
}
if state == machine.Running {
@@ -447,26 +431,45 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
if v.Name != machine.DefaultMachineName {
suffix = " " + v.Name
}
- return errors.Errorf("cannot change setting while the vm is running, run 'podman machine stop%s' first", suffix)
+ return setErrors, errors.Errorf("cannot change settings while the vm is running, run 'podman machine stop%s' first", suffix)
}
- changeCon, err := machine.AnyConnectionDefault(v.Name, v.Name+"-root")
- if err != nil {
- return err
+ if opts.Rootful != nil && v.Rootful != *opts.Rootful {
+ if err := v.setRootful(*opts.Rootful); err != nil {
+ setErrors = append(setErrors, errors.Wrapf(err, "failed to set rootful option"))
+ } else {
+ v.Rootful = *opts.Rootful
+ }
}
- if changeCon {
- newDefault := v.Name
- if opts.Rootful {
- newDefault += "-root"
- }
- if err := machine.ChangeDefault(newDefault); err != nil {
- return err
+ if opts.CPUs != nil && v.CPUs != *opts.CPUs {
+ v.CPUs = *opts.CPUs
+ v.editCmdLine("-smp", strconv.Itoa(int(v.CPUs)))
+ }
+
+ if opts.Memory != nil && v.Memory != *opts.Memory {
+ v.Memory = *opts.Memory
+ v.editCmdLine("-m", strconv.Itoa(int(v.Memory)))
+ }
+
+ if opts.DiskSize != nil && v.DiskSize != *opts.DiskSize {
+ if err := v.resizeDisk(*opts.DiskSize, v.DiskSize); err != nil {
+ setErrors = append(setErrors, errors.Wrapf(err, "failed to resize disk"))
+ } else {
+ v.DiskSize = *opts.DiskSize
}
}
- v.Rootful = opts.Rootful
- return v.writeConfig()
+ err = v.writeConfig()
+ if err != nil {
+ setErrors = append(setErrors, err)
+ }
+
+ if len(setErrors) > 0 {
+ return setErrors, setErrors[0]
+ }
+
+ return setErrors, nil
}
// Start executes the qemu command line and forks it
@@ -1462,3 +1465,64 @@ func (v *MachineVM) getImageFile() string {
func (v *MachineVM) getIgnitionFile() string {
return v.IgnitionFilePath.GetPath()
}
+
+// resizeDisk increases the size of the machine's disk in GB.
+func (v *MachineVM) resizeDisk(diskSize uint64, oldSize uint64) error {
+ // Resize the disk image to input disk size
+ // only if the virtualdisk size is less than
+ // the given disk size
+ if diskSize < oldSize {
+ return errors.Errorf("new disk size must be larger than current disk size: %vGB", oldSize)
+ }
+
+ // Find the qemu executable
+ cfg, err := config.Default()
+ if err != nil {
+ return err
+ }
+ resizePath, err := cfg.FindHelperBinary("qemu-img", true)
+ if err != nil {
+ return err
+ }
+ resize := exec.Command(resizePath, []string{"resize", v.getImageFile(), strconv.Itoa(int(diskSize)) + "G"}...)
+ resize.Stdout = os.Stdout
+ resize.Stderr = os.Stderr
+ if err := resize.Run(); err != nil {
+ return errors.Errorf("resizing image: %q", err)
+ }
+
+ return nil
+}
+
+func (v *MachineVM) setRootful(rootful bool) error {
+ changeCon, err := machine.AnyConnectionDefault(v.Name, v.Name+"-root")
+ if err != nil {
+ return err
+ }
+
+ if changeCon {
+ newDefault := v.Name
+ if rootful {
+ newDefault += "-root"
+ }
+ err := machine.ChangeDefault(newDefault)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (v *MachineVM) editCmdLine(flag string, value string) {
+ found := false
+ for i, val := range v.CmdLine {
+ if val == flag {
+ found = true
+ v.CmdLine[i+1] = value
+ break
+ }
+ }
+ if !found {
+ v.CmdLine = append(v.CmdLine, []string{flag, value}...)
+ }
+}
diff --git a/pkg/machine/qemu/machine_test.go b/pkg/machine/qemu/machine_test.go
new file mode 100644
index 000000000..62ca6068a
--- /dev/null
+++ b/pkg/machine/qemu/machine_test.go
@@ -0,0 +1,17 @@
+package qemu
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestEditCmd(t *testing.T) {
+ vm := new(MachineVM)
+ vm.CmdLine = []string{"command", "-flag", "value"}
+
+ vm.editCmdLine("-flag", "newvalue")
+ vm.editCmdLine("-anotherflag", "anothervalue")
+
+ require.Equal(t, vm.CmdLine, []string{"command", "-flag", "newvalue", "-anotherflag", "anothervalue"})
+}
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index f57dbd299..1f1f2dcaf 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -736,28 +736,34 @@ func pipeCmdPassThrough(name string, input string, arg ...string) error {
return cmd.Run()
}
-func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
- return nil
+func (v *MachineVM) Set(_ string, opts machine.SetOptions) ([]error, error) {
+ // If one setting fails to be applied, the others settings will not fail and still be applied.
+ // The setting(s) that failed to be applied will have its errors returned in setErrors
+ var setErrors []error
+
+ if opts.Rootful != nil && v.Rootful != *opts.Rootful {
+ err := v.setRootful(*opts.Rootful)
+ if err != nil {
+ setErrors = append(setErrors, errors.Wrapf(err, "error setting rootful option"))
+ } else {
+ v.Rootful = *opts.Rootful
+ }
}
- changeCon, err := machine.AnyConnectionDefault(v.Name, v.Name+"-root")
- if err != nil {
- return err
+ if opts.CPUs != nil {
+ setErrors = append(setErrors, errors.Errorf("changing CPUs not suppored for WSL machines"))
}
- if changeCon {
- newDefault := v.Name
- if opts.Rootful {
- newDefault += "-root"
- }
- if err := machine.ChangeDefault(newDefault); err != nil {
- return err
- }
+ if opts.Memory != nil {
+ setErrors = append(setErrors, errors.Errorf("changing memory not suppored for WSL machines"))
+
}
- v.Rootful = opts.Rootful
- return v.writeConfig()
+ if opts.DiskSize != nil {
+ setErrors = append(setErrors, errors.Errorf("changing Disk Size not suppored for WSL machines"))
+ }
+
+ return setErrors, v.writeConfig()
}
func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
@@ -1362,3 +1368,22 @@ func (p *Provider) IsValidVMName(name string) (bool, error) {
func (p *Provider) CheckExclusiveActiveVM() (bool, string, error) {
return false, "", nil
}
+
+func (v *MachineVM) setRootful(rootful bool) error {
+ changeCon, err := machine.AnyConnectionDefault(v.Name, v.Name+"-root")
+ if err != nil {
+ return err
+ }
+
+ if changeCon {
+ newDefault := v.Name
+ if rootful {
+ newDefault += "-root"
+ }
+ err := machine.ChangeDefault(newDefault)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 49c387227..baec444e4 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -1133,6 +1133,8 @@ EXPOSE 2004-2005/tcp`, ALPINE)
})
It("podman run with ipam none driver", func() {
+ // Test fails, issue #13931
+ SkipIfNetavark(podmanTest)
net := "ipam" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", "--ipam-driver=none", net})
session.WaitWithDefaultTimeout()
diff --git a/test/system/110-history.bats b/test/system/110-history.bats
index 0f6d75cb3..da6f2177c 100644
--- a/test/system/110-history.bats
+++ b/test/system/110-history.bats
@@ -55,4 +55,17 @@ size | -\\\?[0-9]\\\+
}
+@test "podman image history Created" {
+ # Values from image LIST
+ run_podman image list --format '{{.CreatedSince}}--{{.CreatedAt}}' $IMAGE
+ from_imagelist="$output"
+ assert "$from_imagelist" =~ "^[0-9].* ago--[0-9]+-[0-9]+-[0-9]+ [0-9:]+ " \
+ "CreatedSince and CreatedAt look reasonable"
+
+ # Values from image HISTORY
+ run_podman image history --format '{{.CreatedSince}}--{{.CreatedAt}}' $IMAGE
+ assert "${lines[0]}" == "$from_imagelist" \
+ "CreatedSince and CreatedAt from image history should == image list"
+}
+
# vim: filetype=sh