Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@vito
Created May 18, 2017 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vito/10ae0ac70bd5d2c280897ee9385cc425 to your computer and use it in GitHub Desktop.
Save vito/10ae0ac70bd5d2c280897ee9385cc425 to your computer and use it in GitHub Desktop.
package driver
import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
)
type AufsDriver struct {
OverlaysDir string
}
func (driver *AufsDriver) CreateVolume(path string) error {
layerDir := driver.layerDir(path)
err := os.MkdirAll(layerDir, 0755)
if err != nil {
return err
}
err = os.Mkdir(path, 0755)
if err != nil {
return err
}
return syscall.Mount(layerDir, path, "", syscall.MS_BIND, "")
}
func (driver *AufsDriver) DestroyVolume(path string) error {
err := syscall.Unmount(path, 0)
if err != nil {
return err
}
err = os.RemoveAll(driver.layerDir(path))
if err != nil {
return err
}
return os.RemoveAll(path)
}
func (driver *AufsDriver) CreateCopyOnWriteLayer(path string, parent string) error {
ancestry, err := driver.ancestry(parent)
if err != nil {
return err
}
childDir := driver.layerDir(path)
err = os.MkdirAll(childDir, 0755)
if err != nil {
return err
}
err = os.MkdirAll(path, 0755)
if err != nil {
return err
}
layers := []string{fmt.Sprintf("br:%s=rw", childDir)}
for _, lower := range ancestry {
layers = append(layers, fmt.Sprintf("%s=ro+wh", lower))
}
opts := []string{
strings.Join(layers, ":"),
"dio",
"xino=/dev/shm/aufs.xino",
"dirperm1",
}
return syscall.Mount("aufs", path, "aufs", 0, strings.Join(opts, ","))
}
func (driver *AufsDriver) GetVolumeSizeInBytes(path string) (int64, error) {
stdout := &bytes.Buffer{}
cmd := exec.Command("du", "-s", driver.layerDir(path))
cmd.Stdout = stdout
err := cmd.Run()
if err != nil {
return 0, err
}
var size int64
_, err = fmt.Sscanf(stdout.String(), "%d", &size)
if err != nil {
return 0, err
}
return size, nil
}
func (driver *AufsDriver) layerDir(path string) string {
return filepath.Join(driver.OverlaysDir, driver.pathId(path))
}
func (driver *AufsDriver) ancestry(path string) ([]string, error) {
ancestry := []string{}
currentPath := path
for {
ancestry = append(ancestry, driver.layerDir(currentPath))
parentVolume, err := os.Readlink(filepath.Join(filepath.Dir(currentPath), "parent"))
if err != nil {
if _, ok := err.(*os.PathError); ok {
break
}
return nil, err
}
currentPath = filepath.Join(parentVolume, "volume")
}
return ancestry, nil
}
func (driver *AufsDriver) pathId(path string) string {
return filepath.Base(filepath.Dir(path))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment