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 15, 2017
1 parent d78364c commit daaf5f9
Show file tree
Hide file tree
Showing 5 changed files with 208 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
178 changes: 178 additions & 0 deletions drivers/ostree/driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// +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 && !os.IsNotExist(err) {
return nil, err
} else if err != nil {
idMappings := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps)
rootIDs := idMappings.RootPair()
if err := idtools.MkdirAllAndChown(repoLocation, 0700, rootIDs); err != nil {
return nil, fmt.Errorf("Could not create OSTree repository directory: %v", err)
}

if err := exec.Command("ostree", fmt.Sprintf("--repo=%s", repoLocation), "init").Run(); err != nil {
return nil, fmt.Errorf("Could not create OSTree repository: %v", err)
}
}

repo, err := otbuiltin.OpenRepo(repoLocation)
if err != nil {
return nil, fmt.Errorf("Could not open the OSTree repository: %v", 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 {
if _, err := d.repo.PrepareTransaction(); err != nil {
return fmt.Errorf("Could not prepare the OSTree transaction: %v", err)
}

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

if _, err := d.repo.Commit(root, branch, commitOpts); err != nil {
return fmt.Errorf("Could not commit the layer: %v", err)
}

if _, err := d.repo.CommitTransaction(); err != nil {
return fmt.Errorf("Could not complete the OSTree transaction: %v", err)
}

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

checkoutOpts := otbuiltin.NewCheckoutOptions()
if err := otbuiltin.Checkout(d.repoLocation, root, branch, checkoutOpts); err != nil {
return fmt.Errorf("Could not checkout from OSTree: %v", err)
}
return nil
}

// Remove deletes the content from the directory for a given id.
func (d *Driver) Remove(id string) error {
branch := fmt.Sprintf("ocilayer/%s", id)
if err := exec.Command("ostree", fmt.Sprintf("--repo=%s", d.repoLocation), "refs", "--delete", branch).Run(); err != nil {
return fmt.Errorf("Could not delete OSTree branch: %v", err)
}
return nil
}

// 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 {
if err := d.convertToOSTree(root, id); 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")
}
8 changes: 8 additions & 0 deletions drivers/register/register_ostree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// +build !exclude_graphdriver_ostree

package register

import (
// register the ostree graphdriver
_ "github.com/containers/storage/drivers/ostree"
)

0 comments on commit daaf5f9

Please sign in to comment.