Skip to content

Instantly share code, notes, and snippets.

@jonjohnsonjr
Last active December 4, 2021 02:18
Show Gist options
  • Save jonjohnsonjr/66c3b5bc75a2bf69e0524d823e3f7228 to your computer and use it in GitHub Desktop.
Save jonjohnsonjr/66c3b5bc75a2bf69e0524d823e3f7228 to your computer and use it in GitHub Desktop.
run

run

Outputs the equivalent argv of what you would get with a docker run command.

This considers the given image's CMD, ENTRYPOINT, and docker run's --entrypoint flag.

$ run hello-world@sha256:96ebeec770e1af26469c98913277e1c3b40933202ca398cefc16177c3f26cc75
["cmd","/C","type C:\\hello.txt"]

$ run --entrypoint /crane hello-world@sha256:96ebeec770e1af26469c98913277e1c3b40933202ca398cefc16177c3f26cc75
["/crane"]

$ run hello-world@sha256:96ebeec770e1af26469c98913277e1c3b40933202ca398cefc16177c3f26cc75 crane
["crane"]

$ run gcr.io/go-containerregistry/crane version
["/ko-app/crane","version"]

$ run --entrypoint '["crane", "ls"]' gcr.io/go-containerregistry/crane ubuntu
["crane","ls","ubuntu"]
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"github.com/google/go-containerregistry/pkg/crane"
flag "github.com/spf13/pflag"
)
var entrypoint string
func init() {
flag.StringVar(&entrypoint, "entrypoint", "", "Overwrite the default ENTRYPOINT of the image")
flag.Parse()
}
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
args := flag.Args()
if len(args) < 1 {
return errors.New("no args")
}
img, err := crane.Pull(args[0])
if err != nil {
return err
}
cf, err := img.ConfigFile()
if err != nil {
return err
}
exec := []string{}
if entrypoint != "" {
b := []byte(entrypoint)
p := make([]string, 0, 1)
if err := json.Unmarshal(b, &p); err == nil {
cf.Config.Entrypoint = p
} else {
cf.Config.Entrypoint = []string{entrypoint}
}
cf.Config.Cmd = nil
}
exec = append(exec, cf.Config.Entrypoint...)
if len(args) > 1 {
exec = append(exec, args[1:]...)
} else if len(cf.Config.Cmd) > 0 {
exec = append(exec, cf.Config.Cmd...)
}
b, err := json.Marshal(exec)
if err != nil {
return err
}
fmt.Println(string(b))
return nil
}
@jonjohnsonjr
Copy link
Author

But here's the one that might surprise you! 🤯

Yes! This is what kept tripping me up. As was explained to me, the CMD depends on the ENTRYPOINT, because we're just supplying args to the entrypoint binary. If we replace the entrypoint, those args should be invalidated.

Your summary is perfect -- I couldn't understand why you would use one approach over the other, but it comes down to whether you treat a container as a process or an environment in which to run processes.

@subfuzion
Copy link

...it comes down to whether you treat a container as a process or an environment in which to run processes.

Nice! I think you condensed everything into the ideal one-line summary. I'm going to use that! 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment