Skip to content

Commit 47ceb62

Browse files
Merge pull request #629 from austinvazquez/remote-snapshotter-integ-test
add: integration test for remote snapshotter
2 parents 5d657a7 + 7509838 commit 47ceb62

File tree

13 files changed

+437
-22
lines changed

13 files changed

+437
-22
lines changed

.buildkite/pipeline.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ steps:
7373
- make test-in-docker
7474
timeout_in_minutes: 10
7575

76+
- label: ":running: snapshotter isolated tests"
77+
agents:
78+
queue: "${BUILDKITE_AGENT_META_DATA_QUEUE:-default}"
79+
distro: "${BUILDKITE_AGENT_META_DATA_DISTRO}"
80+
hostname: "${BUILDKITE_AGENT_META_DATA_HOSTNAME}"
81+
env:
82+
DOCKER_IMAGE_TAG: "$BUILDKITE_BUILD_NUMBER"
83+
NUMBER_OF_VMS: 10
84+
EXTRAGOARGS: "-v -count=1 -race"
85+
artifact_paths:
86+
- "snapshotter/logs/*"
87+
command:
88+
- make -C snapshotter integ-test
89+
7690
- label: ":running: runtime isolated tests"
7791
agents:
7892
queue: "${BUILDKITE_AGENT_META_DATA_QUEUE:-default}"

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.idea/
22
bin/
3+
tmp/
34
runtime/logs
45
*stamp
56
default-vmlinux.bin

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ $(INTEG_TEST_SUBDIRS): test-images
187187

188188
test-images: test-images-stamp
189189

190-
test-images-stamp: | image firecracker-containerd-test-image
190+
test-images-stamp: | image image-stargz firecracker-containerd-test-image
191191
touch $@
192192

193193
firecracker-containerd-test-image: all-in-docker firecracker runc test-cni-bins cni-bins default-vmlinux kernel

internal/integtest/runtime.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,31 @@ package integtest
1515

1616
import (
1717
"os"
18+
"strconv"
1819
)
1920

2021
const (
2122
// FirecrackerRuntime is the Firecracker-containerd runtime
2223
FirecrackerRuntime = "aws.firecracker"
2324

2425
containerdSockPathEnvVar = "CONTAINERD_SOCKET"
26+
numberOfVmsEnvVar = "NUMBER_OF_VMS"
2527
)
2628

2729
var (
2830
// ContainerdSockPath is the default Firecracker-containerd socket path
2931
ContainerdSockPath = "/run/firecracker-containerd/containerd.sock"
32+
33+
// NumberOfVms is the number of VMs used in integration testing set
34+
// by either environment variable read or defaults to 5 VMs.
35+
NumberOfVms = 5
3036
)
3137

3238
func init() {
3339
if v := os.Getenv(containerdSockPathEnvVar); v != "" {
3440
ContainerdSockPath = v
3541
}
42+
if v := os.Getenv(numberOfVmsEnvVar); v != "" {
43+
NumberOfVms, _ = strconv.Atoi(v)
44+
}
3645
}

snapshotter/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
demux-snapshotter
22
http-address-resolver
3+
logs/

snapshotter/Makefile

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,72 @@
1212
# permissions and limitations under the License.
1313

1414
EXTRAGOARGS?=
15+
NUMBER_OF_VMS?=
1516

1617
SOURCES := $(shell find . -name '*.go')
1718
GOMOD := $(shell go env GOMOD)
1819
GOSUM := $(GOMOD:.mod=.sum)
20+
DOCKER_IMAGE_TAG?=latest
21+
GO_CACHE_VOLUME_NAME?=gocache
22+
FIRECRACKER_CONTAINERD_TEST_IMAGE?=localhost/firecracker-containerd-test
1923

2024
REVISION := $(shell git rev-parse HEAD)
2125

22-
all: demux-snapshotter
26+
INTEG_TEST_SUFFIX := _Isolated
27+
INTEG_TESTNAMES=$(shell docker run --rm \
28+
--network=none \
29+
--volume $(CURDIR)/..:/src \
30+
--volume $(GO_CACHE_VOLUME_NAME):/go \
31+
--entrypoint=/bin/bash \
32+
--workdir=/src/snapshotter \
33+
$(FIRECRACKER_CONTAINERD_TEST_IMAGE):$(DOCKER_IMAGE_TAG) \
34+
-c "go test -list . | sed '$$d' | grep $(INTEG_TEST_SUFFIX)")
35+
36+
all: demux-snapshotter http-address-resolver
2337

