@@ -16,6 +16,7 @@ import (
1616 "github.com/launchdarkly/go-sdk-common/v3/ldcontext"
1717 "go.opentelemetry.io/otel/attribute"
1818 "go.opentelemetry.io/otel/trace"
19+ "go.uber.org/zap"
1920 "golang.org/x/net/idna"
2021
2122 "github.com/e2b-dev/infra/packages/api/internal/api"
@@ -31,6 +32,7 @@ import (
3132 "github.com/e2b-dev/infra/packages/shared/pkg/ginutils"
3233 "github.com/e2b-dev/infra/packages/shared/pkg/grpc/orchestrator"
3334 "github.com/e2b-dev/infra/packages/shared/pkg/id"
35+ "github.com/e2b-dev/infra/packages/shared/pkg/logger"
3436 sbxlogger "github.com/e2b-dev/infra/packages/shared/pkg/logger/sandbox"
3537 sandbox_network "github.com/e2b-dev/infra/packages/shared/pkg/sandbox-network"
3638 "github.com/e2b-dev/infra/packages/shared/pkg/telemetry"
@@ -185,9 +187,15 @@ func (a *APIStore) PostSandboxes(c *gin.Context) {
185187 }
186188
187189 sbxVolumeMounts , err := convertAPIVolumesToOrchestratorVolumes (
188- ctx , a .sqlcDB , a .featureFlags , teamInfo .ID , apiVolumeMounts ,
190+ ctx , a .sqlcDB , a .featureFlags , teamInfo .ID , apiVolumeMounts , build ,
189191 )
190192 if err != nil {
193+ if errors .Is (err , errVolumesNotSupported ) {
194+ a .sendAPIStoreError (c , http .StatusBadRequest , err .Error ())
195+
196+ return
197+ }
198+
191199 if errors .Is (err , ErrVolumeMountsDisabled ) {
192200 a .sendAPIStoreError (c , http .StatusBadRequest , "Volume mounts are not enabled." )
193201
@@ -292,21 +300,36 @@ func (im InvalidVolumeMountsError) Error() string {
292300 return fmt .Sprintf ("invalid mounts:\n %s" , strings .Join (errs , "\n " ))
293301}
294302
295- func convertAPIVolumesToOrchestratorVolumes (
296- ctx context.Context ,
297- sqlClient * sqlcdb.Client ,
298- featureFlags featureFlagsClient ,
299- teamID uuid.UUID ,
300- volumeMounts []api.SandboxVolumeMount ,
301- ) ([]* orchestrator.SandboxVolumeMount , error ) {
303+ var errVolumesNotSupported = errors .New ("volumes are not supported" )
304+
305+ var errNoEnvdVersion = errors .New ("no envd version provided" )
306+
307+ const minEnvdVersionForVolumes = "0.5.8"
308+
309+ func convertAPIVolumesToOrchestratorVolumes (ctx context.Context , sqlClient * sqlcdb.Client , featureFlags featureFlagsClient , teamID uuid.UUID , volumeMounts []api.SandboxVolumeMount , env * queries.EnvBuild ) ([]* orchestrator.SandboxVolumeMount , error ) {
310+ // are any volumes configured?
302311 if len (volumeMounts ) == 0 {
303312 return []* orchestrator.SandboxVolumeMount {}, nil // only b/c you should never return (nil, nil)
304313 }
305314
315+ // are volumes enabled?
306316 if ! featureFlags .BoolFlag (ctx , featureflags .PersistentVolumesFlag ) {
307317 return nil , ErrVolumeMountsDisabled
308318 }
309319
320+ // does your envd version support volumes?
321+ if envdVersion := sharedUtils .DerefOrDefault (env .EnvdVersion , "" ); envdVersion == "" {
322+ logger .L ().Warn (ctx , "envd version is unset" )
323+
324+ return nil , errNoEnvdVersion
325+ } else if ok , err := sharedUtils .IsGTEVersion (envdVersion , minEnvdVersionForVolumes ); err != nil {
326+ logger .L ().Warn (ctx , "failed to check envd version" , zap .Error (err ), zap .String ("envd_version" , envdVersion ))
327+
328+ return nil , fmt .Errorf ("invalid envd version %q: %w" , envdVersion , err )
329+ } else if ! ok {
330+ return nil , fmt .Errorf ("%w; template must be rebuilt. Template envd version is %s, must be at least %s to support volumes" , errVolumesNotSupported , envdVersion , minEnvdVersionForVolumes )
331+ }
332+
310333 // get volumes from the database
311334 dbVolumesMap , err := getDBVolumesMap (ctx , sqlClient , teamID , volumeMounts )
312335 if err != nil {
0 commit comments