Skip to content
This repository has been archived by the owner on Mar 13, 2021. It is now read-only.

riff image load #819

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ test:

gen-mocks:
mockery -output pkg/core/mocks -outpkg mocks -dir pkg/core -name Client
mockery -output pkg/core/mocks -outpkg mocks -dir pkg/core -name ImageClient
mockery -output pkg/core/vendor_mocks -outpkg vendor_mocks -dir vendor/k8s.io/client-go/kubernetes -name Interface
mockery -output pkg/core/vendor_mocks -outpkg vendor_mocks -dir vendor/k8s.io/client-go/kubernetes/typed/core/v1 -name CoreV1Interface
mockery -output pkg/core/vendor_mocks -outpkg vendor_mocks -dir vendor/k8s.io/client-go/kubernetes/typed/core/v1 -name NamespaceInterface
mockery -output pkg/core/vendor_mocks -outpkg vendor_mocks -dir vendor/k8s.io/client-go/kubernetes/typed/core/v1 -name ServiceAccountInterface
mockery -output pkg/core/vendor_mocks -outpkg vendor_mocks -dir vendor/k8s.io/client-go/kubernetes/typed/core/v1 -name SecretInterface
mockery -output pkg/docker/mocks -outpkg mocks -dir pkg/docker -name Docker

install: build
cp $(OUTPUT) $(GOBIN)
Expand Down
45 changes: 43 additions & 2 deletions cmd/commands/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func Image() *cobra.Command {
}
}