2438
demux-snapshotter: $(SOURCES) $(GOMOD) $(GOSUM)
2539
go build $(EXTRAGOARGS) -ldflags "-X main.revision=$(REVISION)" -o $@
2640

2741
http-address-resolver: $(SOURCES) $(GOMOD) $(GOSUM)
2842
go build $(EXTRAGOARGS) -ldflags "-X main.revision=$(REVISION)" -o $@ internal/http_address_resolver.go
2943

44+
install: demux-snapshotter http-address-resolver
45+
install -D -o root -g root -m755 -t $(INSTALLROOT)/bin $^
46+
3047
test:
3148
go test ./... $(EXTRAGOARGS)
3249

3350
integ-test:
51+
$(MAKE) $(addprefix integ-test-,$(INTEG_TESTNAMES))
52+
53+
integ-test-%: logs
54+
docker run --rm -it \
55+
--privileged \
56+
--ipc=host \
57+
--network=bridge \
58+
--volume /dev:/dev \
59+
--volume /run/udev/control:/run/udev/control \
60+
--volume $(CURDIR)/logs:/var/log/firecracker-containerd-test \
61+
--volume $(CURDIR)/..:/src \
62+
--volume $(GO_CACHE_VOLUME_NAME):/go \
63+
--env ENABLE_ISOLATED_TESTS=1 \
64+
--env GOPROXY=direct \
65+
--env GOSUMDB=off \
66+
--env GO111MODULE=on \
67+
--env NUMBER_OF_VMS=$(NUMBER_OF_VMS) \
68+
--workdir="/src/snapshotter" \
69+
--init \
70+
$(FIRECRACKER_CONTAINERD_TEST_IMAGE):$(DOCKER_IMAGE_TAG) \
71+
"go test $(EXTRAGOARGS) -run '^$(subst integ-test-,,$@)$$'"
72+
73+
logs:
74+
mkdir logs
3475

3576
clean:
3677
- rm -f demux-snapshotter
37-
- rm -f http-resolver
78+
- rm -f http-address-resolver
3879

3980
distclean: clean
81+
- rm -rf logs
4082

