Skip to content

Create CNI-enabled firecracker-runtime.json on the fly #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2019
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
1 change: 1 addition & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ integ-test:
--ipc=host \
--volume /dev:/dev \
--volume /run/udev/control:/run/udev/control \
--volume $(CURDIR)/etc/containerd/firecracker-runtime.json:/etc/containerd/firecracker-runtime.json \
--volume $(CURDIR)/logs:/var/log/firecracker-containerd-test \
--env EXTRAGOARGS="${EXTRAGOARGS}" \
--workdir="/firecracker-containerd/examples" \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@
"root_drive": "/var/lib/firecracker-containerd/runtime/default-rootfs.img",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since most customers wouldn't generate the configuration file on-the-fly, I'd like to keep this JSON file inside examples/.

"cpu_count": 1,
"cpu_template": "T2",
"log_fifo": "/tmp/fc-logs.fifo",
"log_level": "Debug",
"metrics_fifo": "/tmp/fc-metrics.fifo"
"log_level": "Debug"
}
26 changes: 14 additions & 12 deletions runtime/cni_integ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import (
)

func TestCNISupport_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

testTimeout := 120 * time.Second
ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), defaultNamespace), testTimeout)
Expand Down Expand Up @@ -133,8 +133,7 @@ func TestCNISupport_Isolated(t *testing.T) {
}

func TestAutomaticCNISupport_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
useDefaultNetworkInterfaceRuntimeConfig(t)
prepareIntegTest(t, withDefaultNetwork())

testTimeout := 120 * time.Second
ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), defaultNamespace), testTimeout)
Expand Down Expand Up @@ -200,7 +199,7 @@ func TestAutomaticCNISupport_Isolated(t *testing.T) {
}

