github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/build/sources/conveyorPacker_oci_test.go (about) 1 // Copyright (c) 2018, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package sources_test 7 8 import ( 9 "io" 10 "io/ioutil" 11 "log" 12 "net/http" 13 "os" 14 "os/exec" 15 "testing" 16 17 "github.com/sylabs/singularity/internal/pkg/build/sources" 18 "github.com/sylabs/singularity/internal/pkg/test" 19 "github.com/sylabs/singularity/pkg/build/types" 20 useragent "github.com/sylabs/singularity/pkg/util/user-agent" 21 ) 22 23 const ( 24 dockerURI = "docker://alpine" 25 dockerArchiveURI = "https://s3.amazonaws.com/singularity-ci-public/alpine-docker-save.tar" 26 ociArchiveURI = "https://s3.amazonaws.com/singularity-ci-public/alpine-oci-archive.tar" 27 dockerDaemonImage = "alpine:latest" 28 ) 29 30 func TestMain(m *testing.M) { 31 useragent.InitValue("singularity", "3.0.0-alpha.1-303-gaed8d30-dirty") 32 33 os.Exit(m.Run()) 34 } 35 36 // TestOCIConveyorDocker tests if we can pull an alpine image from dockerhub 37 func TestOCIConveyorDocker(t *testing.T) { 38 test.DropPrivilege(t) 39 defer test.ResetPrivilege(t) 40 41 b, err := types.NewBundle("", "sbuild-oci") 42 if err != nil { 43 return 44 } 45 46 b.Recipe, err = types.NewDefinitionFromURI(dockerURI) 47 if err != nil { 48 t.Fatalf("unable to parse URI %s: %v\n", dockerURI, err) 49 } 50 51 cp := &sources.OCIConveyorPacker{} 52 53 err = cp.Get(b) 54 // clean up tmpfs since assembler isnt called 55 defer cp.CleanUp() 56 if err != nil { 57 t.Fatalf("failed to Get from %s: %v\n", dockerURI, err) 58 } 59 } 60 61 // TestOCIConveyorDockerArchive tests if we can use a docker save archive 62 // as a source 63 func TestOCIConveyorDockerArchive(t *testing.T) { 64 test.DropPrivilege(t) 65 defer test.ResetPrivilege(t) 66 67 archive, err := getTestTar(dockerArchiveURI) 68 if err != nil { 69 t.Fatalf("Could not download docker archive test file: %v", err) 70 } 71 defer os.Remove(archive) 72 73 b, err := types.NewBundle("", "sbuild-oci") 74 if err != nil { 75 return 76 } 77 78 archiveURI := "docker-archive:" + archive 79 b.Recipe, err = types.NewDefinitionFromURI(archiveURI) 80 if err != nil { 81 t.Fatalf("unable to parse URI %s: %v\n", archiveURI, err) 82 } 83 84 cp := &sources.OCIConveyorPacker{} 85 86 err = cp.Get(b) 87 // clean up tmpfs since assembler isnt called 88 defer cp.CleanUp() 89 if err != nil { 90 t.Fatalf("failed to Get from %s: %v\n", archiveURI, err) 91 } 92 } 93 94 // TestOCIConveyerDockerDaemon tests if we can use an oci laytout dir 95 // as a source 96 func TestOCIConveyorDockerDaemon(t *testing.T) { 97 test.DropPrivilege(t) 98 defer test.ResetPrivilege(t) 99 100 cmd := exec.Command("docker", "ps") 101 err := cmd.Run() 102 if err != nil { 103 t.Logf("docker not available - skipping docker-daemon test") 104 return 105 } 106 107 cmd = exec.Command("docker", "pull", dockerDaemonImage) 108 err = cmd.Run() 109 if err != nil { 110 t.Fatalf("could not docker pull alpine:latest %v", err) 111 return 112 } 113 114 b, err := types.NewBundle("", "sbuild-oci") 115 if err != nil { 116 return 117 } 118 119 daemonURI := "docker-daemon:" + dockerDaemonImage 120 b.Recipe, err = types.NewDefinitionFromURI(daemonURI) 121 if err != nil { 122 t.Fatalf("unable to parse URI %s: %v\n", daemonURI, err) 123 } 124 125 cp := &sources.OCIConveyorPacker{} 126 127 err = cp.Get(b) 128 // clean up tmpfs since assembler isnt called 129 defer cp.CleanUp() 130 if err != nil { 131 t.Fatalf("failed to Get from %s: %v\n", daemonURI, err) 132 } 133 } 134 135 // TestOCIConveyorOCIArchive tests if we can use an oci archive 136 // as a source 137 func TestOCIConveyorOCIArchive(t *testing.T) { 138 test.DropPrivilege(t) 139 defer test.ResetPrivilege(t) 140 141 archive, err := getTestTar(ociArchiveURI) 142 if err != nil { 143 t.Fatalf("Could not download oci archive test file: %v", err) 144 } 145 defer os.Remove(archive) 146 147 b, err := types.NewBundle("", "sbuild-oci") 148 if err != nil { 149 return 150 } 151 152 archiveURI := "oci-archive:" + archive 153 b.Recipe, err = types.NewDefinitionFromURI(archiveURI) 154 if err != nil { 155 t.Fatalf("unable to parse URI %s: %v\n", archiveURI, err) 156 } 157 158 cp := &sources.OCIConveyorPacker{} 159 160 err = cp.Get(b) 161 // clean up tmpfs since assembler isnt called 162 defer cp.CleanUp() 163 if err != nil { 164 t.Fatalf("failed to Get from %s: %v\n", archiveURI, err) 165 } 166 } 167 168 // TestOCIConveyerOCILayout tests if we can use an oci layout dir 169 // as a source 170 func TestOCIConveyorOCILayout(t *testing.T) { 171 test.DropPrivilege(t) 172 defer test.ResetPrivilege(t) 173 174 archive, err := getTestTar(ociArchiveURI) 175 if err != nil { 176 t.Fatalf("Could not download oci archive test file: %v", err) 177 } 178 defer os.Remove(archive) 179 180 // We need to extract the oci archive to a directory 181 // Don't want to implement untar routines here, so use system tar 182 dir, err := ioutil.TempDir("", "oci-test") 183 if err != nil { 184 t.Fatalf("Could not create temporary directory: %v", err) 185 } 186 defer os.RemoveAll(dir) 187 cmd := exec.Command("tar", "-C", dir, "-xf", archive) 188 err = cmd.Run() 189 if err != nil { 190 t.Fatalf("Error extracting oci archive to layout: %v", err) 191 } 192 193 b, err := types.NewBundle("", "sbuild-oci") 194 if err != nil { 195 return 196 } 197 198 layoutURI := "oci:" + dir 199 b.Recipe, err = types.NewDefinitionFromURI(layoutURI) 200 if err != nil { 201 t.Fatalf("unable to parse URI %s: %v\n", layoutURI, err) 202 } 203 204 cp := &sources.OCIConveyorPacker{} 205 206 err = cp.Get(b) 207 // clean up tmpfs since assembler isnt called 208 defer cp.CleanUp() 209 if err != nil { 210 t.Fatalf("failed to Get from %s: %v\n", layoutURI, err) 211 } 212 } 213 214 // TestOCIPacker checks if we can create a Kitchen 215 func TestOCIPacker(t *testing.T) { 216 test.DropPrivilege(t) 217 defer test.ResetPrivilege(t) 218 219 b, err := types.NewBundle("", "sbuild-oci") 220 if err != nil { 221 return 222 } 223 224 b.Recipe, err = types.NewDefinitionFromURI(dockerURI) 225 if err != nil { 226 t.Fatalf("unable to parse URI %s: %v\n", dockerURI, err) 227 } 228 229 ocp := &sources.OCIConveyorPacker{} 230 231 err = ocp.Get(b) 232 // clean up tmpfs since assembler isnt called 233 defer ocp.CleanUp() 234 if err != nil { 235 t.Fatalf("failed to Get from %s: %v\n", dockerURI, err) 236 } 237 238 _, err = ocp.Pack() 239 240 if err != nil { 241 t.Fatalf("failed to Pack from %s: %v\n", dockerURI, err) 242 } 243 } 244 245 func getTestTar(url string) (path string, err error) { 246 dl, err := ioutil.TempFile("", "oci-test") 247 if err != nil { 248 log.Fatal(err) 249 } 250 defer dl.Close() 251 252 r, err := http.Get(url) 253 if err != nil { 254 return "", err 255 } 256 defer r.Body.Close() 257 258 _, err = io.Copy(dl, r.Body) 259 if err != nil { 260 return "", err 261 } 262 263 return dl.Name(), nil 264 }