diff --git a/src/runtime/cmd/kata-runtime/kata-volume.go b/src/runtime/cmd/kata-runtime/kata-volume.go index 1477091299..e08e9482fa 100644 --- a/src/runtime/cmd/kata-runtime/kata-volume.go +++ b/src/runtime/cmd/kata-runtime/kata-volume.go @@ -54,7 +54,10 @@ var addCommand = cli.Command{ }, }, Action: func(c *cli.Context) error { - return volume.Add(volumePath, mountInfo) + if err := volume.Add(volumePath, mountInfo); err != nil { + return cli.NewExitError(err.Error(), 1) + } + return nil }, } @@ -69,7 +72,10 @@ var removeCommand = cli.Command{ }, }, Action: func(c *cli.Context) error { - return volume.Remove(volumePath) + if err := volume.Remove(volumePath); err != nil { + return cli.NewExitError(err.Error(), 1) + } + return nil }, } @@ -86,9 +92,8 @@ var statsCommand = cli.Command{ Action: func(c *cli.Context) (string, error) { stats, err := Stats(volumePath) if err != nil { - return "", err + return "", cli.NewExitError(err.Error(), 1) } - return string(stats), nil }, } @@ -109,7 +114,10 @@ var resizeCommand = cli.Command{ }, }, Action: func(c *cli.Context) error { - return Resize(volumePath, size) + if err := Resize(volumePath, size); err != nil { + return cli.NewExitError(err.Error(), 1) + } + return nil }, } diff --git a/src/runtime/pkg/direct-volume/utils.go b/src/runtime/pkg/direct-volume/utils.go index 275b0508f8..124e8b4ab5 100644 --- a/src/runtime/pkg/direct-volume/utils.go +++ b/src/runtime/pkg/direct-volume/utils.go @@ -6,13 +6,13 @@ package volume import ( + b64 "encoding/base64" "encoding/json" "errors" "fmt" "io/ioutil" "os" "path/filepath" - "strings" ) const ( @@ -37,19 +37,20 @@ type MountInfo struct { // Add writes the mount info of a direct volume into a filesystem path known to Kata Container. func Add(volumePath string, mountInfo string) error { - volumeDir := filepath.Join(kataDirectVolumeRootPath, volumePath) + volumeDir := filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath))) stat, err := os.Stat(volumeDir) - if err != nil && !errors.Is(err, os.ErrNotExist) { - return err - } - if stat != nil && !stat.IsDir() { - return fmt.Errorf("%s should be a directory", volumeDir) - } - if errors.Is(err, os.ErrNotExist) { + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } if err := os.MkdirAll(volumeDir, 0700); err != nil { return err } } + if stat != nil && !stat.IsDir() { + return fmt.Errorf("%s should be a directory", volumeDir) + } + var deserialized MountInfo if err := json.Unmarshal([]byte(mountInfo), &deserialized); err != nil { return err @@ -60,14 +61,12 @@ func Add(volumePath string, mountInfo string) error { // Remove deletes the direct volume path including all the files inside it. func Remove(volumePath string) error { - // Find the base of the volume path to delete the whole volume path - base := strings.SplitN(volumePath, string(os.PathSeparator), 2)[0] - return os.RemoveAll(filepath.Join(kataDirectVolumeRootPath, base)) + return os.RemoveAll(filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath)))) } // VolumeMountInfo retrieves the mount info of a direct volume. func VolumeMountInfo(volumePath string) (*MountInfo, error) { - mountInfoFilePath := filepath.Join(kataDirectVolumeRootPath, volumePath, mountInfoFileName) + mountInfoFilePath := filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath)), mountInfoFileName) if _, err := os.Stat(mountInfoFilePath); err != nil { return nil, err } @@ -84,16 +83,17 @@ func VolumeMountInfo(volumePath string) (*MountInfo, error) { // RecordSandboxId associates a sandbox id with a direct volume. func RecordSandboxId(sandboxId string, volumePath string) error { - mountInfoFilePath := filepath.Join(kataDirectVolumeRootPath, volumePath, mountInfoFileName) + encodedPath := b64.URLEncoding.EncodeToString([]byte(volumePath)) + mountInfoFilePath := filepath.Join(kataDirectVolumeRootPath, encodedPath, mountInfoFileName) if _, err := os.Stat(mountInfoFilePath); err != nil { return err } - return ioutil.WriteFile(filepath.Join(kataDirectVolumeRootPath, volumePath, sandboxId), []byte(""), 0600) + return ioutil.WriteFile(filepath.Join(kataDirectVolumeRootPath, encodedPath, sandboxId), []byte(""), 0600) } func GetSandboxIdForVolume(volumePath string) (string, error) { - files, err := ioutil.ReadDir(filepath.Join(kataDirectVolumeRootPath, volumePath)) + files, err := ioutil.ReadDir(filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath)))) if err != nil { return "", err } diff --git a/src/runtime/pkg/direct-volume/utils_test.go b/src/runtime/pkg/direct-volume/utils_test.go index 6ca80dab81..0fa8abb1c7 100644 --- a/src/runtime/pkg/direct-volume/utils_test.go +++ b/src/runtime/pkg/direct-volume/utils_test.go @@ -6,6 +6,7 @@ package volume import ( + b64 "encoding/base64" "encoding/json" "errors" "os" @@ -22,7 +23,6 @@ func TestAdd(t *testing.T) { assert.Nil(t, err) defer os.RemoveAll(kataDirectVolumeRootPath) var volumePath = "/a/b/c" - var basePath = "a" actual := MountInfo{ VolumeType: "block", Device: "/dev/sda", @@ -42,14 +42,15 @@ func TestAdd(t *testing.T) { assert.Equal(t, expected.FsType, actual.FsType) assert.Equal(t, expected.Options, actual.Options) + _, err = os.Stat(filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath)))) + assert.Nil(t, err) // Remove the file err = Remove(volumePath) assert.Nil(t, err) - _, err = os.Stat(filepath.Join(kataDirectVolumeRootPath, basePath)) + _, err = os.Stat(filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath)))) assert.True(t, errors.Is(err, os.ErrNotExist)) - - // Test invalid mount info json - assert.Error(t, Add(volumePath, "{invalid json}")) + _, err = os.Stat(filepath.Join(kataDirectVolumeRootPath)) + assert.Nil(t, err) } func TestRecordSandboxId(t *testing.T) { diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index 339b2220b2..c2a8c901f4 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -1549,11 +1549,9 @@ func (k *kataAgent) handleBlkOCIMounts(c *Container, spec *specs.Spec) ([]*grpc. // Each device will be mounted at a unique location within the VM only once. Mounting // to the container specific location is handled within the OCI spec. Let's ensure that // the storage mount point is unique for each device. This is then utilized as the source - // in the OCI spec. If multiple containers mount the same block device, it's refcounted inside + // in the OCI spec. If multiple containers mount the same block device, it's ref-counted inside // the guest by Kata agent. - filename := b64.StdEncoding.EncodeToString([]byte(vol.Source)) - // Make the base64 encoding path safe. - filename = strings.ReplaceAll(filename, "/", "_") + filename := b64.URLEncoding.EncodeToString([]byte(vol.Source)) path := filepath.Join(kataGuestSandboxStorageDir(), filename) // Update applicable OCI mount source