github.com/uber/kraken@v0.1.4/tools/lib/image/image.go (about) 1 // Copyright (c) 2016-2019 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package image 15 16 import ( 17 "bytes" 18 "fmt" 19 "io" 20 "io/ioutil" 21 "log" 22 "math/rand" 23 "os" 24 "os/exec" 25 "path/filepath" 26 "strings" 27 "time" 28 ) 29 30 func run(name string, args ...string) error { 31 stderr := new(bytes.Buffer) 32 cmd := exec.Command(name, args...) 33 cmd.Stdout = os.Stdout 34 cmd.Stderr = stderr 35 if err := cmd.Run(); err != nil { 36 return fmt.Errorf("exec `%s`: %s, stderr:\n%s", 37 strings.Join(cmd.Args, " "), err, stderr.String()) 38 } 39 return nil 40 } 41 42 // Generate creates a random image. 43 func Generate(size uint64, numLayers int) (name string, err error) { 44 dir, err := ioutil.TempDir("", "") 45 if err != nil { 46 return "", fmt.Errorf("temp dir: %s", err) 47 } 48 defer os.RemoveAll(dir) 49 50 name = fmt.Sprintf("kraken-test-image-%s", filepath.Base(dir)) 51 52 dockerfile, err := os.Create(fmt.Sprintf("%s/Dockerfile", dir)) 53 if err != nil { 54 return "", fmt.Errorf("create dockerfile: %s", err) 55 } 56 log.Printf("Generating dockerfile %s", dockerfile.Name()) 57 58 if _, err := fmt.Fprintln(dockerfile, "FROM scratch"); err != nil { 59 return "", fmt.Errorf("fprint dockerfile: %s", err) 60 } 61 62 layerSize := size / uint64(numLayers) 63 for i := 0; i < numLayers; i++ { 64 f, err := os.Create(fmt.Sprintf("%s/file_%d", dir, i)) 65 if err != nil { 66 return "", fmt.Errorf("create file: %s", err) 67 } 68 r := io.LimitReader(rand.New(rand.NewSource(time.Now().Unix())), int64(layerSize)) 69 if _, err := io.Copy(f, r); err != nil { 70 return "", fmt.Errorf("copy rand: %s", err) 71 } 72 layerName := filepath.Base(f.Name()) 73 if _, err := fmt.Fprintf(dockerfile, "COPY %s /\n", layerName); err != nil { 74 return "", fmt.Errorf("fprint dockerfile: %s", err) 75 } 76 } 77 78 if err := run("sudo", "docker", "build", "-t", name, dir); err != nil { 79 return "", err 80 } 81 return name + ":latest", nil 82 } 83 84 // Push pushes an image to a Kraken proxy. 85 func Push(name string, proxy string) error { 86 proxyName := proxy + "/" + name 87 log.Printf("Pushing %s to %s", name, proxyName) 88 if err := run("sudo", "docker", "tag", name, proxyName); err != nil { 89 return err 90 } 91 return run("sudo", "docker", "push", proxyName) 92 }