Skip to content

Commit

Permalink
Add also stand-alone image push matching pull
Browse files Browse the repository at this point in the history
Normally this is done as part of image build
  • Loading branch information
afbjorklund committed Aug 22, 2021
1 parent 380b846 commit 817f8b4
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 0 deletions.
19 changes: 19 additions & 0 deletions cmd/minikube/cmd/image.go
Expand Up @@ -285,6 +285,24 @@ $ minikube image tag source target
},
}

var pushImageCmd = &cobra.Command{
Use: "push",
Short: "Push images",
Example: `
$ minikube image push busybox
`,
Run: func(cmd *cobra.Command, args []string) {
profile, err := config.LoadProfile(viper.GetString(config.ProfileName))
if err != nil {
exit.Error(reason.Usage, "loading profile", err)
}

if err := machine.PushImages(args, profile); err != nil {
exit.Error(reason.GuestImagePush, "Failed to push images", err)
}
},
}

func init() {
loadImageCmd.Flags().BoolVarP(&pull, "pull", "", false, "Pull the remote image (no caching)")
loadImageCmd.Flags().BoolVar(&imgDaemon, "daemon", false, "Cache image from docker daemon")
Expand All @@ -301,4 +319,5 @@ func init() {
imageCmd.AddCommand(buildImageCmd)
imageCmd.AddCommand(listImageCmd)
imageCmd.AddCommand(tagImageCmd)
imageCmd.AddCommand(pushImageCmd)
}
9 changes: 9 additions & 0 deletions pkg/minikube/cruntime/containerd.go
Expand Up @@ -422,6 +422,15 @@ func (r *Containerd) BuildImage(src string, file string, tag string, push bool,
return nil
}

// PushImage pushes an image
func (r *Containerd) PushImage(name string) error {
klog.Infof("Pushing image %s: %s", name)
c := exec.Command("sudo", "ctr", "-n=k8s.io", "images", "push", name)
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrapf(err, "ctr images push")
}
return nil
}
func (r *Containerd) initBuildkitDaemon() error {
// if daemon is already running, do nothing
cmd := exec.Command("pgrep", "buildkitd")
Expand Down
10 changes: 10 additions & 0 deletions pkg/minikube/cruntime/crio.go
Expand Up @@ -260,6 +260,16 @@ func (r *CRIO) BuildImage(src string, file string, tag string, push bool, env []
return nil
}

// PushImage pushes an image
func (r *CRIO) PushImage(name string) error {
klog.Infof("Pushing image %s", name)
c := exec.Command("sudo", "podman", "push", name)
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "crio push image")
}
return nil
}

