mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 12:14:48 +00:00
runtime: Base64 encode the direct volume mountInfo path
This is to avoid accidentally deleting multiple volumes. Fixes #4020 Signed-off-by: Feng Wang <feng.wang@databricks.com>
This commit is contained in:
parent
5d0adb2164
commit
354cd3b9b6
@ -54,7 +54,10 @@ var addCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
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 {
|
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) {
|
Action: func(c *cli.Context) (string, error) {
|
||||||
stats, err := Stats(volumePath)
|
stats, err := Stats(volumePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", cli.NewExitError(err.Error(), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(stats), nil
|
return string(stats), nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -109,7 +114,10 @@ var resizeCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(c *cli.Context) error {
|
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
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
package volume
|
package volume
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
b64 "encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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.
|
// Add writes the mount info of a direct volume into a filesystem path known to Kata Container.
|
||||||
func Add(volumePath string, mountInfo string) error {
|
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)
|
stat, err := os.Stat(volumeDir)
|
||||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
if err != nil {
|
||||||
return err
|
if !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 := os.MkdirAll(volumeDir, 0700); err != nil {
|
if err := os.MkdirAll(volumeDir, 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if stat != nil && !stat.IsDir() {
|
||||||
|
return fmt.Errorf("%s should be a directory", volumeDir)
|
||||||
|
}
|
||||||
|
|
||||||
var deserialized MountInfo
|
var deserialized MountInfo
|
||||||
if err := json.Unmarshal([]byte(mountInfo), &deserialized); err != nil {
|
if err := json.Unmarshal([]byte(mountInfo), &deserialized); err != nil {
|
||||||
return err
|
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.
|
// Remove deletes the direct volume path including all the files inside it.
|
||||||
func Remove(volumePath string) error {
|
func Remove(volumePath string) error {
|
||||||
// Find the base of the volume path to delete the whole volume path
|
return os.RemoveAll(filepath.Join(kataDirectVolumeRootPath, b64.URLEncoding.EncodeToString([]byte(volumePath))))
|
||||||
base := strings.SplitN(volumePath, string(os.PathSeparator), 2)[0]
|
|
||||||
return os.RemoveAll(filepath.Join(kataDirectVolumeRootPath, base))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VolumeMountInfo retrieves the mount info of a direct volume.
|
// VolumeMountInfo retrieves the mount info of a direct volume.
|
||||||
func VolumeMountInfo(volumePath string) (*MountInfo, error) {
|
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 {
|
if _, err := os.Stat(mountInfoFilePath); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -84,16 +83,17 @@ func VolumeMountInfo(volumePath string) (*MountInfo, error) {
|
|||||||
|
|
||||||
// RecordSandboxId associates a sandbox id with a direct volume.
|
// RecordSandboxId associates a sandbox id with a direct volume.
|
||||||
func RecordSandboxId(sandboxId string, volumePath string) error {
|
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 {
|
if _, err := os.Stat(mountInfoFilePath); err != nil {
|
||||||
return err
|
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) {
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
package volume
|
package volume
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
b64 "encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
@ -22,7 +23,6 @@ func TestAdd(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
defer os.RemoveAll(kataDirectVolumeRootPath)
|
defer os.RemoveAll(kataDirectVolumeRootPath)
|
||||||
var volumePath = "/a/b/c"
|
var volumePath = "/a/b/c"
|
||||||
var basePath = "a"
|
|
||||||
actual := MountInfo{
|
actual := MountInfo{
|
||||||
VolumeType: "block",
|
VolumeType: "block",
|
||||||
Device: "/dev/sda",
|
Device: "/dev/sda",
|
||||||
@ -42,14 +42,15 @@ func TestAdd(t *testing.T) {
|
|||||||
assert.Equal(t, expected.FsType, actual.FsType)
|
assert.Equal(t, expected.FsType, actual.FsType)
|
||||||
assert.Equal(t, expected.Options, actual.Options)
|
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
|
// Remove the file
|
||||||
err = Remove(volumePath)
|
err = Remove(volumePath)
|
||||||
assert.Nil(t, err)
|
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))
|
assert.True(t, errors.Is(err, os.ErrNotExist))
|
||||||
|
_, err = os.Stat(filepath.Join(kataDirectVolumeRootPath))
|
||||||
// Test invalid mount info json
|
assert.Nil(t, err)
|
||||||
assert.Error(t, Add(volumePath, "{invalid json}"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRecordSandboxId(t *testing.T) {
|
func TestRecordSandboxId(t *testing.T) {
|
||||||
|
@ -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
|
// 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
|
// 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
|
// 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.
|
// the guest by Kata agent.
|
||||||
filename := b64.StdEncoding.EncodeToString([]byte(vol.Source))
|
filename := b64.URLEncoding.EncodeToString([]byte(vol.Source))
|
||||||
// Make the base64 encoding path safe.
|
|
||||||
filename = strings.ReplaceAll(filename, "/", "_")
|
|
||||||
path := filepath.Join(kataGuestSandboxStorageDir(), filename)
|
path := filepath.Join(kataGuestSandboxStorageDir(), filename)
|
||||||
|
|
||||||
// Update applicable OCI mount source
|
// Update applicable OCI mount source
|
||||||
|
Loading…
Reference in New Issue
Block a user