Skip to content

Commit

Permalink
pull docker images which are not already present
Browse files Browse the repository at this point in the history
  • Loading branch information
steiler committed Sep 30, 2020
1 parent 55b10c1 commit cf2f56d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
2 changes: 1 addition & 1 deletion clab/clab.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"sync"
"time"

docker "github.com/docker/engine/client"
docker "github.com/docker/docker/client"
)

// var debug bool
Expand Down
57 changes: 57 additions & 0 deletions clab/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"os/exec"
"strconv"
"strings"
Expand Down Expand Up @@ -144,6 +146,12 @@ func (c *cLab) CreateContainer(ctx context.Context, node *Node) (err error) {
if node.Group != "" {
labels["group"] = node.Group
}

err = c.PullImageIfRequired(nctx, node)
if err != nil {
return err
}

cont, err := c.DockerClient.ContainerCreate(nctx,
&container.Config{
Image: node.Image,
Expand Down Expand Up @@ -179,6 +187,55 @@ func (c *cLab) CreateContainer(ctx context.Context, node *Node) (err error) {
return createContainerNS(node.Pid, node.LongName)
}

func (c *cLab) PullImageIfRequired(ctx context.Context, node *Node) (err error) {
filter := filters.NewArgs()
filter.Add("reference", node.Image)

ilo := types.ImageListOptions{
All: false,
Filters: filter,
}

log.Debugf("Looking up %s Docker image", node.Image)

images, err := c.DockerClient.ImageList(ctx, ilo)
if err != nil {
return err
}

// If Image doesn't exist, we need to pull it
if len(images) > 0 {
log.Debugf("Image %s present, skip pulling", node.Image)
return nil
}

// might need canonical name e.g.
// -> alpine == docker.io/library/alpine
// -> foo/bar == docker.io/foo/bar
// -> docker.elastic.co/elasticsearch/elasticsearch == docker.elastic.co/elasticsearch/elasticsearch
canonicalImageName := node.Image
slashCount := strings.Count(node.Image, "/")

switch slashCount {
case 0:
canonicalImageName = "docker.io/library/" + node.Image
case 1:
canonicalImageName = "docker.io/" + node.Image
}

log.Infof("Pulling %s Docker image", node.Image)
reader, err := c.DockerClient.ImagePull(ctx, canonicalImageName, types.ImagePullOptions{})
if err != nil {
return err
}
defer reader.Close()
// must read from reader, otherwise image is not properly pulled
io.Copy(ioutil.Discard, reader)
log.Infof("Done pulling %s", canonicalImageName)

return nil
}

// StartContainer starts a docker container
func (c *cLab) StartContainer(ctx context.Context, id string) error {
nctx, cancel := context.WithTimeout(ctx, c.timeout)
Expand Down
2 changes: 1 addition & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Containerlab is distributed as Linux package and can be installed on any Debian-
### Pre-requisites
* Have `sudo` rights on the system: `containerlab` sets some parameters in the linux system to support the various options the containers need
* [Install docker](https://docs.docker.com/engine/install/): this is used to manage the containers
* Pull the container images which you intend to run to the Linux system
* Import or Pull container images (e.g. Nokia SR-Linux, Arista cEOS) which are not online available for download from a registry. Containerlab will try to pull images if they do not exist on execution time.

### Package installation
Containerlab package can be installed using the [installer script](https://github.com/srl-wim/container-lab/blob/master/get.sh) which detects the operating system type and installs the relevant package:
Expand Down

0 comments on commit cf2f56d

Please sign in to comment.