github.com/containerd/nerdctl@v1.7.7/cmd/nerdctl/ipfs_linux_test.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"regexp"
    23  	"testing"
    24  
    25  	"github.com/containerd/nerdctl/pkg/infoutil"
    26  	"github.com/containerd/nerdctl/pkg/rootlessutil"
    27  	"github.com/containerd/nerdctl/pkg/testutil"
    28  
    29  	"gotest.tools/v3/assert"
    30  )
    31  
    32  func TestIPFS(t *testing.T) {
    33  	testutil.DockerIncompatible(t)
    34  	base := testutil.NewBase(t)
    35  	ipfsCID := pushImageToIPFS(t, base, testutil.AlpineImage)
    36  	base.Env = append(os.Environ(), "CONTAINERD_SNAPSHOTTER=overlayfs")
    37  	base.Cmd("pull", ipfsCID).AssertOK()
    38  	base.Cmd("run", "--rm", ipfsCID, "echo", "hello").AssertOK()
    39  
    40  	// encryption
    41  	keyPair := newJWEKeyPair(t)
    42  	defer keyPair.cleanup()
    43  	tID := testutil.Identifier(t)
    44  	encryptImageRef := tID + ":enc"
    45  	layersNum := 1
    46  	base.Cmd("image", "encrypt", "--recipient=jwe:"+keyPair.pub, ipfsCID, encryptImageRef).AssertOK()
    47  	base.Cmd("image", "inspect", "--mode=native", "--format={{len .Manifest.Layers}}", encryptImageRef).AssertOutExactly(fmt.Sprintf("%d\n", layersNum))
    48  	for i := 0; i < layersNum; i++ {
    49  		base.Cmd("image", "inspect", "--mode=native", fmt.Sprintf("--format={{json (index .Manifest.Layers %d) }}", i), encryptImageRef).AssertOutContains("org.opencontainers.image.enc.keys.jwe")
    50  	}
    51  	ipfsCIDEnc := cidOf(t, base.Cmd("push", "ipfs://"+encryptImageRef).OutLines())
    52  	rmiAll(base)
    53  
    54  	decryptImageRef := tID + ":dec"
    55  	base.Cmd("pull", "--unpack=false", ipfsCIDEnc).AssertOK()
    56  	base.Cmd("image", "decrypt", "--key="+keyPair.pub, ipfsCIDEnc, decryptImageRef).AssertFail() // decryption needs prv key, not pub key
    57  	base.Cmd("image", "decrypt", "--key="+keyPair.prv, ipfsCIDEnc, decryptImageRef).AssertOK()
    58  	base.Cmd("run", "--rm", decryptImageRef, "/bin/sh", "-c", "echo hello").AssertOK()
    59  }
    60  
    61  var iplineRegexp = regexp.MustCompile(`"([0-9\.]*)"`)
    62  
    63  func TestIPFSAddress(t *testing.T) {
    64  	testutil.DockerIncompatible(t)
    65  	base := testutil.NewBase(t)
    66  	ipfsaddr, done := runIPFSDaemonContainer(t, base)
    67  	defer done()
    68  	ipfsCID := pushImageToIPFS(t, base, testutil.AlpineImage, fmt.Sprintf("--ipfs-address=%s", ipfsaddr))
    69  	base.Env = append(os.Environ(), "CONTAINERD_SNAPSHOTTER=overlayfs")
    70  	base.Cmd("pull", "--ipfs-address", ipfsaddr, ipfsCID).AssertOK()
    71  	base.Cmd("run", "--ipfs-address", ipfsaddr, "--rm", ipfsCID, "echo", "hello").AssertOK()
    72  }
    73  
    74  func runIPFSDaemonContainer(t *testing.T, base *testutil.Base) (ipfsAddress string, done func()) {
    75  	name := "test-ipfs-address"
    76  	base.Cmd("run", "-d", "--name", name, "--entrypoint=/bin/sh", testutil.KuboImage, "-c", "ipfs init && ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001 && ipfs daemon --offline").AssertOK()
    77  	iplines := base.Cmd("inspect", name, "-f", "'{{json .NetworkSettings.IPAddress}}'").OutLines()
    78  	t.Logf("IPAddress=%v", iplines)
    79  	assert.Equal(t, len(iplines), 2)
    80  	matches := iplineRegexp.FindStringSubmatch(iplines[0])
    81  	t.Logf("ip address matches=%v", matches)
    82  	assert.Equal(t, len(matches), 2)
    83  	ipfsaddr := fmt.Sprintf("/ip4/%s/tcp/5001", matches[1])
    84  	return ipfsaddr, func() {
    85  		base.Cmd("kill", "test-ipfs-address").AssertOK()
    86  		base.Cmd("rm", "test-ipfs-address").AssertOK()
    87  	}
    88  }
    89  
    90  func TestIPFSCommit(t *testing.T) {
    91  	// cgroup is required for nerdctl commit
    92  	if rootlessutil.IsRootless() && infoutil.CgroupsVersion() == "1" {
    93  		t.Skip("test skipped for rootless containers on cgroup v1")
    94  	}
    95  	testutil.DockerIncompatible(t)
    96  	base := testutil.NewBase(t)
    97  	ipfsCID := pushImageToIPFS(t, base, testutil.AlpineImage)
    98  
    99  	base.Env = append(os.Environ(), "CONTAINERD_SNAPSHOTTER=overlayfs")
   100  	base.Cmd("pull", ipfsCID).AssertOK()
   101  	base.Cmd("run", "--rm", ipfsCID, "echo", "hello").AssertOK()
   102  	tID := testutil.Identifier(t)
   103  	newContainer, newImg := tID, tID+":v1"
   104  	base.Cmd("run", "--name", newContainer, "-d", ipfsCID, "/bin/sh", "-c", "echo hello > /hello ; sleep 10000").AssertOK()
   105  	base.Cmd("commit", newContainer, newImg).AssertOK()
   106  	base.Cmd("kill", newContainer).AssertOK()
   107  	base.Cmd("rm", newContainer).AssertOK()
   108  	ipfsCID2 := cidOf(t, base.Cmd("push", "ipfs://"+newImg).OutLines())
   109  	rmiAll(base)
   110  	base.Cmd("pull", ipfsCID2).AssertOK()
   111  	base.Cmd("run", "--rm", ipfsCID2, "/bin/sh", "-c", "cat /hello").AssertOK()
   112  }
   113  
   114  func TestIPFSWithLazyPulling(t *testing.T) {
   115  	testutil.DockerIncompatible(t)
   116  	base := testutil.NewBase(t)
   117  	requiresStargz(base)
   118  	ipfsCID := pushImageToIPFS(t, base, testutil.AlpineImage, "--estargz")
   119  
   120  	base.Env = append(os.Environ(), "CONTAINERD_SNAPSHOTTER=stargz")
   121  	base.Cmd("pull", ipfsCID).AssertOK()
   122  	base.Cmd("run", "--rm", ipfsCID, "ls", "/.stargz-snapshotter").AssertOK()
   123  }
   124  
   125  func TestIPFSWithLazyPullingCommit(t *testing.T) {
   126  	// cgroup is required for nerdctl commit
   127  	if rootlessutil.IsRootless() && infoutil.CgroupsVersion() == "1" {
   128  		t.Skip("test skipped for rootless containers on cgroup v1")
   129  	}
   130  	testutil.DockerIncompatible(t)
   131  	base := testutil.NewBase(t)
   132  	requiresStargz(base)
   133  	ipfsCID := pushImageToIPFS(t, base, testutil.AlpineImage, "--estargz")
   134  
   135  	base.Env = append(os.Environ(), "CONTAINERD_SNAPSHOTTER=stargz")
   136  	base.Cmd("pull", ipfsCID).AssertOK()
   137  	base.Cmd("run", "--rm", ipfsCID, "ls", "/.stargz-snapshotter").AssertOK()
   138  	tID := testutil.Identifier(t)
   139  	newContainer, newImg := tID, tID+":v1"
   140  	base.Cmd("run", "--name", newContainer, "-d", ipfsCID, "/bin/sh", "-c", "echo hello > /hello ; sleep 10000").AssertOK()
   141  	base.Cmd("commit", newContainer, newImg).AssertOK()
   142  	base.Cmd("kill", newContainer).AssertOK()
   143  	base.Cmd("rm", newContainer).AssertOK()
   144  	ipfsCID2 := cidOf(t, base.Cmd("push", "--estargz", "ipfs://"+newImg).OutLines())
   145  	rmiAll(base)
   146  
   147  	base.Cmd("pull", ipfsCID2).AssertOK()
   148  	base.Cmd("run", "--rm", ipfsCID2, "/bin/sh", "-c", "ls /.stargz-snapshotter && cat /hello").AssertOK()
   149  	base.Cmd("image", "rm", ipfsCID2).AssertOK()
   150  }
   151  
   152  func pushImageToIPFS(t *testing.T, base *testutil.Base, name string, opts ...string) string {
   153  	base.Cmd("pull", name).AssertOK()
   154  	ipfsCID := cidOf(t, base.Cmd(append([]string{"push"}, append(opts, "ipfs://"+name)...)...).OutLines())
   155  	base.Cmd("rmi", name).AssertOK()
   156  	return ipfsCID
   157  }
   158  
   159  func cidOf(t *testing.T, lines []string) string {
   160  	assert.Equal(t, len(lines) >= 2, true)
   161  	return "ipfs://" + lines[len(lines)-2]
   162  }