Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

Fixing default search for /etc/docker/certs.d by image library #39

Merged
merged 2 commits into from
Aug 28, 2017
Merged
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
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ go_import_path: github.com/GoogleCloudPlatform/container-diff

script:
- ./.gofmt.sh
- sudo rm -rf /etc/docker
- travis_wait ./.container-diff-tests.sh
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,6 @@ type MultiVersionInfo struct {

To run container-diff on image IDs, docker must be installed.

If encountering this error ```open /etc/docker/certs.d/gcr.io: permission
denied```, run ```sudo rm -rf /etc/docker```.

## Example Run

Expand Down
119 changes: 18 additions & 101 deletions utils/docker_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"syscall"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
img "github.com/docker/docker/api/types/image"
"github.com/docker/docker/client"
Expand All @@ -41,74 +39,6 @@ func ValidDockerVersion() (bool, error) {
return false, nil
}

func getImagePullResponse(image string, response []Event) (string, error) {
var imageDigest string
for _, event := range response {
if event.Error != "" {
err := fmt.Errorf("Error pulling image %s: %s", image, event.Error)
return "", err
}
digestPattern := regexp.MustCompile("^Digest: (sha256:[a-z|0-9]{64})$")
digestMatch := digestPattern.FindStringSubmatch(event.Status)
if len(digestMatch) != 0 {
imageDigest = digestMatch[1]
return imageDigest, nil
}
}
err := fmt.Errorf("Could not pull image %s", image)
return "", err
}

func processImagePullEvents(image string, events []Event) (string, string, error) {
imageDigest, err := getImagePullResponse(image, events)
if err != nil {
return "", "", err
}

URLPattern := regexp.MustCompile("^.+/(.+(:.+){0,1})$")
URLMatch := URLPattern.FindStringSubmatch(image)
imageName := strings.Replace(URLMatch[1], ":", "", -1)
imageURL := strings.TrimSuffix(image, URLMatch[2])
imageID := imageURL + "@" + imageDigest

return imageID, imageName, nil
}

type Event struct {
Status string `json:"status"`
Error string `json:"error"`
Progress string `json:"progress"`
ProgressDetail struct {
Current int `json:"current"`
Total int `json:"total"`
} `json:"progressDetail"`
}

func pullImageFromRepo(image string) (string, string, error) {
glog.Info("Pulling image")
cli, err := client.NewEnvClient()
response, err := cli.ImagePull(context.Background(), image, types.ImagePullOptions{})
if err != nil {
return "", "", err
}
defer response.Close()

d := json.NewDecoder(response)

var events []Event
for {
var event Event
if err := d.Decode(&event); err != nil {
if err == io.EOF {
break
}
return "", "", err
}
events = append(events, event)
}
return processImagePullEvents(image, events)
}

type HistDiff struct {
Adds []string
Dels []string
Expand Down Expand Up @@ -169,42 +99,29 @@ func processHistOutput(response bytes.Buffer) ([]img.HistoryResponseItem, error)
return history, nil
}

func processPullCmdOutput(image string, response bytes.Buffer) (string, string, error) {
respReader := bytes.NewReader(response.Bytes())
reader := bufio.NewReader(respReader)
func imageToTar(image, dest string) (string, error) {
cli, err := client.NewEnvClient()
if err != nil {
return "", err
}

var events []Event
for {
var event Event
text, _, err := reader.ReadLine()
if err != nil {
if err == io.EOF {
break
}
return "", "", err
}
event.Status = string(text)
events = append(events, event)
imageTarPath, err := saveImageToTar(cli, image, dest)
if err != nil {
return "", err
}
return processImagePullEvents(image, events)
return imageTarPath, nil
}

func pullImageCmd(image string) (string, string, error) {
glog.Info("Pulling image")
pullArgs := []string{"pull", image}
dockerPullCmd := exec.Command("docker", pullArgs...)
var response bytes.Buffer
dockerPullCmd.Stdout = &response
if err := dockerPullCmd.Run(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
glog.Error("Docker Pull Command Exit Status: ", status.ExitStatus())
}
} else {
return "", "", err
}
// ImageToTar writes an image to a .tar file
func saveImageToTar(cli client.APIClient, image, tarName string) (string, error) {
glog.Info("Saving image")
imgBytes, err := cli.ImageSave(context.Background(), []string{image})
if err != nil {
return "", err
}
return processPullCmdOutput(image, response)
defer imgBytes.Close()
newpath := tarName + ".tar"
return newpath, copyToFile(newpath, imgBytes)
}

func imageToTarCmd(imageID, imageName string) (string, error) {
Expand Down
44 changes: 0 additions & 44 deletions utils/docker_utils_test.go

This file was deleted.

27 changes: 23 additions & 4 deletions utils/image_prep_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strings"

"github.com/containers/image/docker"
"github.com/containers/image/types"
"github.com/docker/docker/api/types/container"
"github.com/golang/glog"
)
Expand Down Expand Up @@ -116,14 +117,23 @@ func (p CloudPrepper) getFileSystem() (string, error) {
panic(err)
}

img, err := ref.NewImage(nil)
// By default, the image library will try to look at /etc/docker/certs.d
// As a non-root user, this would result in a permissions error, so we avoid this
// by looking in a temporary directory we create in the container-diff home directory
cwd, _ := os.Getwd()
tmpCerts, _ := ioutil.TempDir(cwd, "certs")
defer os.RemoveAll(tmpCerts)
ctx := &types.SystemContext{
DockerCertPath: tmpCerts,
}
img, err := ref.NewImage(ctx)
if err != nil {
glog.Error(err)
return "", err
}
defer img.Close()

imgSrc, err := ref.NewImageSource(nil, nil)
imgSrc, err := ref.NewImageSource(ctx, nil)
if err != nil {
glog.Error(err)
return "", err
Expand Down Expand Up @@ -157,7 +167,16 @@ func (p CloudPrepper) getConfig() (ConfigSchema, error) {
return ConfigSchema{}, err
}

img, err := ref.NewImage(nil)
// By default, the image library will try to look at /etc/docker/certs.d
// As a non-root user, this would result in a permissions error, so we avoid this
// by looking in a temporary directory we create in the container-diff home directory
cwd, _ := os.Getwd()
tmpCerts, _ := ioutil.TempDir(cwd, "certs")
defer os.RemoveAll(tmpCerts)
ctx := &types.SystemContext{
DockerCertPath: tmpCerts,
}
img, err := ref.NewImage(ctx)
if err != nil {
glog.Errorf("Error referencing image %s from registry: %s", p.Source, err)
return ConfigSchema{}, errors.New("Could not obtain image config")
Expand Down Expand Up @@ -194,7 +213,7 @@ func (p IDPrepper) getFileSystem() (string, error) {
glog.Info("Docker version incompatible with api, shelling out to local Docker client.")
tarPath, err = imageToTarCmd(p.Source, p.Source)
} else {
tarPath, err = saveImageToTar(p.Source, p.Source)
tarPath, err = imageToTar(p.Source, p.Source)
}
if err != nil {
return "", err
Expand Down
27 changes: 0 additions & 27 deletions utils/image_utils.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package utils

import (
"context"
"io"
"io/ioutil"
"os"
"path/filepath"
"regexp"

"github.com/docker/docker/client"
"github.com/docker/docker/pkg/system"
"github.com/golang/glog"
)
Expand All @@ -28,31 +26,6 @@ func GetImageLayers(pathToImage string) []string {
return layers
}

func saveImageToTar(image, dest string) (string, error) {
cli, err := client.NewEnvClient()
if err != nil {
return "", err
}

imageTarPath, err := ImageToTar(cli, image, dest)
if err != nil {
return "", err
}
return imageTarPath, nil
}

// ImageToTar writes an image to a .tar file
func ImageToTar(cli client.APIClient, image, tarName string) (string, error) {
glog.Info("Saving image")
imgBytes, err := cli.ImageSave(context.Background(), []string{image})
if err != nil {
return "", err
}
defer imgBytes.Close()
newpath := tarName + ".tar"
return newpath, copyToFile(newpath, imgBytes)
}

func CheckImageID(image string) bool {
pattern := regexp.MustCompile("[a-z|0-9]{12}")
if exp := pattern.FindString(image); exp != image {
Expand Down