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

Commit

Permalink
create a new docker-daemon fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
surajssd committed Jun 16, 2018
1 parent 12a3a3b commit 4e78b87
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 55 deletions.
111 changes: 111 additions & 0 deletions rkt/image/docker-daemon-fetcher.go
Original file line number Diff line number Diff line change
@@ -1 +1,112 @@
package image

import (
"context"
"fmt"
"io"
"os"

docker2aci "github.com/appc/docker2aci/lib"
d2acommon "github.com/appc/docker2aci/lib/common"
dockerCli "github.com/docker/docker/client"
)

type dockerDaemonFetcher struct {
*Fetcher
ImageName string
}

func (d *dockerDaemonFetcher) Hash() (string, error) {
// image verification is not supported for docker images so adding this check
// incase the user has forgotten to give such a flag then indicate such
if !d.InsecureFlags.SkipImageCheck() {
return "", fmt.Errorf("signature verification for docker images is not supported (try --insecure-options=image)")
}

// fetch the image from docker's store as tar file
tarFilePath, tarCleaner, err := d.dockerToTar()
if err != nil {
return "", err
}
defer tarCleaner()

// convert the tar file into rkt readable ACI format
aciFilePath, aciCleaner, err := d.tarToACI(tarFilePath)
if err != nil {
return "", err
}
defer aciCleaner()

// now that we have the ACI format image import into rkt store
return d.importToRktStore(aciFilePath)
}

// dockerToTar fetches the image from docker's store and save it as
// a tar file in temporary place
func (d *dockerDaemonFetcher) dockerToTar() (string, func(), error) {
// create a docker client to interact with docker daemon
cli, err := dockerCli.NewEnvClient()
if err != nil {
return "", nil, fmt.Errorf("creating the docker client: %v", err)
}

// fetch the image from docker's store
tar, err := cli.ImageSave(
context.Background(),
[]string{d.ImageName},
)
if err != nil {
return "", nil, fmt.Errorf("fetching the image from docker store: %v", err)
}
defer tar.Close()

// create a temporary file to copy the tar data we just received
tmpTarFile, err := d.S.TmpFile()
if err != nil {
return "", nil, fmt.Errorf("creating tar file: %v", err)
}
defer tmpTarFile.Close()

// now copy that tar content into a temporary file
if _, err = io.Copy(tmpTarFile, tar); err != nil {
return "", nil, fmt.Errorf("copying to tar file: %v", err)
}
tmpTarFile.Close()

path := tmpTarFile.Name()
return path, func() {
os.Remove(path)
}, nil
}

// tarToACI converts the tar file fetched from docker's store into
// rkt readable ACI image format
func (d *dockerDaemonFetcher) tarToACI(tarFilePath string) (string, func(), error) {
// we will save all the temporary artifacts in this directory
tempDir, err := d.S.TmpDir()
if err != nil {
return "", nil, fmt.Errorf("creating temporary directory: %v", err)
}

// Now convert that tar file into aci
out, err := docker2aci.ConvertSavedFile(tarFilePath, docker2aci.FileConfig{
CommonConfig: docker2aci.CommonConfig{
Squash: true,
OutputDir: tempDir,
TmpDir: tempDir,
Compression: d2acommon.GzipCompression,
},
})
if err != nil {
return "", nil, fmt.Errorf("converting tar to aci: %v", err)
}

return out[0], func() {
os.RemoveAll(tempDir)
}, nil
}

func (d *dockerDaemonFetcher) importToRktStore(aciFilePath string) (string, error) {
// TODO: implement the way to handle the image security options
return d.fetchSingleImageByPath(aciFilePath, nil)
}
59 changes: 4 additions & 55 deletions rkt/image/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,18 @@ 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 @@ -239,57 +234,11 @@ func (f *Fetcher) fetchSingleImageByDockerURL(d *dist.Docker) (string, error) {
}

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)
ddf := &dockerDaemonFetcher{
Fetcher: f,
ImageName: d.ReferenceURL(),
}

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)
return ddf.Hash()
}

func (f *Fetcher) maybeCheckRemoteFromStore(rem *imagestore.Remote) string {
Expand Down

0 comments on commit 4e78b87

Please sign in to comment.