Skip to content

Commit

Permalink
ostree: new storage
Browse files Browse the repository at this point in the history
Skopeo needs a bugfix from:

containers/image#305

which is not merged yet.  Just apply this patch:

diff --git a/vendor/github.com/containers/image/storage/storage_image.go b/vendor/github.com/containers/image/storage/storage_image.go
index 08fa71b..5edccce 100644
--- a/vendor/github.com/containers/image/storage/storage_image.go
+++ b/vendor/github.com/containers/image/storage/storage_image.go
@@ -174,7 +174,7 @@ func (s *storageImageDestination) putBlob(stream io.Reader, blobinfo types.BlobI
                        id = ddigest.Canonical.FromBytes([]byte(parentLayer + "+" + digest.String())).Hex()
                }
                // Attempt to create the identified layer and import its contents.
-               layer, uncompressedSize, err := s.imageRef.transport.store.PutLayer(id, parentLayer, nil, "", true, multi)
+               layer, uncompressedSize, err := s.imageRef.transport.store.PutLayer(id, parentLayer, nil, "", false, multi)
                if err != nil && errors.Cause(err) != storage.ErrDuplicateID {
                        logrus.Debugf("error importing layer blob %q as %q: %v", blobinfo.Digest, id, err)
                        return errorBlobInfo, err

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Nov 14, 2017
1 parent a7e90cd commit 6362511
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ go:
- 1.7
dist: trusty
sudo: required
env:
- TAGS='exclude_graphdriver_ostree'
before_install:
- sudo apt-get -qq update
- sudo apt-get -qq install btrfs-tools libdevmapper-dev
script:
- make install.tools
- make local-binary docs local-cross local-validate
- sudo PATH="$PATH" make local-test-unit local-test-integration
- sudo -E PATH="$PATH" make local-test-unit local-test-integration
1 change: 1 addition & 0 deletions drivers/driver_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var (
"btrfs",
"zfs",
"vfs",
"ostree",
}

// FsNames maps filesystem id to name of the filesystem.
Expand Down
182 changes: 182 additions & 0 deletions drivers/ostree/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// +build !exclude_graphdriver_ostree

package ostree

import (
"fmt"
"os"
"os/exec"
"strings"
"time"

"github.com/containers/storage/drivers"
"github.com/containers/storage/drivers/overlay"
"github.com/containers/storage/pkg/idtools"
"github.com/containers/storage/pkg/system"
"github.com/ostreedev/ostree-go/pkg/otbuiltin"
)

func init() {
graphdriver.Register("ostree", Init)
}

// Init returns a new OSTREE driver.
// This sets the home directory for the driver and returns NaiveDiffDriver.
func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
overlay, err := overlay.Init(home, options, uidMaps, gidMaps)
if err != nil {
return nil, err
}

repoLocation := fmt.Sprintf("%s/.repo", home)
for _, option := range options {
if strings.HasPrefix(option, "ostree.repo=") {
repoLocation = option[12:]
}
}

_, err = os.Stat(repoLocation)
if err != nil {
idMappings := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps)
rootIDs := idMappings.RootPair()
if err := idtools.MkdirAllAndChown(repoLocation, 0700, rootIDs); err != nil {
return nil, err
}
err := exec.Command("ostree", fmt.Sprintf("--repo=%s", repoLocation), "init").Run()
if err != nil {
return nil, err
}
}

repo, err := otbuiltin.OpenRepo(repoLocation)
if err != nil {
return nil, err
}

d := &Driver{
home: home,
overlay: overlay,
convert: make(map[string]bool),
}
d.repo = repo
d.repoLocation = repoLocation
return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil
}

// Driver must be wrapped in NaiveDiffDriver to be used as a graphdriver.Driver
type Driver struct {
home string
overlay graphdriver.Driver
repo *otbuiltin.Repo
repoLocation string
convert map[string]bool
}

func (d *Driver) String() string {
return "ostree"
}

// Status is used for implementing the graphdriver.ProtoDriver interface. OSTREE does not currently have any status information.
func (d *Driver) Status() [][2]string {
return d.overlay.Status()
}

// Metadata is used for implementing the graphdriver.ProtoDriver interface. OSTREE does not currently have any meta data.
func (d *Driver) Metadata(id string) (map[string]string, error) {
return d.overlay.Metadata(id)
}

// Cleanup is used to implement graphdriver.ProtoDriver. There is no cleanup required for this driver.
func (d *Driver) Cleanup() error {
return d.overlay.Cleanup()
}

// CreateReadWrite creates a layer that is writable for use as a container
// file system.
func (d *Driver) CreateReadWrite(id, parent string, opts *graphdriver.CreateOpts) error {
return d.overlay.CreateReadWrite(id, parent, opts)
}

// Create prepares the filesystem for the OSTREE driver and copies the directory for the given id under the parent.
func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error {
d.convert[id] = true
return d.overlay.Create(id, parent, opts)
}

func getDir(home, id string) string {
return fmt.Sprintf("%s/%s/diff", home, id)
}

// Create prepares the filesystem for the OSTREE driver and copies the directory for the given id under the parent.
func (d *Driver) convertToOSTree(root, id string) error {
_, err := d.repo.PrepareTransaction()
if err != nil {
return err
}

commitOpts := otbuiltin.NewCommitOptions()
commitOpts.Timestamp = time.Now()
commitOpts.Parent = "0000000000000000000000000000000000000000000000000000000000000000"
branch := fmt.Sprintf("ocilayer/%s", id)

_, err = d.repo.Commit(root, branch, commitOpts)
if err != nil {
return err
}

_, err = d.repo.CommitTransaction()
if err != nil {
return err
}

err = system.EnsureRemoveAll(root)
if err != nil {
return err
}

checkoutOpts := otbuiltin.NewCheckoutOptions()
err = otbuiltin.Checkout(d.repoLocation, root, branch, checkoutOpts)
if err != nil {
return err
}
return nil
}

// Remove deletes the content from the directory for a given id.
func (d *Driver) Remove(id string) error {
opts := otbuiltin.NewPruneOptions()
branch := fmt.Sprintf("ocilayer/%s", id)
opts.DeleteCommit = branch
_, err := otbuiltin.Prune(d.repoLocation, opts)
return err
}

// Get returns the directory for the given id.
func (d *Driver) Get(id, mountLabel string) (string, error) {
path, err := d.overlay.Get(id, mountLabel)
return path, err
}

func (d *Driver) Put(id string) error {
root := getDir(d.home, id)

_, convert := d.convert[id]
if convert {
err := d.convertToOSTree(root, id)
if err != nil {
return err
}
}

return d.overlay.Put(id)
}

// Exists checks to see if the directory exists for the given id.
func (d *Driver) Exists(id string) bool {
return d.overlay.Exists(id)
}

// AdditionalImageStores returns additional image stores supported by the driver
func (d *Driver) AdditionalImageStores() []string {
return d.overlay.AdditionalImageStores()
}
18 changes: 18 additions & 0 deletions drivers/ostree/driver_stub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// +build exclude_graphdriver_ostree

package ostree

import (
"fmt"

"github.com/containers/storage/drivers"
"github.com/containers/storage/pkg/idtools"
)

func init() {
graphdriver.Register("ostree", Init)
}

func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
return nil, fmt.Errorf("ostree driver not supported")
}

0 comments on commit 6362511

Please sign in to comment.