Skip to content

Commit

Permalink
feat(sdl): "ram" storage class
Browse files Browse the repository at this point in the history
* Add SDL support for `"ram"` storage class.
* `"ram"` volumes cannot be persistent or `ReadOnly`.

refs akash-network/support#179

Signed-off-by: Adam Bozanich <adam.boz@gmail.com>
  • Loading branch information
boz committed Feb 26, 2024
1 parent 2b47656 commit 44514dc
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 36 deletions.
30 changes: 21 additions & 9 deletions sdl/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
StorageAttributeMount = "mount"
StorageAttributeReadOnly = "readOnly" // we might not need it at this point of time
StorageClassDefault = "default"
StorageClassRAM = "ram"
)

var (
Expand All @@ -25,6 +26,7 @@ var (
errStorageMultipleRootEphemeral = errors.New("sdl: multiple root ephemeral storages are not allowed")
errStorageDuplicatedVolumeName = errors.New("sdl: duplicated volume name")
errStorageEphemeralClass = errors.New("sdl: ephemeral storage should not set attribute class")
errStorageRAMClass = errors.New("sdl: ram storage class cannot be persistent")
)

type v2StorageAttributes types.Attributes
Expand All @@ -45,10 +47,11 @@ type v2ResourceStorageArray []v2ResourceStorage
type validateAttrFn func(string, *string) error

var allowedStorageClasses = map[string]bool{
"default": true,
"beta1": true,
"beta2": true,
"beta3": true,
"default": true,
"beta1": true,
"beta2": true,
"beta3": true,
StorageClassRAM: true,
}

var validateStorageAttributes = map[string]validateAttrFn{
Expand Down Expand Up @@ -162,11 +165,20 @@ func (sdl *v2StorageAttributes) UnmarshalYAML(node *yaml.Node) error {

persistent := res[StorageAttributePersistent]
class := res[StorageAttributeClass]
if persistent == valueFalse && class != "" {
return errStorageEphemeralClass
}
if persistent == valueTrue && class == "" {
res[StorageAttributeClass] = StorageClassDefault

switch class {
case "":
if persistent == valueTrue {
res[StorageAttributeClass] = StorageClassDefault
}
case StorageClassRAM:
if persistent != valueFalse {
return errStorageRAMClass
}
default:
if persistent == valueFalse {
return errStorageEphemeralClass
}
}

for k, v := range res {
Expand Down
32 changes: 32 additions & 0 deletions sdl/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,38 @@ func TestStorage_PersistentClass(t *testing.T) {
require.Equal(t, p[0].Attributes[0].Value, "beta1")
}

func TestStorage_RAMClass_Valid(t *testing.T) {
var stream = `
- size: 1Gi
attributes:
persistent: false
class: ram
`

var p v2ResourceStorageArray

err := yaml.Unmarshal([]byte(stream), &p)
require.NoError(t, err)
require.Len(t, p[0].Attributes, 2)

require.Equal(t, p[0].Attributes[0].Key, "class")
require.Equal(t, p[0].Attributes[0].Value, "ram")
}

func TestStorage_RamClass_Invalid(t *testing.T) {
var stream = `
- size: 1Gi
attributes:
persistent: true
class: ram
`

var p v2ResourceStorageArray

err := yaml.Unmarshal([]byte(stream), &p)
require.Error(t, err)
}

func TestStorage_StableSort(t *testing.T) {
storage := v2ResourceStorageArray{
{
Expand Down
65 changes: 38 additions & 27 deletions sdl/v2_1.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,14 @@ func (sdl *v2_1) validate() error {
}
}

attr := make(map[string]string)
mounts := make(map[string]string)

if svc.Params != nil {
mounts := make(map[string]string)

Check warning on line 233 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L232-L233

Added lines #L232 - L233 were not covered by tests
for name, params := range svc.Params.Storage {
if _, exists := volumes[name]; !exists {

volume, exists := volumes[name]

if !exists {

Check warning on line 238 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L235-L238

Added lines #L235 - L238 were not covered by tests
return fmt.Errorf(
"%w: service \"%s\" references to no-existing compute volume named \"%s\"",
errSDLInvalid,
Expand All @@ -251,42 +253,51 @@ func (sdl *v2_1) validate() error {
)
}

attr[StorageAttributeMount] = params.Mount
attr[StorageAttributeReadOnly] = strconv.FormatBool(params.ReadOnly)

mount := attr[StorageAttributeMount]
if vlname, exists := mounts[mount]; exists {
if mount == "" {
if vlname, exists := mounts[params.Mount]; exists {
if params.Mount == "" {

Check warning on line 257 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L256-L257

Added lines #L256 - L257 were not covered by tests
return errStorageMultipleRootEphemeral
}

return fmt.Errorf(
"%w: mount %q already in use by volume %q",
errStorageDupMountPoint,
mount,
params.Mount,

Check warning on line 264 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L264

Added line #L264 was not covered by tests
vlname,
)
}

mounts[mount] = name
}
}
mounts[params.Mount] = name

Check warning on line 269 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L269

Added line #L269 was not covered by tests

for name, volume := range volumes {
for _, nd := range types.Attributes(volume.Attributes) {
attr[nd.Key] = nd.Value
}
attr := make(map[string]string)
attr[StorageAttributeMount] = params.Mount
attr[StorageAttributeReadOnly] = strconv.FormatBool(params.ReadOnly)

for _, nd := range types.Attributes(volume.Attributes) {
attr[nd.Key] = nd.Value
}

Check warning on line 277 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L271-L277

Added lines #L271 - L277 were not covered by tests

persistent, _ := strconv.ParseBool(attr[StorageAttributePersistent])
persistent, _ := strconv.ParseBool(attr[StorageAttributePersistent])
class := attr[StorageAttributeClass]

Check warning on line 280 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L279-L280

Added lines #L279 - L280 were not covered by tests

if persistent && attr[StorageAttributeMount] == "" {
return fmt.Errorf(
"%w: compute.storage.%s has persistent=true which requires service.%s.params.storage.%s to have mount",
errSDLInvalid,
name,
svcName,
name,
)
if persistent && params.Mount == "" {
return fmt.Errorf(
"%w: compute.storage.%s has persistent=true which requires service.%s.params.storage.%s to have mount",
errSDLInvalid,
name,
svcName,
name,
)
}

Check warning on line 290 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L282-L290

Added lines #L282 - L290 were not covered by tests

if class == StorageClassRAM && params.ReadOnly {
return fmt.Errorf(
"%w: services.%s.params.storage.%s has readOnly=true which is not allowed for storage class \"%s\"",
errSDLInvalid,
svcName,
name,
class,
)
}

Check warning on line 300 in sdl/v2_1.go

View check run for this annotation

Codecov / codecov/patch

sdl/v2_1.go#L292-L300

Added lines #L292 - L300 were not covered by tests
}
}
}
Expand Down

0 comments on commit 44514dc

Please sign in to comment.