Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Commit 8847998

Browse files
committed
agent: Add support for local storage
Local storage is just a directory created inside the VM. This will use whatever the storage driver is for the container rootfs. This will normally be 9p, but in some cases could be device mapper. In this case the directory will benefit from the improved performance of device mapper. Fixes #524 Signed-off-by: Alex Price <aprice@atlassian.com>
1 parent 7ce9fa5 commit 8847998

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

device.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const (
3131
driverSCSIType = "scsi"
3232
driverNvdimmType = "nvdimm"
3333
driverEphemeralType = "ephemeral"
34+
driverLocalType = "local"
3435
)
3536

3637
const (

mount.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"fmt"
1212
"os"
1313
"path/filepath"
14+
"strconv"
1415
"strings"
1516
"syscall"
1617

@@ -176,6 +177,19 @@ func parseMountFlagsAndOptions(optionList []string) (int, string, error) {
176177
return flags, strings.Join(options, ","), nil
177178
}
178179

180+
func parseOptions(optionList []string) map[string]string {
181+
options := make(map[string]string)
182+
for _, opt := range optionList {
183+
idx := strings.Index(opt, "=")
184+
if idx < 1 {
185+
continue
186+
}
187+
key, val := opt[:idx], opt[idx+1:]
188+
options[key] = val
189+
}
190+
return options
191+
}
192+
179193
func removeMounts(mounts []string) error {
180194
for _, mount := range mounts {
181195
if err := syscall.Unmount(mount, 0); err != nil {
@@ -198,6 +212,7 @@ var storageHandlerList = map[string]storageHandler{
198212
driverMmioBlkType: virtioMmioBlkStorageHandler,
199213
driverSCSIType: virtioSCSIStorageHandler,
200214
driverEphemeralType: ephemeralStorageHandler,
215+
driverLocalType: localStorageHandler,
201216
}
202217

203218
func ephemeralStorageHandler(storage pb.Storage, s *sandbox) (string, error) {
@@ -215,6 +230,29 @@ func ephemeralStorageHandler(storage pb.Storage, s *sandbox) (string, error) {
215230
return "", nil
216231
}
217232

233+
func localStorageHandler(storage pb.Storage, s *sandbox) (string, error) {
234+
s.Lock()
235+
defer s.Unlock()
236+
newStorage := s.setSandboxStorage(storage.MountPoint)
237+
if newStorage {
238+
239+
// Extract and parse the mode out of the storage options.
240+
// Default to os.ModePerm.
241+
opts := parseOptions(storage.Options)
242+
mode := os.ModePerm
243+
if val, ok := opts["mode"]; ok {
244+
m, err := strconv.ParseUint(val, 8, 32)
245+
if err != nil {
246+
return "", err
247+
}
248+
mode = os.FileMode(m)
249+
}
250+
251+
return "", os.MkdirAll(storage.MountPoint, mode)
252+
}
253+
return "", nil
254+
}
255+
218256
// virtio9pStorageHandler handles the storage for 9p driver.
219257
func virtio9pStorageHandler(storage pb.Storage, s *sandbox) (string, error) {
220258
return commonStorageHandler(storage)

mount_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,66 @@ func TestEphemeralStorageHandlerSuccessful(t *testing.T) {
4848
assert.Nil(t, err, "ephemeralStorageHandler() failed: %v", err)
4949
}
5050

51+
func TestLocalStorageHandlerSuccessful(t *testing.T) {
52+
skipUnlessRoot(t)
53+
54+
storage, err := createSafeAndFakeStorage()
55+
if err != nil {
56+
t.Fatal(err)
57+
}
58+
defer syscall.Unmount(storage.MountPoint, 0)
59+
defer os.RemoveAll(storage.MountPoint)
60+
61+
sbs := make(map[string]*sandboxStorage)
62+
_, err = localStorageHandler(storage, &sandbox{storages: sbs})
63+
assert.Nil(t, err, "localStorageHandler() failed: %v", err)
64+
}
65+
66+
func TestLocalStorageHandlerPermModeSuccessful(t *testing.T) {
67+
skipUnlessRoot(t)
68+
69+
storage, err := createSafeAndFakeStorage()
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
defer syscall.Unmount(storage.MountPoint, 0)
74+
defer os.RemoveAll(storage.MountPoint)
75+
76+
// Set the mode to be 0400 (ready only)
77+
storage.Options = []string{
78+
"mode=0400",
79+
}
80+
81+
sbs := make(map[string]*sandboxStorage)
82+
_, err = localStorageHandler(storage, &sandbox{storages: sbs})
83+
assert.Nil(t, err, "localStorageHandler() failed: %v", err)
84+
85+
// Check the mode of the mountpoint
86+
info, err := os.Stat(storage.MountPoint)
87+
assert.Nil(t, err)
88+
assert.Equal(t, 0400|os.ModeDir, info.Mode())
89+
}
90+
91+
func TestLocalStorageHandlerPermModeFailure(t *testing.T) {
92+
skipUnlessRoot(t)
93+
94+
storage, err := createSafeAndFakeStorage()
95+
if err != nil {
96+
t.Fatal(err)
97+
}
98+
//defer syscall.Unmount(storage.MountPoint, 0)
99+
//defer os.RemoveAll(storage.MountPoint)
100+
101+
// Set the mode to something invalid
102+
storage.Options = []string{
103+
"mode=abcde",
104+
}
105+
106+
sbs := make(map[string]*sandboxStorage)
107+
_, err = localStorageHandler(storage, &sandbox{storages: sbs})
108+
assert.NotNil(t, err, "localStorageHandler() should have failed")
109+
}
110+
51111
func TestVirtio9pStorageHandlerSuccessful(t *testing.T) {
52112
skipUnlessRoot(t)
53113

0 commit comments

Comments
 (0)