func TestCNIPlugin_Performance(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

numVMs := perfTestVMCount(t)
runtimeDuration := perfTestRuntime(t)
Expand Down Expand Up @@ -354,14 +353,17 @@ func writeCNIConf(path, chainedPluginName, networkName, nameserver string) error
}`, networkName, nameserver, chainedPluginName)), 0644)
}

func useDefaultNetworkInterfaceRuntimeConfig(t *testing.T) {
t.Helper()

err := os.RemoveAll(runtimeConfigPath)
require.NoError(t, err, "failed to remove existing firecracker containerd runtime config file")

err = os.Symlink(defaultNetworkInterfaceRuntimeConfigPath, runtimeConfigPath)
require.NoError(t, err, "failed to symlink default network interface runtime config")
func withDefaultNetwork() func(c *Config) {
return func(c *Config) {
c.DefaultNetworkInterfaces = []proto.FirecrackerNetworkInterface{
{
CNIConfig: &proto.CNIConfiguration{
NetworkName: "fcnet",
InterfaceName: "veth0",
},
},
}
}
}

func runCommand(ctx context.Context, t *testing.T, name string, args ...string) {
Expand Down
69 changes: 69 additions & 0 deletions runtime/integ_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 (
"encoding/json"
"os"
"testing"

"github.com/firecracker-microvm/firecracker-containerd/internal"
)

const runtimeConfigPath = "/etc/containerd/firecracker-runtime.json"

var defaultRuntimeConfig = Config{
FirecrackerBinaryPath: "/usr/local/bin/firecracker",
KernelImagePath: "/var/lib/firecracker-containerd/runtime/default-vmlinux.bin",
KernelArgs: "ro console=ttyS0 noapic reboot=k panic=1 pci=off nomodules systemd.journald.forward_to_console systemd.unit=firecracker.target init=/sbin/overlay-init",
RootDrive: "/var/lib/firecracker-containerd/runtime/default-rootfs.img",
CPUCount: 1,
CPUTemplate: "T2",
LogLevel: "Debug",
}

func prepareIntegTest(t *testing.T, options ...func(*Config)) {
t.Helper()

internal.RequiresIsolation(t)

err := writeRuntimeConfig(options...)
if err != nil {
t.Error(err)
}
}

func writeRuntimeConfig(options ...func(*Config)) error {
config := defaultRuntimeConfig
for _, option := range options {
option(&config)
}

file, err := os.Create(runtimeConfigPath)
if err != nil {
return err
}
defer file.Close()

bytes, err := json.Marshal(config)
if err != nil {
return err
}

_, err = file.Write(bytes)
if err != nil {
return err
}

return nil
}
18 changes: 9 additions & 9 deletions runtime/service_integ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,6 @@ const (
defaultVMRootfsPath = "/var/lib/firecracker-containerd/runtime/default-rootfs.img"
defaultVMNetDevName = "eth0"
varRunDir = "/run/firecracker-containerd"

runtimeConfigPath = "/etc/containerd/firecracker-runtime.json"
defaultNetworkInterfaceRuntimeConfigPath = "/etc/containerd/firecracker-runtime-defaultnetwork.json"
)

// Images are presumed by the isolated tests to have already been pulled
Expand Down Expand Up @@ -94,7 +91,7 @@ func iperf3Image(ctx context.Context, client *containerd.Client, snapshotterName
}

func TestShimExitsUponContainerDelete_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

ctx := namespaces.WithNamespace(context.Background(), defaultNamespace)

Expand Down Expand Up @@ -224,7 +221,7 @@ func createTapDevice(ctx context.Context, tapName string) error {
}

func TestMultipleVMs_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

const (
numVMs = 3
Expand Down Expand Up @@ -457,13 +454,14 @@ func TestMultipleVMs_Isolated(t *testing.T) {
}

func TestLongUnixSocketPath_Isolated(t *testing.T) {
prepareIntegTest(t)

// Verify that if the absolute path of the Firecracker unix sockets are longer
// than the max length enforced by the kernel (UNIX_PATH_MAX, usually 108), we
// don't fail (due to the internal implementation using relative paths).
// We do this by using the max VMID len (76 chars), which in combination with the
// default location we store state results in a path like
// "/run/firecracker-containerd/default/<vmID>" (with len 112).
internal.RequiresIsolation(t)
const maxUnixSockLen = 108
vmID := strings.Repeat("x", 76)

Expand Down Expand Up @@ -502,7 +500,8 @@ func TestLongUnixSocketPath_Isolated(t *testing.T) {
}

func TestStubBlockDevices_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

const vmID = 0

ctx := namespaces.WithNamespace(context.Background(), "default")
Expand Down Expand Up @@ -734,7 +733,7 @@ func testCreateContainerWithSameName(t *testing.T, vmID string) {
}

func TestCreateContainerWithSameName_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

testCreateContainerWithSameName(t, "")

Expand All @@ -743,7 +742,8 @@ func TestCreateContainerWithSameName_Isolated(t *testing.T) {
}

func TestCreateTooManyContainers_Isolated(t *testing.T) {
internal.RequiresIsolation(t)
prepareIntegTest(t)

assert := assert.New(t)

ctx := namespaces.WithNamespace(context.Background(), "default")
Expand Down
3 changes: 0 additions & 3 deletions tools/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ COPY _submodules/firecracker/target/$FIRECRACKER_TARGET/release/firecracker /usr
COPY _submodules/firecracker/target/$FIRECRACKER_TARGET/release/jailer /usr/local/bin/
COPY _submodules/runc/runc /usr/local/bin
COPY tools/image-builder/rootfs.img /var/lib/firecracker-containerd/runtime/default-rootfs.img
COPY tools/docker/firecracker-runtime.json /etc/containerd/firecracker-runtime.json

# pull the images the tests need into the content store so we don't need internet
# access during the tests themselves
Expand All @@ -164,8 +163,6 @@ RUN make -C /firecracker-containerd/internal test-bridged-tap && \
cp /firecracker-containerd/internal/test-bridged-tap /opt/cni/bin/ && \
chmod a+x /firecracker-containerd/internal/test-bridged-tap

COPY tools/docker/firecracker-runtime.json /etc/containerd/firecracker-runtime.json
COPY tools/docker/firecracker-runtime-defaultnetwork.json /etc/containerd/firecracker-runtime-defaultnetwork.json
COPY tools/docker/naive-snapshotter/entrypoint.sh /entrypoint

ENTRYPOINT ["/entrypoint"]
Expand Down
19 changes: 0 additions & 19 deletions tools/docker/firecracker-runtime-defaultnetwork.json

This file was deleted.