diff --git a/config/config.go b/config/config.go index 0a09229..f0405c8 100644 --- a/config/config.go +++ b/config/config.go @@ -21,8 +21,8 @@ const ( var NameFilter = regexp.MustCompile(PWDHostPortGroupRegex) var AliasFilter = regexp.MustCompile(AliasPortGroupRegex) -var PortNumber, Key, Cert, SessionsFile, PWDContainerName, L2ContainerName, L2Subdomain, PWDCName, HashKey, SSHKeyPath, L2RouterIP string -var UseLetsEncrypt bool +var PortNumber, Key, Cert, SessionsFile, PWDContainerName, L2ContainerName, L2Subdomain, PWDCName, HashKey, SSHKeyPath, L2RouterIP, DindVolumeSize string +var UseLetsEncrypt, ExternalDindVolume bool var LetsEncryptCertsDir string var LetsEncryptDomains stringslice var MaxLoadAvg float64 @@ -53,6 +53,8 @@ func ParseFlags() { flag.StringVar(&L2Subdomain, "l2-subdomain", "direct", "Subdomain to the L2 Router") flag.StringVar(&PWDCName, "cname", "", "CNAME given to this host") flag.StringVar(&HashKey, "hash_key", "salmonrosado", "Hash key to use for cookies") + flag.StringVar(&DindVolumeSize, "dind-volume-size", "5G", "Dind volume folder size") + flag.BoolVar(&ExternalDindVolume, "external-dind-volume", false, "Use external dind volume") flag.Float64Var(&MaxLoadAvg, "maxload", 100, "Maximum allowed load average before failing ping requests") flag.StringVar(&SSHKeyPath, "ssh_key_path", "", "SSH Private Key to use") flag.Parse() diff --git a/docker/docker.go b/docker/docker.go index 97c10ea..35b2086 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -19,8 +19,10 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" "github.com/docker/docker/pkg/jsonmessage" + "github.com/play-with-docker/play-with-docker/config" ) const ( @@ -239,7 +241,7 @@ type CreateContainerOpts struct { Networks []string } -func (d *docker) CreateContainer(opts CreateContainerOpts) error { +func (d *docker) CreateContainer(opts CreateContainerOpts) (err error) { // Make sure directories are available for the new instance container containerDir := "/var/run/pwd" containerCertDir := fmt.Sprintf("%s/certs", containerDir) @@ -268,8 +270,7 @@ func (d *docker) CreateContainer(opts CreateContainerOpts) error { NetworkMode: container.NetworkMode(opts.SessionId), Privileged: opts.Privileged, AutoRemove: true, - //PublishAllPorts: true, - LogConfig: container.LogConfig{Config: map[string]string{"max-size": "10m", "max-file": "1"}}, + LogConfig: container.LogConfig{Config: map[string]string{"max-size": "10m", "max-file": "1"}}, } if os.Getenv("APPARMOR_PROFILE") != "" { @@ -315,49 +316,69 @@ func (d *docker) CreateContainer(opts CreateContainerOpts) error { EndpointsConfig: map[string]*network.EndpointSettings{opts.Networks[0]: &network.EndpointSettings{}}, } + if config.ExternalDindVolume { + _, err = d.c.VolumeCreate(context.Background(), volume.VolumesCreateBody{ + Driver: "xfsvol", + DriverOpts: map[string]string{ + "size": config.DindVolumeSize, + }, + Name: opts.SessionId, + }) + if err != nil { + return + } + h.Binds = []string{fmt.Sprintf("%s:/var/lib/docker", opts.SessionId)} + + defer func() { + if err != nil { + d.c.VolumeRemove(context.Background(), opts.SessionId, true) + } + }() + } + container, err := d.c.ContainerCreate(context.Background(), cf, h, networkConf, opts.ContainerName) if err != nil { if client.IsErrImageNotFound(err) { log.Printf("Unable to find image '%s' locally\n", opts.Image) if err = d.pullImage(context.Background(), opts.Image); err != nil { - return err + return } container, err = d.c.ContainerCreate(context.Background(), cf, h, networkConf, opts.ContainerName) if err != nil { - return err + return } } else { - return err + return } } //connect remaining networks if there are any if len(opts.Networks) > 1 { for _, nid := range opts.Networks { - err := d.c.NetworkConnect(context.Background(), nid, container.ID, &network.EndpointSettings{}) + err = d.c.NetworkConnect(context.Background(), nid, container.ID, &network.EndpointSettings{}) if err != nil { - return err + return } } } - if err := d.copyIfSet(opts.ServerCert, "cert.pem", containerCertDir, opts.ContainerName); err != nil { - return err + if err = d.copyIfSet(opts.ServerCert, "cert.pem", containerCertDir, opts.ContainerName); err != nil { + return } - if err := d.copyIfSet(opts.ServerKey, "key.pem", containerCertDir, opts.ContainerName); err != nil { - return err + if err = d.copyIfSet(opts.ServerKey, "key.pem", containerCertDir, opts.ContainerName); err != nil { + return } - if err := d.copyIfSet(opts.CACert, "ca.pem", containerCertDir, opts.ContainerName); err != nil { - return err + if err = d.copyIfSet(opts.CACert, "ca.pem", containerCertDir, opts.ContainerName); err != nil { + return } err = d.c.ContainerStart(context.Background(), container.ID, types.ContainerStartOptions{}) if err != nil { - return err + return } - return nil + return } func (d *docker) GetContainerIPs(id string) (map[string]string, error) { diff --git a/dockerfiles/dind/Dockerfile.dind b/dockerfiles/dind/Dockerfile.dind index f237a29..c3631cf 100644 --- a/dockerfiles/dind/Dockerfile.dind +++ b/dockerfiles/dind/Dockerfile.dind @@ -1,7 +1,7 @@ -ARG VERSION=docker:17.07-dind +ARG VERSION=docker:17-dind FROM ${VERSION} -RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh zfs +RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh ENV GOPATH /root/go ENV PATH $PATH:$GOPATH @@ -37,9 +37,6 @@ COPY [".vimrc",".profile", ".inputrc", ".gitconfig", "./root/"] COPY ["motd", "/etc/motd"] COPY ["daemon.json", "/etc/docker/"] -ARG docker_storage_driver=overlay2 - -ENV DOCKER_STORAGE_DRIVER=$docker_storage_driver # Move to our home WORKDIR /root @@ -53,7 +50,6 @@ RUN mkdir -p /var/run/pwd/certs && mkdir -p /var/run/pwd/uploads \ # Remove IPv6 alias for localhost and start docker in the background ... CMD cat /etc/hosts >/etc/hosts.bak && \ sed 's/^::1.*//' /etc/hosts.bak > /etc/hosts && \ - sed -i "s/\DOCKER_STORAGE_DRIVER/$DOCKER_STORAGE_DRIVER/" /etc/docker/daemon.json && \ sed -i "s/\PWD_IP_ADDRESS/$PWD_IP_ADDRESS/" /etc/docker/daemon.json && \ sed -i "s/\DOCKER_TLSENABLE/$DOCKER_TLSENABLE/" /etc/docker/daemon.json && \ sed -i "s/\DOCKER_TLSCACERT/$DOCKER_TLSCACERT/" /etc/docker/daemon.json && \