Skip to content
Closed
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
102 changes: 102 additions & 0 deletions .github/workflows/windows-acceptance-basic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# This workflow runs the command test suite on GitHub-based Windows Server runners.
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.

Could you explain pros/cons compared to the current Cirrus CI ?

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.

The main pro would be the fact the containerd repo has a workflow using the same GitHub runner images to run the integration tests, so we could crossref any errors we're seeing to any bugs which may have gotten into containerd without having to worry about differences in the runner's OS/patch number as much.

I don't think there are any cons to having both running in parallel, so I could also update the Cirrus config to run the tests on 2022 as well if needed. (currently looks like Cirrus only has images based on 2019 OOB so we'd have to setup a custom 2022 image for it though)

name: Windows Basic Acceptance

on:
workflow_dispatch:
push:
branches:
- master
pull_request:
branches:
- master

env:
GO_VERSION: '1.19'

# NOTE: some tests require that the version string returned
# by the server be SemVer-compatible
CONTAINERD_VERSION: '1.6.8'

jobs:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be better to have a test arg like docker.

go test -exec sudo -v ./cmd/nerdctl/... -args -test.target=docker

and if a test is windows compatible it will run automatically

acceptance-basic:
name: Windows Basic Acceptance
runs-on: ${{ matrix.os }}
timeout-minutes: 50
env:
GOTEST: gotestsum --

strategy:
fail-fast: false
matrix:
os: [windows-2019, windows-2022]

defaults:
run:
shell: powershell
working-directory: 'src\github.com\containerd\nerdctl'

steps:

- uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}

- uses: actions/checkout@v2
with:
path: src/github.com/containerd/nerdctl

#
# Build and start containerd.
#
- uses: actions/checkout@v2
with:
repository: 'containerd/containerd'
path: 'src\github.com\containerd\containerd'

- uses: actions/checkout@v2
with:
path: src/github.com/containerd/nerdctl

- name: Install Dev Tools
run: bash script/setup/install-dev-tools
working-directory: src/github.com/containerd/containerd

- name: Setup CNI
env:
CGO_ENABLED: 1
GOPATH: ${{ github.workspace }}
run: bash script/setup/install-cni-windows
working-directory: src/github.com/containerd/containerd

- name: Build containerd
shell: bash
env:
CGO_ENABLED: 1
GOPATH: ${{ github.workspace }}
run: |
mingw32-make.exe binaries
working-directory: src/github.com/containerd/containerd

- name: Start containerd
env:
GOPATH: ${{ github.workspace }}
run: |
Set-Content ./containerd-log.txt ""
./bin/containerd.exe --version
./bin/containerd.exe --log-level=debug --log-file=$(pwd)\containerd-log.txt --service-name containerd --register-service
Set-Service -StartupType Automatic containerd
start-service containerd
get-process | sls containerd
start-sleep 60
working-directory: src/github.com/containerd/containerd

- name: Run Tests
run: |
go install ./cmd/nerdctl/
go test -v ./cmd/...

