Skip to content
This repository has been archived by the owner on Feb 24, 2020. It is now read-only.

Commit

Permalink
add support to import image from docker-daemon in rkt
Browse files Browse the repository at this point in the history
Now you can import an image that is available in docker's image store on
a local machine into rkt's imagestore.

To do so run following command:

```
rkt fetch --insecure-options=all docker-daemon://docker.io/library/alpine
```

This will import the image `docker.io/library/alpine` into rkt's store.
  • Loading branch information
surajssd committed Jun 15, 2018
1 parent 4080b17 commit 12a3a3b
Show file tree
Hide file tree
Showing 314 changed files with 27,158 additions and 9,026 deletions.
48 changes: 45 additions & 3 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,7 @@ import:
version: v1.1.0
- package: github.com/PuerkitoBio/urlesc
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
- package: github.com/docker/docker
version: v17.05.0-ce
subpackages:
- client
83 changes: 83 additions & 0 deletions pkg/distribution/docker-daemon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package distribution

import (
"fmt"
"net/url"

d2acommon "github.com/appc/docker2aci/lib/common"
)

const (
TypeDockerDaemon Type = "docker-daemon"
)

func init() {
Register(TypeDockerDaemon, NewDockerDaemon)
}

type DockerDaemon struct {
url string // a valid docker reference URL
parsedURL *d2acommon.ParsedDockerURL

full string // the full string representation for equals operations
simple string // the user friendly (simple) string representation
}

func NewDockerDaemon(u *url.URL) (Distribution, error) {
dp, err := parseCIMD(u)
if err != nil {
return nil, fmt.Errorf("cannot parse URI: %q: %v", u.String(), err)
}
if dp.Type != TypeDocker {
return nil, fmt.Errorf("wrong distribution type: %q", dp.Type)
}

parsed, err := d2acommon.ParseDockerURL(dp.Data)
if err != nil {
return nil, fmt.Errorf("bad docker URL %q: %v", dp.Data, err)
}

return &DockerDaemon{
url: dp.Data,
parsedURL: parsed,
simple: SimpleDockerRef(parsed),
full: FullDockerRef(parsed),
}, nil
}

func NewDockerDaemonFromString(ds string) (Distribution, error) {
urlStr := NewCIMDString(TypeDocker, distDockerVersion, ds)
u, err := url.Parse(urlStr)
if err != nil {
return nil, err
}
return NewDockerDaemon(u)
}

func (d *DockerDaemon) CIMD() *url.URL {
uriStr := NewCIMDString(TypeDocker, distDockerVersion, d.url)
// Create a copy of the URL
u, err := url.Parse(uriStr)
if err != nil {
panic(err)
}
return u
}

func (d *DockerDaemon) String() string {
return d.simple
}

func (d *DockerDaemon) Equals(dist Distribution) bool {
d2, ok := dist.(*DockerDaemon)
if !ok {
return false
}

return d.full == d2.full
}

// ReferenceURL returns the docker reference URL.
func (d *DockerDaemon) ReferenceURL() string {
return d.url
}
14 changes: 14 additions & 0 deletions rkt/image/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,20 @@ func DistFromImageString(is string) (dist.Distribution, error) {
return nil, fmt.Errorf("docker distribution creation error: %v", err)
}
return dist, nil
case "docker-daemon":
dockerDaemonStr := is
if strings.HasPrefix(dockerDaemonStr, "docker-daemon://") {
dockerDaemonStr = strings.TrimPrefix(dockerDaemonStr, "docker-daemon://")
} else if strings.HasPrefix(dockerDaemonStr, "docker-daemon:") {
dockerDaemonStr = strings.TrimPrefix(dockerDaemonStr, "docker-daemon:")
}

dist, err := dist.NewDockerDaemonFromString(dockerDaemonStr)
if err != nil {
return nil, fmt.Errorf("docker-daemon distribution creation error: %v", err)
}
return dist, nil

case dist.Scheme: // cimd
return dist.Parse(is)
default:
Expand Down
1 change: 1 addition & 0 deletions rkt/image/docker-daemon-fetcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package image
61 changes: 61 additions & 0 deletions rkt/image/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,23 @@ package image

import (
"container/list"
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"

dockerCli "github.com/docker/docker/client"
"github.com/hashicorp/errwrap"
"github.com/rkt/rkt/common"
"github.com/rkt/rkt/common/apps"
dist "github.com/rkt/rkt/pkg/distribution"
"github.com/rkt/rkt/stage0"
"github.com/rkt/rkt/store/imagestore"

docker2aci "github.com/appc/docker2aci/lib"
"github.com/appc/spec/discovery"
"github.com/appc/spec/schema/types"
)
Expand Down Expand Up @@ -175,6 +180,8 @@ func (f *Fetcher) fetchSingleImage(db *distBundle, a *asc) (string, error) {
return f.fetchSingleImageByName(db, a)
case *dist.Docker:
return f.fetchSingleImageByDockerURL(v)
case *dist.DockerDaemon:
return f.fetchSingleImageByDockerDaemonURL(v)
default:
return "", fmt.Errorf("unknown distribution type %T", v)
}
Expand Down Expand Up @@ -231,6 +238,60 @@ func (f *Fetcher) fetchSingleImageByDockerURL(d *dist.Docker) (string, error) {
return "", fmt.Errorf("unable to fetch docker image from URL %q: either image was not found in the store or store was disabled and fetching from remote yielded nothing or it was disabled", u.String())
}

func (f *Fetcher) fetchSingleImageByDockerDaemonURL(d *dist.DockerDaemon) (string, error) {
// the image to export from the docker daemon
imageName := d.ReferenceURL()
imageIDs := []string{imageName}

// extract the image as tar in temporary directory
cli, err := dockerCli.NewEnvClient()
if err != nil {
return "", fmt.Errorf("could not create the docker client: %v", err)
}

tar, err := cli.ImageSave(context.Background(), imageIDs)
if err != nil {
return "", fmt.Errorf("could not fetch the image: %v", err)
}
defer tar.Close()

tmpTarredFile, err := ioutil.TempFile("", "tarred-file")
if err != nil {
return "", fmt.Errorf("failed creating tarred file: %v", err)
}
defer tmpTarredFile.Close()

if _, err = io.Copy(tmpTarredFile, tar); err != nil {
return "", fmt.Errorf("copying file error: %v", err)
}

tarFilePath := tmpTarredFile.Name()
// delete this file
tmpTarredFile.Close()

// we will save the aci image
dir, err := ioutil.TempDir("", "convdir")
if err != nil {
log.Fatal(err)
}
fmt.Println("output dir:", dir)

// Now convert that stringtar file into aci
out, err := docker2aci.ConvertSavedFile(tarFilePath, docker2aci.FileConfig{
DockerURL: imageName,
CommonConfig: docker2aci.CommonConfig{
OutputDir: dir,
TmpDir: dir,
},
})
if err != nil {
return "", fmt.Errorf("converting tar failed: %v", err)
}

// Now import that aci into rkt environment
return f.fetchSingleImageByPath(out[0], nil)
}

func (f *Fetcher) maybeCheckRemoteFromStore(rem *imagestore.Remote) string {
if f.PullPolicy == PullPolicyUpdate || rem == nil {
return ""
Expand Down
22 changes: 22 additions & 0 deletions vendor/github.com/Microsoft/go-winio/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 12a3a3b

Please sign in to comment.