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  }