func ImageRelocate(c *core.Client) *cobra.Command {
func ImageRelocate(c *core.ImageClient) *cobra.Command {
options := core.RelocateImagesOptions{}

command := &cobra.Command{
Expand Down Expand Up @@ -119,14 +119,55 @@ func ImageRelocate(c *core.Client) *cobra.Command {
return command
}

func ImageLoad(c *core.ImageClient) *cobra.Command {
options := core.LoadAndTagImagesOptions{}

command := &cobra.Command{
Use: "load",
Short: "Load and tag docker images",
Long: "Load the set of images identified by the provided image manifest into a docker daemon.\n\n" +
"NOTE: This command requires the `docker` command line tool, as well as a (local) docker daemon.\n\n"+
"SEE ALSO: To load, tag, and push images, use `riff image push`.",
Example: ` riff image load --images=riff-distro-xx/image-manifest.yaml`,
PreRunE: func(cmd *cobra.Command, args []string) error {
// FIXME: these flags should not apply to this command: https://github.com/projectriff/riff/issues/743
if cmd.Flags().Changed("kubeconfig") {
return errors.New("the 'kubeconfig' flag is not supported by the 'image load' command")
}
m, _ := cmd.Flags().GetString("master")
if len(m) > 0 {
return errors.New("the 'master' flag is not supported by the 'image load' command")
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
err := (*c).LoadAndTagImages(options)
if err != nil {
return err
}

PrintSuccessfulCompletion(cmd)
return nil
},
}
command.Flags().StringVarP(&options.Images, "images", "i", "", "path of an image manifest of image names to be loaded")
command.MarkFlagRequired("images")
command.MarkFlagFilename("images", "yml", "yaml")

return command
}


func ImagePush(c *core.ImageClient) *cobra.Command {
options := core.PushImagesOptions{}

command := &cobra.Command{
Use: "push",
Short: "Push (relocated) docker image names to an image registry",
Long: "Push the set of images identified by the provided image manifest into a remote registry, for later consumption by `riff system install`.\n\n" +
"NOTE: This command requires the `docker` command line tool, as well as a (local) docker daemon and will load and tag the images using that daemon.",
"NOTE: This command requires the `docker` command line tool, as well as a (local) docker daemon and will load and tag the images using that daemon.\n\n"+
"SEE ALSO: To load and tag images, but not push them, use `riff image load`.",
Example: ` riff image push --images=riff-distro-xx/image-manifest.yaml`,
RunE: func(cmd *cobra.Command, args []string) error {
err := (*c).PushImages(options)
Expand Down
10 changes: 5 additions & 5 deletions cmd/commands/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
var _ = Describe("The riff image relocate command", func() {
Context("when given wrong args or flags", func() {
var (
mockClient core.Client
mockClient core.ImageClient
cc *cobra.Command
)

Expand Down Expand Up @@ -67,15 +67,15 @@ var _ = Describe("The riff image relocate command", func() {

Context("when given suitable flags", func() {
var (
client core.Client
asMock *mocks.Client
client core.ImageClient
asMock *mocks.ImageClient
sc *cobra.Command
err error
)

BeforeEach(func() {
client = new(mocks.Client)
asMock = client.(*mocks.Client)
client = new(mocks.ImageClient)
asMock = client.(*mocks.ImageClient)

sc = commands.ImageRelocate(&client)
})
Expand Down
3 changes: 2 additions & 1 deletion cmd/commands/wiring.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ See https://projectriff.io and https://github.com/knative/docs`,

image := Image()
image.AddCommand(
ImageRelocate(&client),
ImageRelocate(&imageClient),
ImageLoad(&imageClient),
ImagePush(&imageClient),
)

Expand Down
1 change: 1 addition & 0 deletions docs/riff_image.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Interact with docker images
### SEE ALSO

* [riff](riff.md) - Commands for creating and managing function resources
* [riff image load](riff_image_load.md) - Load and tag docker images
* [riff image push](riff_image_push.md) - Push (relocated) docker image names to an image registry
* [riff image relocate](riff_image_relocate.md) - Relocate docker image names to another registry

33 changes: 33 additions & 0 deletions docs/riff_image_load.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## riff image load

Load and tag docker images

### Synopsis

Load the set of images identified by the provided image manifest into a docker daemon.

NOTE: This command requires the `docker` command line tool, as well as a (local) docker daemon.

SEE ALSO: To load, tag, and push images, use `riff image push`.

```
riff image load [flags]
```

### Examples

```
riff image load --images=riff-distro-xx/image-manifest.yaml
```

### Options

```
-h, --help help for load
-i, --images string path of an image manifest of image names to be loaded
```

### SEE ALSO

* [riff image](riff_image.md) - Interact with docker images

2 changes: 2 additions & 0 deletions docs/riff_image_push.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Push the set of images identified by the provided image manifest into a remote r

NOTE: This command requires the `docker` command line tool, as well as a (local) docker daemon and will load and tag the images using that daemon.

SEE ALSO: To load and tag images, but not push them, use `riff image load`.

```
riff image push [flags]
```
Expand Down
2 changes: 0 additions & 2 deletions pkg/core/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ type Client interface {
DeleteService(options DeleteServiceOptions) error
ServiceStatus(options ServiceStatusOptions) (*v1alpha1.ServiceCondition, error)
ServiceCoordinates(options ServiceInvokeOptions) (ingressIP string, hostName string, err error)

RelocateImages(options RelocateImagesOptions) error
}

type client struct {
Expand Down
4 changes: 4 additions & 0 deletions pkg/core/fixtures/image_client/complete.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Images:
a/b: "1"
c/d: "2"
manifestVersion: "0.1"
4 changes: 4 additions & 0 deletions pkg/core/fixtures/image_client/incomplete.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
manifestVersion: 0.1
images:
"a/b": "1"
"c/d":
2 changes: 1 addition & 1 deletion pkg/core/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type RelocateImagesOptions struct {
Images string
}

func (c *client) RelocateImages(options RelocateImagesOptions) error {
func (c *imageClient) RelocateImages(options RelocateImagesOptions) error {
imageMapper, err := createImageMapper(options)
if err != nil {
return err
Expand Down
42 changes: 34 additions & 8 deletions pkg/core/image_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@ import (
)

type ImageClient interface {
LoadAndTagImages(options LoadAndTagImagesOptions) error
PushImages(options PushImagesOptions) error
PullImages(options PullImagesOptions) error
RelocateImages(options RelocateImagesOptions) error
}

type PushImagesOptions struct {
Images string
}

type LoadAndTagImagesOptions struct {
Images string
}

type PullImagesOptions struct {
Images string
Output string
Expand All @@ -44,22 +50,42 @@ type imageClient struct {
docker docker.Docker
}

// TODO: provide unit test
func (c *imageClient) LoadAndTagImages(options LoadAndTagImagesOptions) error {
_, err := c.loadAndTagImages(options.Images)
return err
}

func (c *imageClient) PushImages(options PushImagesOptions) error {
imManifest, err := NewImageManifest(options.Images)
imManifest, err := c.loadAndTagImages(options.Images)
if err != nil {
return err
}
distroLocation := filepath.Dir(options.Images)
for name, digest := range imManifest.Images {
filename := filepath.Join(distroLocation, "images", string(digest))
if err := c.docker.PushImage(string(name), string(digest), filename); err != nil {
for name, _ := range imManifest.Images {
if err := c.docker.PushImage(string(name)); err != nil {
return err
}
}
return nil
}

func (c *imageClient) loadAndTagImages(imageManifest string) (*ImageManifest, error) {
imManifest, err := NewImageManifest(imageManifest)
if err != nil {
return nil, err
}
distroLocation := filepath.Dir(imageManifest)
for name, digest := range imManifest.Images {
if digest == "" {
return nil, fmt.Errorf("image manifest %s does not specify a digest for image %s", imageManifest, name)
}
filename := filepath.Join(distroLocation, "images", string(digest))
if err := c.docker.LoadAndTagImage(string(name), string(digest), filename); err != nil {
return nil, err
}
}
return imManifest, nil
}

func (c *imageClient) PullImages(options PullImagesOptions) error {
originalManifest, err := NewImageManifest(options.Images)
if err != nil {
Expand All @@ -74,7 +100,7 @@ func (c *imageClient) PullImages(options PullImagesOptions) error {
newManifestPath = filepath.Join(options.Output, "image-manifest.yaml")
imagesDir = filepath.Join(options.Output, "images")
}
if _, err := os.Stat(imagesDir); err != nil && os.IsNotExist(err) {
if _, err := os.Stat(imagesDir); err != nil {
if err2 := os.MkdirAll(imagesDir, outputDirPermissions); err2 != nil {
return err2
}
Expand All @@ -86,7 +112,7 @@ func (c *imageClient) PullImages(options PullImagesOptions) error {
if newSha, err := c.docker.PullImage(string(name), imagesDir); err != nil {
return err
} else if newSha != string(sha) && sha != "" && !options.ContinueOnMismatch {
return fmt.Errorf("image %q had digest %v in the original manifest, but the pulled version now has digest %s", name, sha, newSha)
return fmt.Errorf("image %q had digest %v in the original manifest, but the pulled version has digest %s", name, sha, newSha)
} else {
newManifest.Images[name] = imageDigest(newSha)
}
Expand Down
Loading