Skip to content

Commit

Permalink
Merge pull request #18 from dfjxs/layer-cache
Browse files Browse the repository at this point in the history
Add option to replace symlink layers with cached layers
  • Loading branch information
roshanmaskey authored Oct 28, 2024
2 parents 37745bb + 69ab1cb commit 5099ac1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 23 deletions.
6 changes: 5 additions & 1 deletion cmd/commands/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func explorerEnvironment(clictx *cli.Context) (context.Context, explorers.Contai
dockerroot := clictx.GlobalString("docker-root")
metadatafile := clictx.GlobalString("metadata-file")
snapshotfile := clictx.GlobalString("snapshot-metadata-file")
layercache := clictx.GlobalString("layer-cache")

// Read support container data if provided using global switch.
var sc *explorers.SupportContainer
Expand Down Expand Up @@ -119,7 +120,10 @@ func explorerEnvironment(clictx *cli.Context) (context.Context, explorers.Contai
"snapshotfile": snapshotfile,
}).Debug("containerd container environment")

cde, err := containerd.NewExplorer(imageroot, containerdroot, metadatafile, snapshotfile, sc)
if !clictx.GlobalBool("use-layer-cache") {
layercache = ""
}
cde, err := containerd.NewExplorer(imageroot, containerdroot, metadatafile, snapshotfile, layercache, sc)
if err != nil {
return ctx, nil, func() { cancel() }, err
}
Expand Down
9 changes: 9 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ func main() {
Name: "snapshot-metadata-file, s",
Usage: "specify the path to containerd snapshot metadata file i.e. metadata.db.",
},
cli.BoolFlag{
Name: "use-layer-cache",
Usage: "attempt to use cached layers where layers are symlinks",
},
cli.StringFlag{
Name: "layer-cache",
Usage: "cached layer folder within the snapshot root",
Value: "layers",
},
cli.StringFlag{
Name: "namespace, n",
Usage: "specify container namespace",
Expand Down
32 changes: 17 additions & 15 deletions explorers/containerd/containerd.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,17 @@ import (
)

type explorer struct {
imageroot string // mounted image path
root string // containerd root
manifest string // path to manifest database file i.e. meta.db
snapshot string // path to snapshot database file i.e. metadata.db
mdb *bolt.DB // manifest database
sc *explorers.SupportContainer // support container structure object
imageroot string // mounted image path
root string // containerd root
manifest string // path to manifest database file i.e. meta.db
snapshot string // path to snapshot database file i.e. metadata.db
layercache string // layer cache folder within snapshot root
mdb *bolt.DB // manifest database
sc *explorers.SupportContainer // support container structure object
}

// NewExplorer returns a ContainerExplorer interface to explore containerd.
func NewExplorer(imageroot string, root string, manifest string, snapshot string, sc *explorers.SupportContainer) (explorers.ContainerExplorer, error) {
func NewExplorer(imageroot string, root string, manifest string, snapshot string, layercache string, sc *explorers.SupportContainer) (explorers.ContainerExplorer, error) {
opt := &bolt.Options{
ReadOnly: true,
}
Expand All @@ -57,12 +58,13 @@ func NewExplorer(imageroot string, root string, manifest string, snapshot string
}

return &explorer{
imageroot: imageroot,
root: root,
manifest: manifest,
snapshot: snapshot,
mdb: db,
sc: sc,
imageroot: imageroot,
root: root,
manifest: manifest,
snapshot: snapshot,
layercache: layercache,
mdb: db,
sc: sc,
}, nil
}

Expand Down Expand Up @@ -260,7 +262,7 @@ func (e *explorer) ListSnapshots(ctx context.Context) ([]explorers.SnapshotKeyIn
}).Error(err)
}

store := NewSnaptshotStore(e.root, e.mdb, ssdb)
store := NewSnaptshotStore(e.root, e.layercache, e.mdb, ssdb)

for _, ns := range nss {
ctx = namespaces.WithNamespace(ctx, ns)
Expand Down Expand Up @@ -480,7 +482,7 @@ func (e *explorer) MountContainer(ctx context.Context, containerid string, mount
}

// snapshot store
ssstore := NewSnaptshotStore(e.root, e.mdb, ssdb)
ssstore := NewSnaptshotStore(e.root, e.layercache, e.mdb, ssdb)
var mountArgs []string
hasWorkDir := false
snapshotRoot, _ := filepath.Split(e.snapshot)
Expand Down
40 changes: 33 additions & 7 deletions explorers/containerd/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/binary"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"

Expand All @@ -34,9 +35,10 @@ import (
)

type snapshotStore struct {
root string // containerd root directory
db *bolt.DB
sdb *bolt.DB
root string // containerd root directory
layercache string
db *bolt.DB
sdb *bolt.DB
}

// NewSnapshotStore returns snapshotStore which handles viewing of snapshot information
Expand All @@ -54,11 +56,12 @@ type snapshotStore struct {
// Snapshot path in snapshot database: metadata.db/v1/snapshots/<snapshot key>
// - id - Snapshot file system ID i.e. /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/<id>/fs
// - kind - ACTIVE vs COMMITTED
func NewSnaptshotStore(root string, db *bolt.DB, sdb *bolt.DB) *snapshotStore {
func NewSnaptshotStore(root string, layercache string, db *bolt.DB, sdb *bolt.DB) *snapshotStore {
return &snapshotStore{
root: root,
db: db,
sdb: sdb,
root: root,
layercache: layercache,
db: db,
sdb: sdb,
}
}

Expand Down Expand Up @@ -213,13 +216,36 @@ func (s *snapshotStore) OverlayPath(ctx context.Context, container containers.Co
upperdir = filepath.Join(snapshotroot, "snapshots", fmt.Sprintf("%d", upperdirID), "fs")
workdir = filepath.Join(snapshotroot, "snapshots", fmt.Sprintf("%d", upperdirID), "work")

if s.layercache != "" {
symlink, err := os.Readlink(upperdir)
if err == nil {
log.WithFields(log.Fields{
"id": upperdirID,
"symlink": symlink,
}).Debug("upperdir")
_, layer := filepath.Split(symlink)
upperdir = filepath.Join(snapshotroot, s.layercache, layer)
}
}

// compute lowerdir
for _, ssk := range snapshotkeys[1:] {
id, err := getSnapshotID(tx, ssk)
if err != nil {
return err
}
ldir := filepath.Join(snapshotroot, "snapshots", fmt.Sprintf("%d", id), "fs")
if s.layercache != "" {
symlink, err := os.Readlink(ldir)
if err == nil {
log.WithFields(log.Fields{
"id": id,
"symlink": symlink,
}).Debug("layer")
_, layer := filepath.Split(symlink)
ldir = filepath.Join(snapshotroot, "layers", layer)
}
}

if lowerdir == "" {
lowerdir = ldir
Expand Down

0 comments on commit 5099ac1

Please sign in to comment.