github.com/sameo/containerd@v0.2.8/integration-test/bundle_utils_test.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"os"
     7  	"os/exec"
     8  	"path/filepath"
     9  	"reflect"
    10  	"runtime"
    11  
    12  	utils "github.com/docker/containerd/testutils"
    13  	ocs "github.com/opencontainers/runtime-spec/specs-go"
    14  )
    15  
    16  type OciProcessArgs struct {
    17  	Cmd  string
    18  	Args []string
    19  }
    20  
    21  type Bundle struct {
    22  	Source string
    23  	Name   string
    24  	Spec   ocs.Spec
    25  	Path   string
    26  }
    27  
    28  var bundleMap map[string]Bundle
    29  
    30  // untarRootfs untars the given `source` tarPath into `destination/rootfs`
    31  func untarRootfs(source string, destination string) error {
    32  	var tar *exec.Cmd
    33  	if runtime.GOOS == "solaris" {
    34  		destination = filepath.Join(destination, "/rootfs/root")
    35  		tar = exec.Command("gtar", "-C", destination, "-xf", source)
    36  	} else {
    37  		destination = filepath.Join(destination, "rootfs")
    38  		tar = exec.Command("tar", "-C", destination, "-xf", source)
    39  	}
    40  
    41  	if err := os.MkdirAll(destination, 0755); err != nil {
    42  		return nil
    43  	}
    44  	return tar.Run()
    45  }
    46  
    47  // CreateBundleWithFilter generate a new oci-bundle named `name` from
    48  // the provide `source` rootfs. It starts from the default spec
    49  // generated by `runc spec`, overrides the `spec.Process.Args` value
    50  // with `args` and set `spec.Process.Terminal` to false. It then apply
    51  // `filter()` to the resulting spec if it is provided.
    52  func CreateBundleWithFilter(source, name string, args []string, filter func(spec *ocs.Spec)) error {
    53  	// Generate the spec
    54  	var spec ocs.Spec
    55  	f, err := os.Open(utils.RefOciSpecsPath)
    56  	if err != nil {
    57  		return fmt.Errorf("Failed to open default spec: %v", err)
    58  	}
    59  	if err := json.NewDecoder(f).Decode(&spec); err != nil {
    60  		return fmt.Errorf("Failed to load default spec: %v", err)
    61  	}
    62  	f.Close()
    63  
    64  	spec.Process.Args = args
    65  	spec.Process.Terminal = false
    66  	if filter != nil {
    67  		filter(&spec)
    68  	}
    69  
    70  	bundlePath := filepath.Join(utils.BundlesRoot, name)
    71  	nb := Bundle{source, name, spec, bundlePath}
    72  
    73  	// Check that we don't already have such a bundle
    74  	if b, ok := bundleMap[name]; ok {
    75  		if reflect.DeepEqual(b, nb) == false {
    76  			return fmt.Errorf("A bundle name named '%s' already exist but with different properties! %#v != %#v",
    77  				name, b, nb)
    78  		}
    79  		return nil
    80  	}
    81  
    82  	// Nothing should be there, but just in case
    83  	os.RemoveAll(bundlePath)
    84  
    85  	var sourceStr string
    86  	if runtime.GOOS == "solaris" {
    87  		sourceStr = source + ".tar.gz"
    88  	} else {
    89  		sourceStr = source + ".tar"
    90  	}
    91  
    92  	if err := untarRootfs(filepath.Join(utils.ArchivesDir, sourceStr), bundlePath); err != nil {
    93  		return fmt.Errorf("Failed to untar %s.tar: %v", source, err)
    94  	}
    95  
    96  	// create a place for the io fifo
    97  	if err := os.Mkdir(filepath.Join(bundlePath, "io"), 0755); err != nil {
    98  		return fmt.Errorf("Failed to create bundle io directory: %v", err)
    99  	}
   100  
   101  	// Write the updated spec to the right location
   102  	config, e := os.Create(filepath.Join(bundlePath, "config.json"))
   103  	if e != nil {
   104  		return fmt.Errorf("Failed to create oci spec: %v", e)
   105  	}
   106  	defer config.Close()
   107  
   108  	if err := json.NewEncoder(config).Encode(&spec); err != nil {
   109  		return fmt.Errorf("Failed to encore oci spec: %v", e)
   110  	}
   111  
   112  	bundleMap[name] = nb
   113  	return nil
   114  }
   115  
   116  func GetBundle(name string) *Bundle {
   117  	bundle, ok := bundleMap[name]
   118  	if !ok {
   119  		return nil
   120  	}
   121  	return &bundle
   122  }
   123  
   124  func CreateBusyboxBundle(name string, args []string) error {
   125  	return CreateBundleWithFilter("busybox", name, args, nil)
   126  }
   127  
   128  func CreateSolarisBundle(name string, args []string) error {
   129  	return CreateBundleWithFilter("rootfs", name, args, nil)
   130  }