Docker pull без docker
Команда запуска:
./script dirName “http://localhost:8081/link/to/docker/registry” myAwesomeImage 1.0
Пример кода:
package main
import (
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
)
func main() {
downloadDir := os.Args[1]
url := os.Args[2]
imageName := os.Args[3]
tag := os.Args[4]
layers := getLayers(url, imageName, tag)
for _, layer := range layers {
fmt.Println("Downloading", layer)
downloadLayer(url, imageName, layer, downloadDir)
}
untarLayers(downloadDir)
fmt.Println("Download completed successfully")
}
func getLayers(url, imageName, tag string) []string {
resp, err := http.Get(fmt.Sprintf("%s/v2/%s/manifests/%s", url, imageName, tag))
if err != nil {
panic(err)
}
defer resp.Body.Close()
var layers []string
for _, header := range resp.Header.Values("Docker-Content-Digest") {
if strings.HasPrefix(header, "sha256:") {
layers = append(layers, header[7:])
}
}
return layers
}
func downloadLayer(url, imageName, layer, downloadDir string) {
resp, err := http.Get(fmt.Sprintf("%s/v2/%s/blobs/%s", url, imageName, layer))
if err != nil {
panic(err)
}
defer resp.Body.Close()
filePath := filepath.Join(downloadDir, layer+".tar")
file, err := os.Create(filePath)
if err != nil {
panic(err)
}
defer file.Close()
_, err = io.Copy(file, resp.Body)
if err != nil {
panic(err)
}
}
func untarLayers(downloadDir string) {
err := filepath.Walk(downloadDir, func(path string, info os.FileInfo, err error) error {
if strings.HasSuffix(info.Name(), ".tar") {
cmd := exec.Command("tar", "xvf", path, "-C", downloadDir)
err := cmd.Run()
if err != nil {
return err
}
}
return nil
})
if err != nil {
panic(err)
}
err = filepath.Walk(downloadDir, func(path string, info os.FileInfo, err error) error {
if strings.HasSuffix(info.Name(), ".tar") {
err := os.Remove(path)
if err != nil {
return err
}
}
return nil
})
if err != nil {
panic(err)
}
}