Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/test-kube.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# This pipeline purpose is solely meant to run a subset of our test suites against a kube cluster
name: kube

on:
push:
branches:
- main
- 'release/**'
pull_request:
paths-ignore:
- '**.md'

env:
ROOTFUL: true

jobs:
linux:
runs-on: "ubuntu-24.04"
timeout-minutes: 40
steps:
- uses: actions/checkout@v4.1.7
with:
fetch-depth: 1
- name: "Run Kube integration tests"
run: |
./hack/build-integration-kube.sh
sudo ./_output/nerdctl exec nerdctl-test-control-plane bash -c -- 'export TMPDIR="$HOME"/tmp; mkdir -p "$TMPDIR"; cd /nerdctl-source; /usr/local/go/bin/go test ./cmd/nerdctl/ -test.only-kube'
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -284,14 +284,14 @@ jobs:
timeout_minutes: 30
max_attempts: 2
retry_on: error
command: go test -timeout 20m -v -exec sudo ./cmd/nerdctl/... -args -test.target=docker -test.kill-daemon
command: go test -timeout 20m -v -exec sudo ./cmd/nerdctl/... -args -test.target=docker -test.allow-kill-daemon
- name: "Ensure that the IPv6 integration test suite is compatible with Docker"
uses: nick-fields/retry@v3
with:
timeout_minutes: 30
max_attempts: 2
retry_on: error
command: go test -timeout 20m -v -exec sudo ./cmd/nerdctl/... -args -test.target=docker -test.kill-daemon -test.ipv6
command: go test -timeout 20m -v -exec sudo ./cmd/nerdctl/... -args -test.target=docker -test.allow-kill-daemon -test.only-ipv6

test-integration-windows:
runs-on: windows-2022
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ RUN curl -o nydus-static.tgz -fsSL --proto '=https' --tlsv1.2 "https://github.co
mv nydus-static/nydus-image nydus-static/nydusd nydus-static/nydusify /usr/bin/ && \
rm nydus-static.tgz
CMD ["gotestsum", "--format=testname", "--rerun-fails=2", "--packages=github.com/containerd/nerdctl/v2/cmd/nerdctl/...", \
"--", "-timeout=60m", "-args", "-test.kill-daemon"]
"--", "-timeout=60m", "-args", "-test.allow-kill-daemon"]

FROM test-integration AS test-integration-rootless
# Install SSH for creating systemd user session.
Expand All @@ -345,7 +345,7 @@ COPY ./Dockerfile.d/test-integration-rootless.sh /
CMD ["/test-integration-rootless.sh", \
"gotestsum", "--format=testname", "--rerun-fails=2", "--raw-command", \
"--", "/usr/local/go/bin/go", "tool", "test2json", "-t", "-p", "github.com/containerd/nerdctl/v2/cmd/nerdctl", \
"/usr/local/bin/nerdctl.test", "-test.v", "-test.timeout=60m", "-test.kill-daemon"]
"/usr/local/bin/nerdctl.test", "-test.v", "-test.timeout=60m", "-test.allow-kill-daemon"]

# test for CONTAINERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns
FROM test-integration-rootless AS test-integration-rootless-port-slirp4netns
Expand All @@ -354,6 +354,6 @@ RUN chown -R rootless:rootless /home/rootless/.config

FROM test-integration AS test-integration-ipv6
CMD ["gotestsum", "--format=testname", "--rerun-fails=2", "--packages=github.com/containerd/nerdctl/v2/cmd/nerdctl/...", \
"--", "-timeout=60m", "-args", "-test.kill-daemon", "-test.ipv6"]
"--", "-timeout=60m", "-args", "-test.allow-kill-daemon", "-test.only-ipv6"]

FROM base AS demo
70 changes: 70 additions & 0 deletions cmd/nerdctl/container_commit_linux_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
Copyright The containerd Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"strings"
"testing"

"gotest.tools/v3/icmd"

"github.com/containerd/nerdctl/v2/pkg/testutil"
)

