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

Commit d251d09

Browse files
author
dlorenc
committed
WIP: adds a simple layer cache.
1 parent ee67c3e commit d251d09

File tree

7 files changed

+95
-4
lines changed

7 files changed

+95
-4
lines changed

cmd/diff.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"sync"
2525

2626
"github.com/GoogleCloudPlatform/container-diff/differs"
27+
"github.com/GoogleCloudPlatform/container-diff/pkg/cache"
2728
pkgutil "github.com/GoogleCloudPlatform/container-diff/pkg/util"
2829
"github.com/golang/glog"
2930
"github.com/spf13/cobra"
@@ -68,6 +69,12 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
6869
return err
6970
}
7071
defer cli.Close()
72+
73+
fsCache, err := cache.NewFileCache(cacheDir())
74+
if err != nil {
75+
return err
76+
}
77+
7178
var wg sync.WaitGroup
7279
wg.Add(2)
7380

@@ -83,6 +90,7 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
8390
ip := pkgutil.ImagePrepper{
8491
Source: imageName,
8592
Client: cli,
93+
Cache: fsCache,
8694
}
8795
image, err := ip.GetImage()
8896
imageMap[imageName] = &image

cmd/root.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"context"
2121
goflag "flag"
2222
"fmt"
23+
"os/user"
24+
"path/filepath"
2325
"sort"
2426
"strings"
2527

@@ -37,6 +39,15 @@ var types string
3739

3840
type validatefxn func(args []string) error
3941

42+
func cacheDir() string {
43+
user, err := user.Current()
44+
if err != nil {
45+
glog.Exit(err)
46+
}
47+
rootDir := filepath.Join(user.HomeDir, ".container-diff")
48+
return filepath.Join(rootDir, "cache")
49+
}
50+
4051
var RootCmd = &cobra.Command{
4152
Use: "container-diff",
4253
Short: "container-diff is a tool for analyzing and comparing container images",

pkg/cache/cache.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2017 Google, Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cache
18+
19+
import (
20+
"io"
21+
"os"
22+
"path/filepath"
23+
)
24+
25+
type FileCache struct {
26+
RootDir string
27+
}
28+
29+
func NewFileCache(rootDir string) (*FileCache, error) {
30+
if err := os.MkdirAll(rootDir, 0700); err != nil {
31+
return nil, err
32+
}
33+
return &FileCache{RootDir: rootDir}, nil
34+
}
35+
36+
func (f *FileCache) HasLayer(layerId string) bool {
37+
_, err := os.Stat(filepath.Join(f.RootDir, layerId))
38+
return !os.IsNotExist(err)
39+
}
40+
41+
func (f *FileCache) SetLayer(layerId string, r io.Reader) (io.ReadCloser, error) {
42+
path := filepath.Join(f.RootDir, layerId)
43+
l, err := os.Create(path)
44+
if err != nil {
45+
return nil, err
46+
}
47+
if _, err := io.Copy(l, r); err != nil {
48+
return nil, err
49+
}
50+
51+
return f.GetLayer(layerId)
52+
}
53+
54+
func (f *FileCache) GetLayer(layerId string) (io.ReadCloser, error) {
55+
path := filepath.Join(f.RootDir, layerId)
56+
return os.Open(path)
57+
}

pkg/util/cloud_prepper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (p CloudPrepper) GetFileSystem() (string, error) {
5050
return "", err
5151
}
5252

53-
return getFileSystemFromReference(ref, p.Source)
53+
return getFileSystemFromReference(ref, p.Source, p.Cache)
5454
}
5555

5656
func (p CloudPrepper) GetConfig() (ConfigSchema, error) {

pkg/util/daemon_prepper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (p DaemonPrepper) GetFileSystem() (string, error) {
4949
if err != nil {
5050
return "", err
5151
}
52-
return getFileSystemFromReference(ref, p.Source)
52+
return getFileSystemFromReference(ref, p.Source, p.Cache)
5353
}
5454

5555
func (p DaemonPrepper) GetConfig() (ConfigSchema, error) {

pkg/util/image_prep_utils.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import (
2020
"archive/tar"
2121
"encoding/json"
2222
"errors"
23+
"io"
2324
"io/ioutil"
2425
"os"
2526
"path/filepath"
2627
"strings"
2728

29+
"github.com/GoogleCloudPlatform/container-diff/pkg/cache"
2830
"github.com/containers/image/pkg/compression"
2931
"github.com/containers/image/types"
3032
"github.com/golang/glog"
@@ -62,7 +64,7 @@ func getImageFromTar(tarPath string) (string, error) {
6264
return path, err
6365
}
6466

65-
func getFileSystemFromReference(ref types.ImageReference, imageName string) (string, error) {
67+
func getFileSystemFromReference(ref types.ImageReference, imageName string, c *cache.FileCache) (string, error) {
6668
sanitizedName := strings.Replace(imageName, ":", "", -1)
6769
sanitizedName = strings.Replace(sanitizedName, "/", "", -1)
6870

@@ -85,7 +87,18 @@ func getFileSystemFromReference(ref types.ImageReference, imageName string) (str
8587
}
8688

8789
for _, b := range img.LayerInfos() {
88-
bi, _, err := imgSrc.GetBlob(b)
90+
var bi io.ReadCloser
91+
var err error
92+
if c.HasLayer(b.Digest.String()) {
93+
bi, err = c.GetLayer(b.Digest.String())
94+
} else {
95+
bi, _, err = imgSrc.GetBlob(b)
96+
if err != nil {
97+
return "", err
98+
}
99+
// We need to get a new reader after caching the old one.
100+
bi, err = c.SetLayer(b.Digest.String(), bi)
101+
}
89102
if err != nil {
90103
glog.Errorf("Failed to pull image layer: %s", err)
91104
return "", err

pkg/util/image_prepper.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ package util
1919
import (
2020
"errors"
2121

22+
"github.com/GoogleCloudPlatform/container-diff/pkg/cache"
2223
"github.com/docker/docker/client"
2324
"github.com/golang/glog"
2425
)
2526

2627
type ImagePrepper struct {
2728
Source string
2829
Client *client.Client
30+
Cache *cache.FileCache
2931
}
3032

3133
type Prepper interface {

0 commit comments

Comments
 (0)