-
Notifications
You must be signed in to change notification settings - Fork 687
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Flynn <[email protected]>
- Loading branch information
Showing
4 changed files
with
242 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"sort" | ||
"strings" | ||
) | ||
|
||
type DockerInspect struct { | ||
Id string | ||
RepoTags []string | ||
RepoDigests []string | ||
} | ||
|
||
func sort_u(in []string) []string { | ||
set := make(map[string]struct{}, len(in)) | ||
for _, item := range in { | ||
set[item] = struct{}{} | ||
} | ||
out := make([]string, 0, len(set)) | ||
for item := range set { | ||
out = append(out, item) | ||
} | ||
sort.Strings(out) | ||
return out | ||
} | ||
|
||
func Main() error { | ||
// 1. Get the "docker inspect" for all images | ||
bs, err := exec.Command("docker", "image", "ls", "--filter=dangling=false", "--format={{ .ID }}").Output() | ||
if err != nil { | ||
return err | ||
} | ||
ids := sort_u(strings.Split(strings.TrimSpace(string(bs)), "\n")) | ||
bs, err = exec.Command("docker", append([]string{"image", "inspect"}, ids...)...).Output() | ||
if err != nil { | ||
return err | ||
} | ||
var infos []DockerInspect | ||
if err := json.Unmarshal(bs, &infos); err != nil { | ||
return err | ||
} | ||
|
||
// 2. Decide what to do with each image | ||
workspacePull := make(map[string]struct{}) // pull these images from remote registries... | ||
workspaceTag := make(map[string]string) // ... then tag them with these names | ||
workspaceLoad := make(map[string]struct{}) // store these images locally with 'docker image save'/'docker image load' | ||
|
||
for _, info := range infos { | ||
b, _ := json.Marshal(info) | ||
fmt.Printf("- check %s: %s\n", info.Id, b) | ||
if len(info.RepoDigests) > 0 { | ||
repoDigest := info.RepoDigests[0] | ||
fmt.Printf(" - pull %s\n", repoDigest) | ||
workspacePull[repoDigest] = struct{}{} | ||
for _, tag := range info.RepoTags { | ||
fmt.Printf(" - tag %s\n", tag) | ||
workspaceTag[tag] = info.Id | ||
} | ||
} else { | ||
for _, tag := range info.RepoTags { | ||
fmt.Printf(" - load %s\n", tag) | ||
workspaceLoad[tag] = struct{}{} | ||
} | ||
} | ||
} | ||
|
||
// 3. Record and do those things | ||
|
||
// Write the pull/tag steps to a file | ||
err = func() error { | ||
var lines []string | ||
for pull := range workspacePull { | ||
lines = append(lines, fmt.Sprintf("docker image pull %s\n", pull)) | ||
} | ||
for tag, id := range workspaceTag { | ||
lines = append(lines, fmt.Sprintf("docker image tag %s %s\n", id, tag)) | ||
} | ||
sort.Strings(lines) // NB: relying on "pull" sorting before "tag" | ||
|
||
lines = append([]string{ | ||
"#!/usr/bin/env bash\n", | ||
"set -ex\n", | ||
}, lines...) | ||
|
||
restoreSh, err := os.OpenFile("docker/images.sh", os.O_CREATE|os.O_WRONLY, 0777) | ||
if err != nil { | ||
return err | ||
} | ||
defer restoreSh.Close() | ||
for _, line := range lines { | ||
if _, err := io.WriteString(restoreSh, line); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
}() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Run 'docker image save' | ||
err = func() error { | ||
localImages := make([]string, 0, len(workspaceLoad)) | ||
for image := range workspaceLoad { | ||
fmt.Printf("- save %s\n", image) | ||
localImages = append(localImages, image) | ||
} | ||
sort.Strings(localImages) | ||
|
||
fmt.Printf("local images:\n") | ||
for _, image := range localImages { | ||
fmt.Printf("- %s\n", image) | ||
} | ||
|
||
restoreTar, err := os.OpenFile("docker/images.tar", os.O_CREATE|os.O_WRONLY, 0666) | ||
if err != nil { | ||
return err | ||
} | ||
defer restoreTar.Close() | ||
|
||
cmd := exec.Command("docker", append([]string{"image", "save"}, localImages...)...) | ||
cmd.Stdout = restoreTar | ||
cmd.Stderr = os.Stderr | ||
|
||
if err := cmd.Run(); err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
}() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func main() { | ||
if err := Main(); err != nil { | ||
fmt.Fprintf(os.Stderr, "%s: error: %v\n", filepath.Base(os.Args[0]), err) | ||
os.Exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env bash | ||
set -ex | ||
|
||
# Load the images | ||
docker image load < docker/images.tar | ||
./docker/images.sh | ||
|
||
stamp_docker () { | ||
tag="$1" | ||
stamp_base="$2" | ||
|
||
hash=$(docker image inspect --format='{{ .Id }}' "$tag") | ||
|
||
for stamp_file in ".$stamp_base.docker.stamp" "$stamp_base.docker" "$stamp_base.docker.tag.local"; do | ||
echo "Stamping $tag as docker/$stamp_file" | ||
echo "$hash" > "docker/$stamp_file" | ||
# sleep 1 | ||
done | ||
|
||
tag_file="docker/$stamp_base.docker.tag.local" | ||
echo "Adding tag to $tag_file" | ||
echo "$tag" >> "$tag_file" | ||
} | ||
|
||
stamp_image () { | ||
tag="$1" | ||
stamp_base="$2" | ||
|
||
hash=$(docker image inspect --format='{{ .Id }}' "$tag") | ||
|
||
for tarfile in "docker/$stamp_base.img.tar" "docker/.$stamp_base.img.tar.stamp"; do | ||
echo "Copying $tag to $tarfile" | ||
docker save "$tag" > "$tarfile" | ||
done | ||
} | ||
|
||
# ORDER MATTERS HERE | ||
stamp_image frolvlad/alpine-glibc:alpine-3.15 base # This MUST be frolvlad, not emissary.local/base | ||
stamp_image emissary.local/kat-client kat-client | ||
stamp_image emissary.local/kat-server kat-server | ||
|
||
stamp_docker emissary.local/base-envoy base-envoy | ||
stamp_docker emissary.local/base-python base-python | ||
stamp_docker emissary.local/base-pip base-pip | ||
stamp_docker emissary.local/base base | ||
stamp_docker emissary.local/emissary emissary | ||
stamp_docker emissary.local/kat-client kat-client | ||
stamp_docker emissary.local/kat-server kat-server | ||
|
||
# # Resume the build container | ||
# if [[ -z "$DEV_REGISTRY" ]]; then | ||
# export DEV_REGISTRY=127.0.0.1:31000 | ||
# export BASE_REGISTRY=docker.io/datawiredev | ||
# fi | ||
# rm -f docker/container.txt docker/container.txt.stamp | ||
# make docker/container.txt | ||
# docker run \ | ||
# --rm \ | ||
# --volume=/var/run/docker.sock:/var/run/docker.sock \ | ||
# --user=root \ | ||
# --entrypoint=rsync $(cat docker/snapshot.docker) \ | ||
# -a -xx --exclude=/etc/{resolv.conf,hostname,hosts} --delete \ | ||
# --blocking-io -e 'docker exec -i --user=root' / "$(cat docker/container.txt):/" | ||
# docker exec "$(cat docker/container.txt)" rm -f /buildroot/image.dirty | ||
# # Load the cache volume | ||
# docker run \ | ||
# --rm \ | ||
# --volumes-from=$(cat docker/container.txt) \ | ||
# --volume="$PWD/docker":/mnt \ | ||
# --user=root \ | ||
# --workdir=/home/dw \ | ||
# --entrypoint=tar $(cat docker/snapshot.docker) -xf /mnt/volume.tar | ||
# rm -f docker/volume.tar |