func TestKubeCommitPush(t *testing.T) {
t.Parallel()

base := testutil.NewBaseForKube(t)
tID := testutil.Identifier(t)

var containerID string

setup := func() {
testutil.KubectlHelper(base, "run", "--image", testutil.CommonImage, tID, "--", "sleep", "Inf").
AssertOK()

testutil.KubectlHelper(base, "wait", "pod", tID, "--for=condition=ready", "--timeout=1m").
AssertOK()

testutil.KubectlHelper(base, "exec", tID, "--", "mkdir", "-p", "/tmp/whatever").
AssertOK()

cmd := testutil.KubectlHelper(base, "get", "pods", tID, "-o", "jsonpath={ .status.containerStatuses[0].containerID }")
cmd.Run()
containerID = strings.TrimPrefix(cmd.Out(), "containerd://")
}

tearDown := func() {
testutil.KubectlHelper(base, "delete", "pod", tID).Run()
Comment thread
apostasie marked this conversation as resolved.
}

tearDown()
Comment thread
apostasie marked this conversation as resolved.
t.Cleanup(tearDown)
setup()

t.Run("test commit / push on Kube (https://github.com/containerd/nerdctl/issues/827)", func(t *testing.T) {
t.Log("This test is meant to verify that we can commit / push an image from a pod." +
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
t.Log("This test is meant to verify that we can commit / push an image from a pod." +
t.Log("This test is meant to verify that we can commit / push an image that belongs to containerd `k8s` namespace." +

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW it is a nerdctl issue not only a kube

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean issue #827 can be reproduced in a non-kube environment?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a separate ticket, or do you have a simple reproducer for it that does not involve kube?

"Currently, this is broken, hence the test assumes it will fail. Once the problem is fixed, we should just" +
"change the expectation to 'success'.")

base.Cmd("commit", containerID, "registry.example.com/my-app:v1").AssertOK()
base.Cmd("push", "registry.example.com/my-app:v1").Assert(icmd.Expected{
ExitCode: 1,
Err: "failed to create a tmp single-platform image",
})
})
}
2 changes: 1 addition & 1 deletion cmd/nerdctl/container_run_restart_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestRunRestart(t *testing.T) {
}
base := testutil.NewBase(t)
if !base.DaemonIsKillable {
t.Skip("daemon is not killable (hint: set \"-test.kill-daemon\")")
t.Skip("daemon is not killable (hint: set \"-test.allow-kill-daemon\")")
}
t.Log("NOTE: this test may take a while")

Expand Down
150 changes: 6 additions & 144 deletions hack/build-integration-canary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

# shellcheck disable=SC2034,SC2015
set -o errexit -o errtrace -o functrace -o nounset -o pipefail
root="$(cd "$(dirname "${BASH_SOURCE[0]:-$PWD}")" 2>/dev/null 1>&2 && pwd)"
readonly root
# shellcheck source=/dev/null
. "$root/scripts/lib.sh"

######################
# Definitions
Expand Down Expand Up @@ -67,141 +71,6 @@ STARGZ_SNAPSHOTTER_CHECKSUM=linux
# We specifically want the static ones
TINI_CHECKSUM=static


Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sharing that with the new kube script (moved to lib.sh)

######################
# Lib
######################

# Simple logger
readonly LOG_LEVEL_DEBUG=0
readonly LOG_LEVEL_INFO=1
readonly LOG_LEVEL_WARNING=2
readonly LOG_LEVEL_ERROR=3

readonly LOG_COLOR_BLACK=0
readonly LOG_COLOR_RED=1
readonly LOG_COLOR_GREEN=2
readonly LOG_COLOR_YELLOW=3
readonly LOG_COLOR_BLUE=4
readonly LOG_COLOR_MAGENTA=5
readonly LOG_COLOR_CYAN=6
readonly LOG_COLOR_WHITE=7
readonly LOG_COLOR_DEFAULT=9

readonly LOG_STYLE_DEBUG=( setaf "$LOG_COLOR_WHITE" )
readonly LOG_STYLE_INFO=( setaf "$LOG_COLOR_GREEN" )
readonly LOG_STYLE_WARNING=( setaf "$LOG_COLOR_YELLOW" )
readonly LOG_STYLE_ERROR=( setaf "$LOG_COLOR_RED" )

_log::log(){
local level
local style
local numeric_level
local message="$2"

level="$(printf "%s" "$1" | tr '[:lower:]' '[:upper:]')"
numeric_level="$(printf "LOG_LEVEL_%s" "$level")"
style="LOG_STYLE_${level}[@]"

[ "${!numeric_level}" -ge "$LOG_LEVEL" ] || return 0

[ ! "$TERM" ] || [ ! -t 2 ] || >&2 tput "${!style}" 2>/dev/null || true
>&2 printf "[%s] %s: %s\n" "$(date 2>/dev/null || true)" "$(printf "%s" "$level" | tr '[:lower:]' '[:upper:]')" "$message"
[ ! "$TERM" ] || [ ! -t 2 ] || >&2 tput op 2>/dev/null || true
}

log::init(){
local _ll
# Default log to warning if unspecified
_ll="$(printf "LOG_LEVEL_%s" "${NERDCTL_CI_LOG_LEVEL:-warning}" | tr '[:lower:]' '[:upper:]')"
# Default to 3 (warning) if unrecognized
LOG_LEVEL="${!_ll:-3}"
}

log::debug(){
_log::log debug "$@"
}

log::info(){
_log::log info "$@"
}

log::warning(){
_log::log warning "$@"
}

log::error(){
_log::log error "$@"
}

# Helpers
host::require(){
local binary="$1"
command -v "$binary" >/dev/null || {
log::error "You need $binary for this script to work, and it cannot be found in your path"
exit 1
}
}

fs::mktemp(){
mktemp -dq "${TMPDIR:-/tmp}/$prefix.XXXXXX" 2>/dev/null || mktemp -dq || {
log::error "Failed to create temporary directory"
exit 1
}
}

http::get(){
local args=(curl --proto '=https' --tlsv1.2 -fsSL)
args+=("$@")

log::debug "${args[*]}"
"${args[@]}"
}

http::checksum(){
local urls=("$@")
local url

local prefix="nerdctl-checksum"

local temp
temp="$(fs::mktemp)"

for url in "${urls[@]}"; do
http::get -o "$temp/${url##*/}" "$url"
done

cd "$temp"
shasum -a 256 ./*
cd - >/dev/null || true
}

# Github API helpers
# Set GITHUB_TOKEN to use authenticated requests to workaround limitations
github::request(){
local endpoint="$1"
local args=(
-H "Accept: application/vnd.github+json"
-H "X-GitHub-Api-Version: 2022-11-28"
)

[ "${GITHUB_TOKEN:-}" == "" ] || args+=(-H "Authorization: Bearer $GITHUB_TOKEN")

http::get "${args[@]}" https://api.github.com/"$endpoint"
}

github::tags::getlatest(){
local repo="$1"
github::request "repos/$repo/tags" |
jq -rc .[0].name
}

github::releases::latest(){
local repo="$1"
github::request "repos/$repo/releases" |
jq -rc .[]
}

version::compare(){
local raw_version_fd="$1"
local parsed
Expand Down Expand Up @@ -304,7 +173,7 @@ latest::release(){
higher_data="$line"
higher_readable="$(echo "$line" | jq -rc .name | sed -E 's/(.*[ ])?(v?[0-9][0-9.a-z-]+).*/\2/')"
fi
done < <(github::releases::latest "$repo")
done < <(github::releases "$repo")

log::info " >>> latest release detected: $higher_readable"
}
Expand All @@ -314,7 +183,7 @@ latest::tag(){
local repo="$1"

log::info "Analyzing tags for $repo"
github::tags::getlatest "$repo"
github::tags::latest "$repo"
}

# Once a latest release has been retrieved for a given project, you can get the url to the asset matching OS and ARCH
Expand Down Expand Up @@ -342,13 +211,6 @@ assets::get(){
}
}

log::init
host::require jq
host::require curl
host::require shasum
host::require docker
host::require tput

######################
# Script
######################
Expand Down
Loading