- name: containerd logs
if: always()
run: |
Get-Content ./containerd-log.txt
working-directory: src/github.com/containerd/containerd
11 changes: 0 additions & 11 deletions cmd/nerdctl/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,17 +204,6 @@ COPY %s /`,
assert.Equal(t, string(data), testContent)
}

func createBuildContext(dockerfile string) (string, error) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why remove this?

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.

I had moved it to image_testing_utils.go since it is also called in a couple of non-build-related tests.

tmpDir, err := os.MkdirTemp("", "nerdctl-build-test")
if err != nil {
return "", err
}
if err = os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
return "", err
}
return tmpDir, nil
}

func TestBuildWithIIDFile(t *testing.T) {
t.Parallel()
testutil.RequiresBuild(t)
Expand Down
7 changes: 0 additions & 7 deletions cmd/nerdctl/image_convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@
package main

import (
"runtime"
"testing"

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

func TestImageConvertEStargz(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("no windows support yet")
}
testutil.DockerIncompatible(t)
t.Parallel()
base := testutil.NewBase(t)
Expand All @@ -39,9 +35,6 @@ func TestImageConvertEStargz(t *testing.T) {
}

func TestImageConvertZstdChunked(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("no windows support yet")
}
testutil.DockerIncompatible(t)
base := testutil.NewBase(t)
convertedImage := testutil.Identifier(t) + ":zstdchunked"
Expand Down
79 changes: 10 additions & 69 deletions cmd/nerdctl/image_encrypt_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,82 +17,23 @@
package main

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/containerd/nerdctl/pkg/buildkitutil"
"github.com/containerd/nerdctl/pkg/testutil"
"github.com/containerd/nerdctl/pkg/testutil/testregistry"
"gotest.tools/v3/assert"
)

type jweKeyPair struct {
prv string
pub string
cleanup func()
}

func newJWEKeyPair(t testing.TB) *jweKeyPair {
if _, err := exec.LookPath("openssl"); err != nil {
t.Skip(err)
}
td, err := os.MkdirTemp(t.TempDir(), "jwe-key-pair")
assert.NilError(t, err)
prv := filepath.Join(td, "mykey.pem")
pub := filepath.Join(td, "mypubkey.pem")
cmds := [][]string{
// Exec openssl commands to ensure that nerdctl is compatible with the output of openssl commands.
// Do NOT refactor this function to use "crypto/rsa" stdlib.
{"openssl", "genrsa", "-out", prv},
{"openssl", "rsa", "-in", prv, "-pubout", "-out", pub},
}
for _, f := range cmds {
cmd := exec.Command(f[0], f[1:]...)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("failed to run %v: %v (%q)", cmd.Args, err, string(out))
}
}
return &jweKeyPair{
prv: prv,
pub: pub,
cleanup: func() {
_ = os.RemoveAll(td)
},
}
}

func rmiAll(base *testutil.Base) {
imageIDs := base.Cmd("images", "--no-trunc", "-a", "-q").OutLines()
base.Cmd(append([]string{"rmi", "-f"}, imageIDs...)...).AssertOK()
if _, err := buildkitutil.GetBuildkitHost(testutil.Namespace); err == nil {
base.Cmd("builder", "prune").AssertOK()
// Returns the list of shell commands to be run for generating public/private RSA keys
// with the given filepaths to be used during the encryption/decryption tests
func keyGenCmdsF(prvPath string, pubPath string) [][]string {
// Exec openssl commands to ensure that nerdctl is compatible with the output of openssl commands.
// Do NOT refactor this function to use "crypto/rsa" stdlib.
return [][]string{
{"openssl", "genrsa", "-out", prvPath},
{"openssl", "rsa", "-in", prvPath, "-pubout", "-out", pubPath},
}
}

func TestImageEncryptJWE(t *testing.T) {
testutil.DockerIncompatible(t)
keyPair := newJWEKeyPair(t)
defer keyPair.cleanup()
base := testutil.NewBase(t)
tID := testutil.Identifier(t)
reg := testregistry.NewPlainHTTP(base, 5000)
defer reg.Cleanup()
base.Cmd("pull", testutil.CommonImage).AssertOK()
encryptImageRef := fmt.Sprintf("127.0.0.1:%d/%s:encrypted", reg.ListenPort, tID)
defer base.Cmd("rmi", encryptImageRef).Run()
base.Cmd("image", "encrypt", "--recipient=jwe:"+keyPair.pub, testutil.CommonImage, encryptImageRef).AssertOK()
base.Cmd("image", "inspect", "--mode=native", "--format={{len .Index.Manifests}}", encryptImageRef).AssertOutExactly("1\n")
base.Cmd("image", "inspect", "--mode=native", "--format={{json .Manifest.Layers}}", encryptImageRef).AssertOutContains("org.opencontainers.image.enc.keys.jwe")
base.Cmd("push", encryptImageRef).AssertOK()
// remove all local images (in the nerdctl-test namespace), to ensure that we do not have blobs of the original image.
rmiAll(base)
base.Cmd("pull", encryptImageRef).AssertFail() // defaults to --unpack=true, and fails due to missing prv key
base.Cmd("pull", "--unpack=false", encryptImageRef).AssertOK()
decryptImageRef := tID + ":decrypted"
defer base.Cmd("rmi", decryptImageRef).Run()
base.Cmd("image", "decrypt", "--key="+keyPair.pub, encryptImageRef, decryptImageRef).AssertFail() // decryption needs prv key, not pub key
base.Cmd("image", "decrypt", "--key="+keyPair.prv, encryptImageRef, decryptImageRef).AssertOK()
keyPair := newJWEKeyPair(t, keyGenCmdsF)
testImageEncryptJWE(t, testutil.CommonImage, keyPair)
}
92 changes: 92 additions & 0 deletions cmd/nerdctl/image_encrypt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
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 (
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/containerd/nerdctl/pkg/buildkitutil"
"github.com/containerd/nerdctl/pkg/testutil"
"github.com/containerd/nerdctl/pkg/testutil/testregistry"
"gotest.tools/v3/assert"
)

type jweKeyPair struct {
prv string
pub string
cleanup func()
}

func newJWEKeyPair(t testing.TB, keyGenCmdsF func(string, string) [][]string) *jweKeyPair {
if _, err := exec.LookPath("openssl"); err != nil {
t.Skip(err)
}
td, err := os.MkdirTemp(t.TempDir(), "jwe-key-pair")
assert.NilError(t, err)
prv := filepath.Join(td, "mykey.pem")
pub := filepath.Join(td, "mypubkey.pem")
cmds := keyGenCmdsF(prv, pub)
for _, f := range cmds {
cmd := exec.Command(f[0], f[1:]...)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("failed to run %v: %v (%q)", cmd.Args, err, string(out))
}
}
return &jweKeyPair{
prv: prv,
pub: pub,
cleanup: func() {
_ = os.RemoveAll(td)
},
}
}

func rmiAll(base *testutil.Base) {
imageIDs := base.Cmd("images", "--no-trunc", "-a", "-q").OutLines()
base.Cmd(append([]string{"rmi", "-f"}, imageIDs...)...).AssertOK()
if _, err := buildkitutil.GetBuildkitHost(testutil.Namespace); err == nil {
base.Cmd("builder", "prune").AssertOK()
}
}

func testImageEncryptJWE(t *testing.T, testImage string, keyPair *jweKeyPair) {
testutil.DockerIncompatible(t)
defer keyPair.cleanup()
base := testutil.NewBase(t)
tID := testutil.Identifier(t)
reg := testregistry.NewPlainHTTP(base, 5000)
defer reg.Cleanup()
base.Cmd("pull", testImage).AssertOK()
encryptImageRef := fmt.Sprintf("127.0.0.1:%d/%s:encrypted", reg.ListenPort, tID)
defer base.Cmd("rmi", encryptImageRef).Run()
base.Cmd("image", "encrypt", "--recipient=jwe:"+keyPair.pub, testImage, encryptImageRef).AssertOK()
base.Cmd("image", "inspect", "--mode=native", "--format={{len .Index.Manifests}}", encryptImageRef).AssertOutExactly("1\n")
base.Cmd("image", "inspect", "--mode=native", "--format={{json .Manifest.Layers}}", encryptImageRef).AssertOutContains("org.opencontainers.image.enc.keys.jwe")
base.Cmd("push", encryptImageRef).AssertOK()
// remove all local images (in the nerdctl-test namespace), to ensure that we do not have blobs of the original image.
rmiAll(base)
base.Cmd("pull", encryptImageRef).AssertFail() // defaults to --unpack=true, and fails due to missing prv key
base.Cmd("pull", "--unpack=false", encryptImageRef).AssertOK()
decryptImageRef := tID + ":decrypted"
defer base.Cmd("rmi", decryptImageRef).Run()
base.Cmd("image", "decrypt", "--key="+keyPair.pub, encryptImageRef, decryptImageRef).AssertFail() // decryption needs prv key, not pub key
base.Cmd("image", "decrypt", "--key="+keyPair.prv, encryptImageRef, decryptImageRef).AssertOK()
}
42 changes: 42 additions & 0 deletions cmd/nerdctl/image_encrypt_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
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 (
"fmt"
"testing"

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

// Returns the list of shell commands to be run for generating public/private RSA keys
// with the given filepaths to be used during the encryption/decryption tests
func keyGenCmdsF(prvPath string, pubPath string) [][]string {
// Exec commands to ensure that nerdctl is compatible with the output of openssl commands.
// Do NOT refactor this function to use "crypto/rsa" stdlib.
return [][]string{
// {"openssl", "genrsa", "-out", prvPath},
{"ssh-keygen.exe", "-t", "rsa", "-b", "2048", "-q", "-N", "''", "-f", prvPath},
// NOTE: redirect will cause `pubPath` to be UTF-16-LE which is necessary for the test:
{"powershell.exe", fmt.Sprintf("{ssh-keygen.exe -e -f %q -y -m PEM > %q}", prvPath, pubPath)},
}
}

func TestImageEncryptJWE(t *testing.T) {
keyPair := newJWEKeyPair(t, keyGenCmdsF)
testImageEncryptJWE(t, testutil.CommonImage, keyPair)
}
Loading