github.com/cvmfs/docker-graphdriver@v0.0.0-20181206110523-155ec6df0521/docker2cvmfs/lib/pull.go (about) 1 package lib 2 3 import ( 4 "bytes" 5 "compress/gzip" 6 "fmt" 7 "io" 8 "io/ioutil" 9 //"log" 10 "net/http" 11 "os" 12 "os/exec" 13 "strings" 14 ) 15 16 func PullLayers(dockerRegistryUrl, inputReference, repository, subdirectory string) error { 17 manifest, err := getManifest(dockerRegistryUrl, inputReference) 18 if err != nil { 19 return err 20 } 21 image := strings.Split(inputReference, ":")[0] 22 23 destDir, err := ioutil.TempDir("", "docker2cvmfs_layers") 24 if err != nil { 25 return err 26 } 27 28 for _, layer := range manifest.Layers { 29 // TODO make use of cvmfsRepo and cvmfsSubDirectory 30 err := getLayer(dockerRegistryUrl, image, layer.Digest, destDir, repository, subdirectory) 31 if err != nil { 32 return err 33 } 34 } 35 return nil 36 } 37 38 func MakeRequestToRegistry(dockerRegistryUrl, repository, digest string) (*http.Response, error) { 39 url := dockerRegistryUrl + "/" + repository + "/blobs/" + digest 40 req, _ := http.NewRequest("GET", url, nil) 41 req.Header.Add("Authorization", "Bearer "+token) 42 var client http.Client 43 return client.Do(req) 44 } 45 46 func getLayer(dockerRegistryUrl, repository, digest, destDir, cvmfsRepo, cvmfsSubDirectory string) error { 47 hash := strings.Split(digest, ":")[1] 48 filename := hash + ".tar.gz" 49 50 file, err := os.Create(destDir + "/" + filename) 51 if err != nil { 52 fmt.Println("Impossible to create the file: ", filename, "\nerr: ", err) 53 return err 54 } 55 56 resp, err := MakeRequestToRegistry(dockerRegistryUrl, repository, digest) 57 58 if err != nil { 59 fmt.Println(err) 60 return err 61 } 62 63 var buf bytes.Buffer 64 tee := io.TeeReader(resp.Body, &buf) 65 66 _, err = io.Copy(file, tee) 67 if err != nil { 68 fmt.Println(err) 69 return err 70 } 71 72 uncompressed, err := gzip.NewReader(&buf) 73 if err != nil { 74 fmt.Println(err) 75 return err 76 } 77 cmd := exec.Command("cvmfs_server", "ingest", "-t", "-", "-b", cvmfsSubDirectory+hash, cvmfsRepo) 78 stdin, err := cmd.StdinPipe() 79 if err != nil { 80 return err 81 } 82 stdout, err := cmd.StdoutPipe() 83 if err != nil { 84 return err 85 } 86 stderr, err := cmd.StderrPipe() 87 if err != nil { 88 return err 89 } 90 err = cmd.Start() 91 92 go func() { 93 _, err := io.Copy(stdin, uncompressed) 94 if err != nil { 95 fmt.Println("Error in writing to stdin: ", err) 96 } 97 }() 98 99 if err != nil { 100 return err 101 } 102 103 slurpOut, err := ioutil.ReadAll(stdout) 104 105 slurpErr, err := ioutil.ReadAll(stderr) 106 107 err = cmd.Wait() 108 fmt.Println("STDOUT: ", string(slurpOut)) 109 fmt.Println("STDERR: ", string(slurpErr)) 110 fmt.Println("Wrote file to: ", filename) 111 file.Close() 112 resp.Body.Close() 113 return nil 114 }