Created
April 24, 2025 15:35
-
-
Save jdolitsky/287c9fac635c53209b9bd671d84df6df to your computer and use it in GitHub Desktop.
Get the size of a container image (the linux/amd64 platform-specific image)
This file contains hidden or 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
package main | |
import ( | |
"fmt" | |
"log" | |
"os" | |
"github.com/google/go-containerregistry/pkg/authn" | |
"github.com/google/go-containerregistry/pkg/name" | |
v1 "github.com/google/go-containerregistry/pkg/v1" | |
"github.com/google/go-containerregistry/pkg/v1/remote" | |
) | |
// Given a string reference to an remote image, fetch the manifest | |
func fetchImageManifest(img string) (*v1.Manifest, error) { | |
ref, err := name.ParseReference(img) | |
if err != nil { | |
return nil, err | |
} | |
oimg, err := remote.Image(ref, // TODO: allow alternate platform? | |
remote.WithPlatform(v1.Platform{OS: "linux", Architecture: "amd64"}), | |
remote.WithAuthFromKeychain(authn.DefaultKeychain), | |
) | |
if err != nil { | |
return nil, err | |
} | |
return oimg.Manifest() | |
} | |
// Given a manifest, get size (size of manifest plus size of each layer) | |
func calculateSize(manifest *v1.Manifest) (int64, error) { | |
size := manifest.Config.Size | |
for _, layer := range manifest.Layers { | |
size += layer.Size | |
} | |
return size, nil | |
} | |
// Convert a size to human readable format | |
// Adapted from https://yourbasic.org/golang/formatting-byte-size-to-human-readable-format/ | |
func humanReadable(b int64) string { | |
if b < 1024 { | |
return fmt.Sprintf("%d B", b) | |
} | |
div, exp := 1024, 0 | |
for n := b / 1024; n >= 1024; n /= 1024 { | |
div *= 1024 | |
exp++ | |
} | |
return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp]) | |
} | |
func main() { | |
args := os.Args | |
if len(args) != 2 { | |
log.Fatal("Usage: go run . <img>") | |
} | |
img := args[1] | |
manifest, err := fetchImageManifest(img) | |
if err != nil { | |
log.Fatalf("fetching image manifest: %v", err) | |
} | |
size, err := calculateSize(manifest) | |
if err != nil { | |
log.Fatalf("calculating size: %v", err) | |
} | |
fmt.Println(humanReadable(size)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment