mirror of
https://github.com/containers/podman.git
synced 2025-06-23 18:59:30 +08:00
Merge pull request #13450 from jwhonce/bz/2052697
Exit code change BZ #2052697
This commit is contained in:
@ -210,6 +210,10 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := shutdown.Register("libpod", func(sig os.Signal) error {
|
if err := shutdown.Register("libpod", func(sig os.Signal) error {
|
||||||
|
// For `systemctl stop podman.service` support, exit code should be 0
|
||||||
|
if sig == syscall.SIGTERM {
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
return nil
|
return nil
|
||||||
}); err != nil && errors.Cause(err) != shutdown.ErrHandlerExists {
|
}); err != nil && errors.Cause(err) != shutdown.ErrHandlerExists {
|
||||||
|
@ -280,7 +280,7 @@ t DELETE containers/$cid_top 204
|
|||||||
t POST containers/create \
|
t POST containers/create \
|
||||||
Image=$ENV_WORKDIR_IMG \
|
Image=$ENV_WORKDIR_IMG \
|
||||||
WorkingDir=/dataDir \
|
WorkingDir=/dataDir \
|
||||||
StopSignal=9 \
|
StopSignal=\"9\" \
|
||||||
201 \
|
201 \
|
||||||
.Id~[0-9a-f]\\{64\\}
|
.Id~[0-9a-f]\\{64\\}
|
||||||
cid=$(jq -r '.Id' <<<"$output")
|
cid=$(jq -r '.Id' <<<"$output")
|
||||||
|
@ -194,8 +194,16 @@ function jsonify() {
|
|||||||
local rhs
|
local rhs
|
||||||
IFS='=' read lhs rhs <<<"$i"
|
IFS='=' read lhs rhs <<<"$i"
|
||||||
|
|
||||||
# If right-hand side already includes double quotes, do nothing
|
if [[ $rhs =~ \" || $rhs == true || $rhs == false || $rhs =~ ^-?[0-9]+$ ]]; then
|
||||||
if [[ ! $rhs =~ \" ]]; then
|
# rhs has been pre-formatted for JSON or a non-string, do not change it
|
||||||
|
:
|
||||||
|
elif [[ $rhs == False ]]; then
|
||||||
|
# JSON boolean is lowercase only
|
||||||
|
rhs=false
|
||||||
|
elif [[ $rhs == True ]]; then
|
||||||
|
# JSON boolean is lowercase only
|
||||||
|
rhs=true
|
||||||
|
else
|
||||||
rhs="\"${rhs}\""
|
rhs="\"${rhs}\""
|
||||||
fi
|
fi
|
||||||
settings_out+=("\"${lhs}\":${rhs}")
|
settings_out+=("\"${lhs}\":${rhs}")
|
||||||
@ -241,26 +249,30 @@ function t() {
|
|||||||
# entrypoint path can include a descriptive comment; strip it off
|
# entrypoint path can include a descriptive comment; strip it off
|
||||||
path=${path%% *}
|
path=${path%% *}
|
||||||
|
|
||||||
# path may include JSONish params that curl will barf on; url-encode them
|
local url=$path
|
||||||
path="${path//'['/%5B}"
|
if ! [[ $path =~ ^'http://' ]]; then
|
||||||
path="${path//']'/%5D}"
|
# path may include JSONish params that curl will barf on; url-encode them
|
||||||
path="${path//'{'/%7B}"
|
path="${path//'['/%5B}"
|
||||||
path="${path//'}'/%7D}"
|
path="${path//']'/%5D}"
|
||||||
path="${path//':'/%3A}"
|
path="${path//'{'/%7B}"
|
||||||
|
path="${path//'}'/%7D}"
|
||||||
|
path="${path//':'/%3A}"
|
||||||
|
|
||||||
|
# If given path begins with /, use it as-is; otherwise prepend /version/
|
||||||
|
url=http://$HOST:$PORT
|
||||||
|
case "$path" in
|
||||||
|
/*) url="$url$path" ;;
|
||||||
|
libpod/*) url="$url/v4.0.0/$path" ;;
|
||||||
|
*) url="$url/v1.41/$path" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
# curl -X HEAD but without --head seems to wait for output anyway
|
# curl -X HEAD but without --head seems to wait for output anyway
|
||||||
if [[ $method == "HEAD" ]]; then
|
if [[ $method == "HEAD" ]]; then
|
||||||
curl_args="--head"
|
curl_args="--head"
|
||||||
fi
|
fi
|
||||||
local expected_code=$1; shift
|
|
||||||
|
|
||||||
# If given path begins with /, use it as-is; otherwise prepend /version/
|
local expected_code=$1; shift
|
||||||
local url=http://$HOST:$PORT
|
|
||||||
case "$path" in
|
|
||||||
/*) url="$url$path" ;;
|
|
||||||
libpod/*) url="$url/v4.0.0/$path" ;;
|
|
||||||
*) url="$url/v1.41/$path" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Log every action we do
|
# Log every action we do
|
||||||
echo "-------------------------------------------------------------" >>$LOG
|
echo "-------------------------------------------------------------" >>$LOG
|
||||||
|
107
test/e2e/systemd_activate_test.go
Normal file
107
test/e2e/systemd_activate_test.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
testUtils "github.com/containers/podman/v4/test/utils"
|
||||||
|
podmanUtils "github.com/containers/podman/v4/utils"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
. "github.com/onsi/gomega/gexec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Systemd activate", func() {
|
||||||
|
var tempDir string
|
||||||
|
var err error
|
||||||
|
var podmanTest *PodmanTestIntegration
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
tempDir, err = testUtils.CreateTempDirInTempDir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
podmanTest = PodmanTestCreate(tempDir)
|
||||||
|
podmanTest.Setup()
|
||||||
|
podmanTest.SeedImages()
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
podmanTest.Cleanup()
|
||||||
|
processTestResult(CurrentGinkgoTestDescription())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("stop podman.service", func() {
|
||||||
|
SkipIfRemote("Testing stopped service requires both podman and podman-remote binaries")
|
||||||
|
|
||||||
|
activate, err := exec.LookPath("systemd-socket-activate")
|
||||||
|
if err != nil {
|
||||||
|
activate = "/usr/bin/systemd-socket-activate"
|
||||||
|
}
|
||||||
|
stat, err := os.Stat(activate)
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, fs.ErrNotExist):
|
||||||
|
Skip(activate + " required for systemd activation tests")
|
||||||
|
case stat.Mode()&0111 == 0:
|
||||||
|
Skip("Unable to execute " + activate)
|
||||||
|
case err != nil:
|
||||||
|
Skip(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// systemd-socket-activate does not support DNS lookups
|
||||||
|
host := "127.0.0.1"
|
||||||
|
port, err := podmanUtils.GetRandomPort()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
activateSession := testUtils.StartSystemExec(activate, []string{
|
||||||
|
fmt.Sprintf("--listen=%s:%d", host, port),
|
||||||
|
podmanTest.PodmanBinary,
|
||||||
|
"--root=" + filepath.Join(tempDir, "server_root"),
|
||||||
|
"system", "service",
|
||||||
|
"--time=0",
|
||||||
|
})
|
||||||
|
Expect(activateSession.Exited).ShouldNot(Receive(), "Failed to start podman service")
|
||||||
|
|
||||||
|
// Curried functions for specialized podman calls
|
||||||
|
podmanRemote := func(args ...string) *testUtils.PodmanSession {
|
||||||
|
args = append([]string{"--url", fmt.Sprintf("tcp://%s:%d", host, port)}, args...)
|
||||||
|
return testUtils.SystemExec(podmanTest.RemotePodmanBinary, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
podman := func(args ...string) *testUtils.PodmanSession {
|
||||||
|
args = append([]string{"--root", filepath.Join(tempDir, "server_root")}, args...)
|
||||||
|
return testUtils.SystemExec(podmanTest.PodmanBinary, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
containerName := "top_" + testUtils.RandomString(8)
|
||||||
|
apiSession := podmanRemote(
|
||||||
|
"create", "--tty", "--name", containerName, "--entrypoint", "top",
|
||||||
|
"quay.io/libpod/alpine_labels:latest",
|
||||||
|
)
|
||||||
|
Expect(apiSession).Should(Exit(0))
|
||||||
|
|
||||||
|
apiSession = podmanRemote("start", containerName)
|
||||||
|
Expect(apiSession).Should(Exit(0))
|
||||||
|
|
||||||
|
apiSession = podmanRemote("inspect", "--format={{.State.Running}}", containerName)
|
||||||
|
Expect(apiSession).Should(Exit(0))
|
||||||
|
Expect(apiSession.OutputToString()).To(Equal("true"))
|
||||||
|
|
||||||
|
// Emulate 'systemd stop podman.service'
|
||||||
|
activateSession.Signal(syscall.SIGTERM)
|
||||||
|
time.Sleep(2)
|
||||||
|
Eventually(activateSession).Should(Exit(0))
|
||||||
|
|
||||||
|
abiSession := podman("inspect", "--format={{.State.Running}}", containerName)
|
||||||
|
Expect(abiSession).To(Exit(0))
|
||||||
|
Expect(abiSession.OutputToString()).To(Equal("true"))
|
||||||
|
})
|
||||||
|
})
|
@ -368,6 +368,7 @@ func CreateTempDirInTempDir() (string, error) {
|
|||||||
// SystemExec is used to exec a system command to check its exit code or output
|
// SystemExec is used to exec a system command to check its exit code or output
|
||||||
func SystemExec(command string, args []string) *PodmanSession {
|
func SystemExec(command string, args []string) *PodmanSession {
|
||||||
c := exec.Command(command, args...)
|
c := exec.Command(command, args...)
|
||||||
|
fmt.Println("Execing " + c.String() + "\n")
|
||||||
session, err := Start(c, GinkgoWriter, GinkgoWriter)
|
session, err := Start(c, GinkgoWriter, GinkgoWriter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
|
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
|
||||||
@ -379,6 +380,7 @@ func SystemExec(command string, args []string) *PodmanSession {
|
|||||||
// StartSystemExec is used to start exec a system command
|
// StartSystemExec is used to start exec a system command
|
||||||
func StartSystemExec(command string, args []string) *PodmanSession {
|
func StartSystemExec(command string, args []string) *PodmanSession {
|
||||||
c := exec.Command(command, args...)
|
c := exec.Command(command, args...)
|
||||||
|
fmt.Println("Execing " + c.String() + "\n")
|
||||||
session, err := Start(c, GinkgoWriter, GinkgoWriter)
|
session, err := Start(c, GinkgoWriter, GinkgoWriter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
|
Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
|
||||||
|
Reference in New Issue
Block a user