// CGroupDriver returns cgroup driver ("cgroupfs" or "systemd")
func (r *CRIO) CGroupDriver() (string, error) {
c := exec.Command("crio", "config")
Expand Down
2 changes: 2 additions & 0 deletions pkg/minikube/cruntime/cruntime.go
Expand Up @@ -103,6 +103,8 @@ type Manager interface {
SaveImage(string, string) error
// Tag an image
TagImage(string, string) error
// Push an image from the runtime to the container registry
PushImage(string) error

// ImageExists takes image name and image sha checks if an it exists
ImageExists(string, string) bool
Expand Down
10 changes: 10 additions & 0 deletions pkg/minikube/cruntime/docker.go
Expand Up @@ -288,6 +288,16 @@ func (r *Docker) BuildImage(src string, file string, tag string, push bool, env
return nil
}

// PushImage pushes an image
func (r *Docker) PushImage(name string) error {
klog.Infof("Pushing image: %s", name)
c := exec.Command("docker", "push", name)
if _, err := r.Runner.RunCmd(c); err != nil {
return errors.Wrap(err, "push image docker.")
}
return nil
}

// CGroupDriver returns cgroup driver ("cgroupfs" or "systemd")
func (r *Docker) CGroupDriver() (string, error) {
// Note: the server daemon has to be running, for this call to return successfully
Expand Down
81 changes: 81 additions & 0 deletions pkg/minikube/machine/cache_images.go
Expand Up @@ -596,3 +596,84 @@ func TagImage(profile *config.Profile, source string, target string) error {
klog.Infof("failed tagging in: %s", strings.Join(failed, " "))
return nil
}

// pushImages pushes images from the container run time
func pushImages(cruntime cruntime.Manager, images []string) error {
klog.Infof("PushImages start: %s", images)
start := time.Now()

defer func() {
klog.Infof("PushImages completed in %s", time.Since(start))
}()

var g errgroup.Group

for _, image := range images {
image := image
g.Go(func() error {
return cruntime.PushImage(image)
})
}
if err := g.Wait(); err != nil {
return errors.Wrap(err, "error pushing images")
}
klog.Infoln("Successfully pushed images")
return nil
}

// PushImages push images on all nodes in profile
func PushImages(images []string, profile *config.Profile) error {
api, err := NewAPIClient()
if err != nil {
return errors.Wrap(err, "error creating api client")
}
defer api.Close()

succeeded := []string{}
failed := []string{}

pName := profile.Name

c, err := config.Load(pName)
if err != nil {
klog.Errorf("Failed to load profile %q: %v", pName, err)
return errors.Wrapf(err, "error loading config for profile :%v", pName)
}

for _, n := range c.Nodes {
m := config.MachineName(*c, n)

status, err := Status(api, m)
if err != nil {
klog.Warningf("error getting status for %s: %v", m, err)
continue
}

if status == state.Running.String() {
h, err := api.Load(m)
if err != nil {
klog.Warningf("Failed to load machine %q: %v", m, err)
continue
}
runner, err := CommandRunner(h)
if err != nil {
return err
}
cruntime, err := cruntime.New(cruntime.Config{Type: c.KubernetesConfig.ContainerRuntime, Runner: runner})
if err != nil {
return errors.Wrap(err, "error creating container runtime")
}
err = pushImages(cruntime, images)
if err != nil {
failed = append(failed, m)
klog.Warningf("Failed to push image for profile %s %v", pName, err.Error())
continue
}
succeeded = append(succeeded, m)
}
}

klog.Infof("succeeded pushing in: %s", strings.Join(succeeded, " "))
klog.Infof("failed pushing in: %s", strings.Join(failed, " "))
return nil
}
2 changes: 2 additions & 0 deletions pkg/minikube/reason/reason.go
Expand Up @@ -317,6 +317,8 @@ var (
GuestImageRemove = Kind{ID: "GUEST_IMAGE_REMOVE", ExitCode: ExGuestError}
// minikube failed to pull an image
GuestImagePull = Kind{ID: "GUEST_IMAGE_PULL", ExitCode: ExGuestError}
// minikube failed to push an image
GuestImagePush = Kind{ID: "GUEST_IMAGE_PUSH", ExitCode: ExGuestError}
// minikube failed to build an image
GuestImageBuild = Kind{ID: "GUEST_IMAGE_BUILD", ExitCode: ExGuestError}
// minikube failed to tag an image
Expand Down
42 changes: 42 additions & 0 deletions site/content/en/docs/commands/image.md
Expand Up @@ -258,6 +258,48 @@ $ minikube image pull busybox
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
```

## minikube image push

Push images

### Synopsis

Push images

```shell
minikube image push [flags]
```

### Examples

```
$ minikube image push busybox
```

### Options inherited from parent commands

```
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files
-b, --bootstrapper string The name of the cluster bootstrapper that will set up the Kubernetes cluster. (default "kubeadm")
-h, --help
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files
--one_output If true, only write logs to their native severity level (vs also writing to each lower severity level)
-p, --profile string The name of the minikube VM being used. This can be set to allow having multiple instances of minikube independently. (default "minikube")
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--user string Specifies the user executing the operation. Useful for auditing operations executed by 3rd party tools. Defaults to the operating system username.
-v, --v Level number for the log level verbosity
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
```

## minikube image rm

Remove one or more images
Expand Down
3 changes: 3 additions & 0 deletions site/content/en/docs/contrib/errorcodes.en.md
Expand Up @@ -381,6 +381,9 @@ minikube failed to remove an image
"GUEST_IMAGE_PULL" (Exit code ExGuestError)
minikube failed to pull an image

"GUEST_IMAGE_PUSH" (Exit code ExGuestError)
minikube failed to push an image

"GUEST_IMAGE_BUILD" (Exit code ExGuestError)
minikube failed to build an image

Expand Down
2 changes: 2 additions & 0 deletions translations/strings.txt
Expand Up @@ -236,6 +236,7 @@
"Failed to persist images": "",
"Failed to pull image": "",
"Failed to pull images": "",
"Failed to push images": "",
"Failed to reload cached images": "",
"Failed to remove image": "",
"Failed to save config {{.profile}}": "",
Expand Down Expand Up @@ -439,6 +440,7 @@
"Pull images": "",
"Pull the remote image (no caching)": "",
"Pulling base image ...": "",
"Push images": "",
"Push the new image (requires tag)": "",
"Reboot to complete VirtualBox installation, verify that VirtualBox is not blocked by your system, and/or use another hypervisor": "",
"Rebuild libvirt with virt-network support": "",
Expand Down

0 comments on commit 817f8b4

Please sign in to comment.