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

Commit 92d4f0e

Browse files
authored
Merge pull request #39 from cftorres/CertsError
Fixing default search for /etc/docker/certs.d by image library
2 parents 6089912 + 8877069 commit 92d4f0e

File tree

6 files changed

+41
-179
lines changed

6 files changed

+41
-179
lines changed

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@ go_import_path: github.com/GoogleCloudPlatform/container-diff
88

99
script:
1010
- ./.gofmt.sh
11-
- sudo rm -rf /etc/docker
1211
- travis_wait ./.container-diff-tests.sh

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,6 @@ type MultiVersionInfo struct {
226226

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

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

232230
## Example Run
233231

utils/docker_utils.go

Lines changed: 18 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@ import (
1212
"os"
1313
"os/exec"
1414
"path/filepath"
15-
"regexp"
1615
"strings"
1716
"syscall"
1817

19-
"github.com/docker/docker/api/types"
2018
"github.com/docker/docker/api/types/container"
2119
img "github.com/docker/docker/api/types/image"
2220
"github.com/docker/docker/client"
@@ -41,74 +39,6 @@ func ValidDockerVersion() (bool, error) {
4139
return false, nil
4240
}
4341

44-
func getImagePullResponse(image string, response []Event) (string, error) {
45-
var imageDigest string
46-
for _, event := range response {
47-
if event.Error != "" {
48-
err := fmt.Errorf("Error pulling image %s: %s", image, event.Error)
49-
return "", err
50-
}
51-
digestPattern := regexp.MustCompile("^Digest: (sha256:[a-z|0-9]{64})$")
52-
digestMatch := digestPattern.FindStringSubmatch(event.Status)
53-
if len(digestMatch) != 0 {
54-
imageDigest = digestMatch[1]
55-
return imageDigest, nil
56-
}
57-
}
58-
err := fmt.Errorf("Could not pull image %s", image)
59-
return "", err
60-
}
61-
62-
func processImagePullEvents(image string, events []Event) (string, string, error) {
63-
imageDigest, err := getImagePullResponse(image, events)
64-
if err != nil {
65-
return "", "", err
66-
}
67-
68-
URLPattern := regexp.MustCompile("^.+/(.+(:.+){0,1})$")
69-
URLMatch := URLPattern.FindStringSubmatch(image)
70-
imageName := strings.Replace(URLMatch[1], ":", "", -1)
71-
imageURL := strings.TrimSuffix(image, URLMatch[2])
72-
imageID := imageURL + "@" + imageDigest
73-
74-
return imageID, imageName, nil
75-
}
76-
77-
type Event struct {
78-
Status string `json:"status"`
79-
Error string `json:"error"`
80-
Progress string `json:"progress"`
81-
ProgressDetail struct {
82-
Current int `json:"current"`
83-
Total int `json:"total"`
84-
} `json:"progressDetail"`
85-
}
86-
87-
func pullImageFromRepo(image string) (string, string, error) {
88-
glog.Info("Pulling image")
89-
cli, err := client.NewEnvClient()
90-
response, err := cli.ImagePull(context.Background(), image, types.ImagePullOptions{})
91-
if err != nil {
92-
return "", "", err
93-
}
94-
defer response.Close()
95-
96-
d := json.NewDecoder(response)
97-
98-
var events []Event
99-
for {
100-
var event Event
101-
if err := d.Decode(&event); err != nil {
102-
if err == io.EOF {
103-
break
104-
}
105-
return "", "", err
106-
}
107-
events = append(events, event)
108-
}
109-
return processImagePullEvents(image, events)
110-
}
111-
11242
type HistDiff struct {
11343
Adds []string
11444
Dels []string
@@ -169,42 +99,29 @@ func processHistOutput(response bytes.Buffer) ([]img.HistoryResponseItem, error)
16999
return history, nil
170100
}
171101

172-
func processPullCmdOutput(image string, response bytes.Buffer) (string, string, error) {
173-
respReader := bytes.NewReader(response.Bytes())
174-
reader := bufio.NewReader(respReader)
102+
func imageToTar(image, dest string) (string, error) {
103+
cli, err := client.NewEnvClient()
104+
if err != nil {
105+
return "", err
106+
}
175107

176-
var events []Event
177-
for {
178-
var event Event
179-
text, _, err := reader.ReadLine()
180-
if err != nil {
181-
if err == io.EOF {
182-
break
183-
}
184-
return "", "", err
185-
}
186-
event.Status = string(text)
187-
events = append(events, event)
108+
imageTarPath, err := saveImageToTar(cli, image, dest)
109+
if err != nil {
110+
return "", err
188111
}
189-
return processImagePullEvents(image, events)
112+
return imageTarPath, nil
190113
}
191114

192-
func pullImageCmd(image string) (string, string, error) {
193-
glog.Info("Pulling image")
194-
pullArgs := []string{"pull", image}
195-
dockerPullCmd := exec.Command("docker", pullArgs...)
196-
var response bytes.Buffer
197-
dockerPullCmd.Stdout = &response
198-
if err := dockerPullCmd.Run(); err != nil {
199-
if exiterr, ok := err.(*exec.ExitError); ok {
200-
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
201-
glog.Error("Docker Pull Command Exit Status: ", status.ExitStatus())
202-
}
203-
} else {
204-
return "", "", err
205-
}
115+
// ImageToTar writes an image to a .tar file
116+
func saveImageToTar(cli client.APIClient, image, tarName string) (string, error) {
117+
glog.Info("Saving image")
118+
imgBytes, err := cli.ImageSave(context.Background(), []string{image})
119+
if err != nil {
120+
return "", err
206121
}
207-
return processPullCmdOutput(image, response)
122+
defer imgBytes.Close()
123+
newpath := tarName + ".tar"
124+
return newpath, copyToFile(newpath, imgBytes)
208125
}
209126

210127
func imageToTarCmd(imageID, imageName string) (string, error) {

utils/docker_utils_test.go

Lines changed: 0 additions & 44 deletions
This file was deleted.

utils/image_prep_utils.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"strings"
1414

1515
"github.com/containers/image/docker"
16+
"github.com/containers/image/types"
1617
"github.com/docker/docker/api/types/container"
1718
"github.com/golang/glog"
1819
)
@@ -116,14 +117,23 @@ func (p CloudPrepper) getFileSystem() (string, error) {
116117
panic(err)
117118
}
118119

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

126-
imgSrc, err := ref.NewImageSource(nil, nil)
136+
imgSrc, err := ref.NewImageSource(ctx, nil)
127137
if err != nil {
128138
glog.Error(err)
129139
return "", err
@@ -157,7 +167,16 @@ func (p CloudPrepper) getConfig() (ConfigSchema, error) {
157167
return ConfigSchema{}, err
158168
}
159169

160-
img, err := ref.NewImage(nil)
170+
// By default, the image library will try to look at /etc/docker/certs.d
171+
// As a non-root user, this would result in a permissions error, so we avoid this
172+
// by looking in a temporary directory we create in the container-diff home directory
173+
cwd, _ := os.Getwd()
174+
tmpCerts, _ := ioutil.TempDir(cwd, "certs")
175+
defer os.RemoveAll(tmpCerts)
176+
ctx := &types.SystemContext{
177+
DockerCertPath: tmpCerts,
178+
}
179+
img, err := ref.NewImage(ctx)
161180
if err != nil {
162181
glog.Errorf("Error referencing image %s from registry: %s", p.Source, err)
163182
return ConfigSchema{}, errors.New("Could not obtain image config")
@@ -194,7 +213,7 @@ func (p IDPrepper) getFileSystem() (string, error) {
194213
glog.Info("Docker version incompatible with api, shelling out to local Docker client.")
195214
tarPath, err = imageToTarCmd(p.Source, p.Source)
196215
} else {
197-
tarPath, err = saveImageToTar(p.Source, p.Source)
216+
tarPath, err = imageToTar(p.Source, p.Source)
198217
}
199218
if err != nil {
200219
return "", err

utils/image_utils.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package utils
22

33
import (
4-
"context"
54
"io"
65
"io/ioutil"
76
"os"
87
"path/filepath"
98
"regexp"
109

11-
"github.com/docker/docker/client"
1210
"github.com/docker/docker/pkg/system"
1311
"github.com/golang/glog"
1412
)
@@ -28,31 +26,6 @@ func GetImageLayers(pathToImage string) []string {
2826
return layers
2927
}
3028

31-
func saveImageToTar(image, dest string) (string, error) {
32-
cli, err := client.NewEnvClient()
33-
if err != nil {
34-
return "", err
35-
}
36-
37-
imageTarPath, err := ImageToTar(cli, image, dest)
38-
if err != nil {
39-
return "", err
40-
}
41-
return imageTarPath, nil
42-
}
43-
44-
// ImageToTar writes an image to a .tar file
45-
func ImageToTar(cli client.APIClient, image, tarName string) (string, error) {
46-
glog.Info("Saving image")
47-
imgBytes, err := cli.ImageSave(context.Background(), []string{image})
48-
if err != nil {
49-
return "", err
50-
}
51-
defer imgBytes.Close()
52-
newpath := tarName + ".tar"
53-
return newpath, copyToFile(newpath, imgBytes)
54-
}
55-
5629
func CheckImageID(image string) bool {
5730
pattern := regexp.MustCompile("[a-z|0-9]{12}")
5831
if exp := pattern.FindString(image); exp != image {

0 commit comments

Comments
 (0)