From d4ddbd7c380bce554d4b6f753dd31ef53d4161cf Mon Sep 17 00:00:00 2001 From: Bryce Adelstein Lelbach Date: Sun, 2 Aug 2026 11:22:56 +0000 Subject: [PATCH 1/3] fix(create): include Shadeform instance types --- pkg/store/instancetypes.go | 5 ++++- pkg/store/instancetypes_test.go | 25 ++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/pkg/store/instancetypes.go b/pkg/store/instancetypes.go index b873345b..521c5509 100644 --- a/pkg/store/instancetypes.go +++ b/pkg/store/instancetypes.go @@ -58,7 +58,10 @@ func (s AuthHTTPStore) GetAllInstanceTypesWithCloudCreds(orgID string) (*gpusear includePreemptible := false includeCPU := true uniqueInstanceType := true - skipAccessFilter := false + // The create flow must see every type the organization can launch through + // its cloud credentials, including reserved-pool types surfaced by search. + // Capacity is still filtered by IncludeUnavailable above. + skipAccessFilter := true res, err := client.ListOrganizationAvailableInstanceTypes(context.Background(), connect.NewRequest(&devplaneapiv1.ListOrganizationAvailableInstanceTypesRequest{ OrganizationId: orgID, Options: &devplaneapiv1.ListInstanceTypeOptions{ diff --git a/pkg/store/instancetypes_test.go b/pkg/store/instancetypes_test.go index 085822af..8b24d33f 100644 --- a/pkg/store/instancetypes_test.go +++ b/pkg/store/instancetypes_test.go @@ -20,6 +20,7 @@ type instanceCatalogTestHandler struct { gotOrgID string gotConnectProtocolVersion string gotIncludeCPU bool + gotSkipAccessFilter bool } func (h *instanceCatalogTestHandler) ListPublicInstanceType( @@ -79,19 +80,24 @@ func (h *instanceCatalogTestHandler) ListOrganizationAvailableInstanceTypes( h.gotAuth = req.Header().Get("Authorization") h.gotOrgID = req.Msg.GetOrganizationId() h.gotConnectProtocolVersion = req.Header().Get("Connect-Protocol-Version") - return connect.NewResponse(&devplaneapiv1.ListOrganizationAvailableInstanceTypesResponse{ - Items: []*devplaneapiv1.InstanceType{{ - Type: "h100-1x", + h.gotSkipAccessFilter = req.Msg.GetOptions().GetSkipAccessFilter() + items := []*devplaneapiv1.InstanceType{} + if h.gotSkipAccessFilter { + items = append(items, &devplaneapiv1.InstanceType{ + Type: "verda_RTXPro6000", CloudCredId: "cc-org-1", CloudCred: &devplaneapiv1.CloudCredMetadata{ CloudCredId: "cc-org-1", - ProviderId: "aws", - Name: "Org AWS", + ProviderId: "shadeform", + Name: "Shadeform", TenantType: devplaneapiv1.TenantType_TENANT_TYPE_ISOLATED, }, - AvailableLocations: []string{"us-east-1"}, + AvailableLocations: []string{"us-central-1"}, IsAvailable: true, - }}, + }) + } + return connect.NewResponse(&devplaneapiv1.ListOrganizationAvailableInstanceTypesResponse{ + Items: items, }), nil } @@ -119,9 +125,10 @@ func TestGetAllInstanceTypesWithCloudCredsUsesDevPlanePublicAPI(t *testing.T) { assert.Equal(t, "Bearer tok", catalogHandler.gotAuth) assert.Equal(t, "1", catalogHandler.gotConnectProtocolVersion) assert.Equal(t, "org-1", catalogHandler.gotOrgID) + assert.True(t, catalogHandler.gotSkipAccessFilter) if assert.Len(t, resp.AllInstanceTypes, 1) { - assert.Equal(t, "h100-1x", resp.AllInstanceTypes[0].Type) - assert.Equal(t, "cc-org-1", resp.GetCloudCredID("h100-1x")) + assert.Equal(t, "verda_RTXPro6000", resp.AllInstanceTypes[0].Type) + assert.Equal(t, "cc-org-1", resp.GetCloudCredID("verda_RTXPro6000")) } } From b5d72f2f6e574e82d19f6c6cb91e0394681e91e1 Mon Sep 17 00:00:00 2001 From: Bryce Adelstein Lelbach Date: Mon, 3 Aug 2026 23:39:04 +0000 Subject: [PATCH 2/3] fix(create): accept public Shadeform types --- pkg/cmd/gpucreate/gpucreate.go | 29 +++++++++++++++++++++-------- pkg/cmd/gpucreate/gpucreate_test.go | 10 ++++++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/pkg/cmd/gpucreate/gpucreate.go b/pkg/cmd/gpucreate/gpucreate.go index 54a07b68..09c00b7d 100644 --- a/pkg/cmd/gpucreate/gpucreate.go +++ b/pkg/cmd/gpucreate/gpucreate.go @@ -895,14 +895,15 @@ func formatInstanceSpecs(specs []InstanceSpec) string { // createContext holds shared state for instance creation type createContext struct { - t *terminal.Terminal - store GPUCreateStore - opts GPUCreateOptions - org *entity.Organization - user *entity.User - allInstanceTypes *gpusearch.AllInstanceTypesResponse - piped bool - logf func(format string, a ...interface{}) + t *terminal.Terminal + store GPUCreateStore + opts GPUCreateOptions + org *entity.Organization + user *entity.User + allInstanceTypes *gpusearch.AllInstanceTypesResponse + publicInstanceTypes *gpusearch.InstanceTypesResponse + piped bool + logf func(format string, a ...interface{}) } // newCreateContext initializes the context for instance creation @@ -952,6 +953,11 @@ func newCreateContext(t *terminal.Terminal, store GPUCreateStore, opts GPUCreate ctx.logf("Falling back to default cloud credential\n") } ctx.allInstanceTypes = allInstanceTypes + publicInstanceTypes, publicErr := store.GetInstanceTypes(false) + if publicErr != nil { + ctx.logf("Warning: could not fetch public instance types: %s\n", publicErr.Error()) + } + ctx.publicInstanceTypes = publicInstanceTypes return ctx, nil } @@ -972,6 +978,13 @@ func (c *createContext) validateInstanceTypeAvailability(instanceType string) er return nil } if !c.allInstanceTypes.HasInstanceType(instanceType) { + if c.publicInstanceTypes != nil { + for _, it := range c.publicInstanceTypes.Items { + if it.Type == instanceType { + return nil + } + } + } return breverrors.NewValidationError(fmt.Sprintf( "instance type %q is not a recognized type; run 'brev search' to see available types", instanceType, diff --git a/pkg/cmd/gpucreate/gpucreate_test.go b/pkg/cmd/gpucreate/gpucreate_test.go index 93b2c1a0..37ac0eda 100644 --- a/pkg/cmd/gpucreate/gpucreate_test.go +++ b/pkg/cmd/gpucreate/gpucreate_test.go @@ -1144,6 +1144,16 @@ func TestValidateInstanceTypeAvailability(t *testing.T) { assert.Contains(t, err.Error(), "brev search") }) + t.Run("accepts a public Shadeform type omitted from the org listing", func(t *testing.T) { + ctx := &createContext{ + allInstanceTypes: &gpusearch.AllInstanceTypesResponse{}, + publicInstanceTypes: &gpusearch.InstanceTypesResponse{Items: []gpusearch.InstanceType{ + {Type: "verda_RTXPro6000"}, + }}, + } + assert.NoError(t, ctx.validateInstanceTypeAvailability("verda_RTXPro6000")) + }) + t.Run("returns unavailable error for known type without a cloud credential", func(t *testing.T) { ctx := &createContext{ allInstanceTypes: &gpusearch.AllInstanceTypesResponse{ From 5387e90e78302583c51dd10b80a184853eb4cf2a Mon Sep 17 00:00:00 2001 From: Bryce Adelstein Lelbach Date: Mon, 3 Aug 2026 23:40:36 +0000 Subject: [PATCH 3/3] fix(create): use public Shadeform credential --- pkg/cmd/gpucreate/gpucreate.go | 8 ++++++++ pkg/cmd/gpucreate/gpucreate_test.go | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/pkg/cmd/gpucreate/gpucreate.go b/pkg/cmd/gpucreate/gpucreate.go index 09c00b7d..b73f5091 100644 --- a/pkg/cmd/gpucreate/gpucreate.go +++ b/pkg/cmd/gpucreate/gpucreate.go @@ -1236,6 +1236,14 @@ func (c *createContext) createWorkspace(name string, spec InstanceSpec) (*entity cwOptions.WithCloudCredID(cloudCredID) } } + if cwOptions.CloudCredID == "" && c.publicInstanceTypes != nil { + for _, it := range c.publicInstanceTypes.Items { + if it.Type == spec.Type && it.CloudCredID != "" { + cwOptions.WithCloudCredID(it.CloudCredID) + break + } + } + } // Apply launchable config or build mode if c.opts.LaunchableID != "" { diff --git a/pkg/cmd/gpucreate/gpucreate_test.go b/pkg/cmd/gpucreate/gpucreate_test.go index 37ac0eda..19b5e0f4 100644 --- a/pkg/cmd/gpucreate/gpucreate_test.go +++ b/pkg/cmd/gpucreate/gpucreate_test.go @@ -1262,6 +1262,27 @@ func TestCreateInstancesWithTypeSetsCloudCredIDFromCatalog(t *testing.T) { assert.Equal(t, "cc-shadeform", mock.CreatedOptions[0].CloudCredID) } +func TestCreateInstancesWithTypeSetsCloudCredIDFromPublicCatalog(t *testing.T) { + mock := NewMockGPUCreateStore() + ctx := &createContext{ + t: terminal.New(), + store: mock, + opts: GPUCreateOptions{Count: 1, Parallel: 1, Name: "jt-4"}, + org: mock.Org, + user: mock.User, + piped: true, + allInstanceTypes: &gpusearch.AllInstanceTypesResponse{}, + publicInstanceTypes: &gpusearch.InstanceTypesResponse{Items: []gpusearch.InstanceType{{Type: "verda_RTXPro6000", CloudCredID: "cc-public-shadeform"}}}, + } + ctx.logf = func(_ string, _ ...interface{}) {} + + result := ctx.createInstancesWithType(InstanceSpec{Type: "verda_RTXPro6000"}, 0, 1) + + assert.False(t, result.hadFailure) + require.Len(t, mock.CreatedOptions, 1) + assert.Equal(t, "cc-public-shadeform", mock.CreatedOptions[0].CloudCredID) +} + func TestCreateInstancesWithTypeBypassesValidationForLaunchable(t *testing.T) { mock := NewMockGPUCreateStore() ctx := &createContext{