41-
# Install is a noop here, for now.
42-
install:
43-
44-
.PHONY: all install test clean distclean
83+
.PHONY: all clean distclean install test integ-test
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
// Copied from https://github.com/containerd/stargz-snapshotter/blob/v0.11.4/fs/config/config.go
15+
//
16+
// Taking Stargz as a code dependency required dropping support for Go 1.16.
17+
// Used to add Stargz annotations to pull requests.
18+
19+
/*
20+
Copyright The containerd Authors.
21+
22+
Licensed under the Apache License, Version 2.0 (the "License");
23+
you may not use this file except in compliance with the License.
24+
You may obtain a copy of the License at
25+
26+
http://www.apache.org/licenses/LICENSE-2.0
27+
28+
Unless required by applicable law or agreed to in writing, software
29+
distributed under the License is distributed on an "AS IS" BASIS,
30+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31+
See the License for the specific language governing permissions and
32+
limitations under the License.
33+
*/
34+
35+
/*
36+
Copyright 2019 The Go Authors. All rights reserved.
37+
Use of this source code is governed by a BSD-style
38+
license that can be found in the NOTICE.md file.
39+
*/
40+
41+
package config
42+
43+
const (
44+
// TargetSkipVerifyLabel is a snapshot label key that indicates to skip content
45+
// verification for the layer.
46+
TargetSkipVerifyLabel = "containerd.io/snapshot/remote/stargz.skipverify"
47+
48+
// TargetPrefetchSizeLabel is a snapshot label key that indicates size to prefetch
49+
// the layer. If the layer is eStargz and contains prefetch landmarks, these config
50+
// will be respeced.
51+
TargetPrefetchSizeLabel = "containerd.io/snapshot/remote/stargz.prefetch"
52+
)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
// Copied from https://github.com/containerd/stargz-snapshotter/blob/v0.11.4/fs/source/source.go
15+
//
16+
// Taking Stargz as a code dependency required dropping support for Go 1.16.
17+
// Used to add Stargz annotations to pull requests.
18+
19+
/*
20+
Copyright The containerd Authors.
21+
22+
Licensed under the Apache License, Version 2.0 (the "License");
23+
you may not use this file except in compliance with the License.
24+
You may obtain a copy of the License at
25+
26+
http://www.apache.org/licenses/LICENSE-2.0
27+
28+
Unless required by applicable law or agreed to in writing, software
29+
distributed under the License is distributed on an "AS IS" BASIS,
30+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31+
See the License for the specific language governing permissions and
32+
limitations under the License.
33+
*/
34+
35+
package source
36+
37+
import (
38+
"context"
39+
"fmt"
40+
"strings"
41+
42+
"github.com/containerd/containerd/images"
43+
"github.com/containerd/containerd/labels"
44+
"github.com/firecracker-microvm/firecracker-containerd/snapshotter/internal/integtest/stargz/fs/config"
45+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
46+
)
47+
48+
const (
49+
// targetRefLabel is a label which contains image reference.
50+
targetRefLabel = "containerd.io/snapshot/remote/stargz.reference"
51+
52+
// targetDigestLabel is a label which contains layer digest.
53+
targetDigestLabel = "containerd.io/snapshot/remote/stargz.digest"
54+
55+
// targetImageLayersLabel is a label which contains layer digests contained in
56+
// the target image.
57+
targetImageLayersLabel = "containerd.io/snapshot/remote/stargz.layers"
58+
59+
// targetImageURLsLabelPrefix is a label prefix which constructs a map from the layer index to
60+
// urls of the layer descriptor.
61+
targetImageURLsLabelPrefix = "containerd.io/snapshot/remote/urls."
62+
63+
// targetURsLLabel is a label which contains layer URL. This is only used to pass URL from containerd
64+
// to snapshotter.
65+
targetURLsLabel = "containerd.io/snapshot/remote/urls"
66+
)
67+
68+
// AppendDefaultLabelsHandlerWrapper makes a handler which appends image's basic
69+
// information to each layer descriptor as annotations during unpack. These
70+
// annotations will be passed to this remote snapshotter as labels and used to
71+
// construct source information.
72+
func AppendDefaultLabelsHandlerWrapper(ref string, prefetchSize int64) func(f images.Handler) images.Handler {
73+
return func(f images.Handler) images.Handler {
74+
return images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
75+
children, err := f.Handle(ctx, desc)
76+
if err != nil {
77+
return nil, err
78+
}
79+
switch desc.MediaType {
80+
case ocispec.MediaTypeImageManifest, images.MediaTypeDockerSchema2Manifest:
81+
for i := range children {
82+
c := &children[i]
83+
if images.IsLayerType(c.MediaType) {
84+
if c.Annotations == nil {
85+
c.Annotations = make(map[string]string)
86+
}
87+
c.Annotations[targetRefLabel] = ref
88+
c.Annotations[targetDigestLabel] = c.Digest.String()
89+
var layers string
90+
for i, l := range children[i:] {
91+
if images.IsLayerType(l.MediaType) {
92+
ls := fmt.Sprintf("%s,", l.Digest.String())
93+
// This avoids the label hits the size limitation.
94+
// Skipping layers is allowed here and only affects performance.
95+
if err := labels.Validate(targetImageLayersLabel, layers+ls); err != nil {
96+
break
97+
}
98+
layers += ls
99+
100+
// Store URLs of the neighbouring layer as well.
101+
urlsKey := targetImageURLsLabelPrefix + fmt.Sprintf("%d", i)
102+
c.Annotations[urlsKey] = appendWithValidation(urlsKey, l.URLs)
103+
}
104+
}
105+
c.Annotations[targetImageLayersLabel] = strings.TrimSuffix(layers, ",")
106+
c.Annotations[config.TargetPrefetchSizeLabel] = fmt.Sprintf("%d", prefetchSize)
107+
108+
// store URL in annotation to let containerd to pass it to the snapshotter
109+
c.Annotations[targetURLsLabel] = appendWithValidation(targetURLsLabel, c.URLs)
110+
}
111+
}
112+
}
113+
return children, nil
114+
})
115+
}
116+
}
117+
118+
func appendWithValidation(key string, values []string) string {
119+
var v string
120+
for _, u := range values {
121+
s := fmt.Sprintf("%s,", u)
122+
if err := labels.Validate(key, v+s); err != nil {
123+
break
124+
}
125+
v += s
126+
}
127+
return strings.TrimSuffix(v, ",")
128+
}

0 commit comments

Comments
 (0)