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