Skip to content

Commit f636937

Browse files
authored
uptake instancetypes APi (#421)
* feat(BRE2-966): uptake dev-plane instancetypes API * uptake buf * remove workspacegroup * migrate public
1 parent fbd6a24 commit f636937

24 files changed

Lines changed: 525 additions & 416 deletions

assets/test_workspace.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
{
2-
"workspaceId": "test_workspace_id",
3-
"workspaceGroupId": "test_workspace_group_id"
4-
}
2+
"workspaceId": "test_workspace_id"
3+
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ module github.com/brevdev/brev-cli
33
go 1.25.0
44

55
require (
6-
buf.build/gen/go/brevdev/devplane/connectrpc/go v1.20.0-20260626205643-49b0d20e08f1.1
7-
buf.build/gen/go/brevdev/devplane/protocolbuffers/go v1.36.11-20260626205643-49b0d20e08f1.1
6+
buf.build/gen/go/brevdev/devplane/connectrpc/go v1.20.0-20260708012811-ecba52f49600.1
7+
buf.build/gen/go/brevdev/devplane/protocolbuffers/go v1.36.11-20260708012811-ecba52f49600.1
88
connectrpc.com/connect v1.20.0
99
github.com/NVIDIA/go-nvml v0.13.0-1
1010
github.com/alessio/shellescape v1.4.1

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
buf.build/gen/go/brevdev/devplane/connectrpc/go v1.20.0-20260626205643-49b0d20e08f1.1 h1:Qj4BTbhIF0KE5YHiJJ+SN2goGYF8dJC1l8cv69YU/Ms=
2-
buf.build/gen/go/brevdev/devplane/connectrpc/go v1.20.0-20260626205643-49b0d20e08f1.1/go.mod h1:KW+lsYUmrF994Z/zj/wibrS7zhitXrYLicqR5BbVSp0=
3-
buf.build/gen/go/brevdev/devplane/protocolbuffers/go v1.36.11-20260626205643-49b0d20e08f1.1 h1:+GNKe6qV3aRH+N/FBlH6NfqyKOxMecAtbHndj3NPZc4=
4-
buf.build/gen/go/brevdev/devplane/protocolbuffers/go v1.36.11-20260626205643-49b0d20e08f1.1/go.mod h1:V/y7Wxg0QvU4XPVwqErF5NHLobUT1QEyfgrGuQIxdPo=
1+
buf.build/gen/go/brevdev/devplane/connectrpc/go v1.20.0-20260708012811-ecba52f49600.1 h1:xanul5g4JQ0OPAQ3tjN8bTznw+aA6B/oq3pzOy8kC8Q=
2+
buf.build/gen/go/brevdev/devplane/connectrpc/go v1.20.0-20260708012811-ecba52f49600.1/go.mod h1:ZxWENaPM6882Wtl2z6rZYVpXoagSyF6DiY/6m4BjGMU=
3+
buf.build/gen/go/brevdev/devplane/protocolbuffers/go v1.36.11-20260708012811-ecba52f49600.1 h1:KMs3AGf1zys1H8TnjBCorCd12zzWoUQae956KgsNfRM=
4+
buf.build/gen/go/brevdev/devplane/protocolbuffers/go v1.36.11-20260708012811-ecba52f49600.1/go.mod h1:V/y7Wxg0QvU4XPVwqErF5NHLobUT1QEyfgrGuQIxdPo=
55
buf.build/gen/go/brevdev/protoc-gen-gotag/protocolbuffers/go v1.36.11-20220906235457-8b4922735da5.1 h1:6amhprQmCKJ4wgJ6ngkh32d9V+dQcOLUZ/SfHdOnYgo=
66
buf.build/gen/go/brevdev/protoc-gen-gotag/protocolbuffers/go v1.36.11-20220906235457-8b4922735da5.1/go.mod h1:O+pnSHMru/naTMrm4tmpBoH3wz6PHa+R75HR7Mv8X2g=
77
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=

pkg/cmd/cmd.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,6 @@ func NewBrevCommand() *cobra.Command { //nolint:funlen,gocognit,gocyclo // defin
132132

133133
analytics.SetUserStore(noLoginCmdStore)
134134

135-
workspaceGroupID, err := fsStore.GetCurrentWorkspaceGroupID()
136-
if err != nil {
137-
fmt.Printf("%v\n", err)
138-
}
139-
if workspaceGroupID != "" {
140-
loginCmdStore.WithStaticHeader("X-Workspace-Group-ID", workspaceGroupID)
141-
noLoginCmdStore.WithStaticHeader("X-Workspace-Group-ID", workspaceGroupID)
142-
}
143-
144135
cmds := &cobra.Command{
145136
SilenceErrors: true,
146137
SilenceUsage: true,

pkg/cmd/create/create.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ func createEmptyWorkspace(user *entity.User, t *terminal.Terminal, options Creat
132132
} else {
133133
t.Vprintf("\tCPU instance %s\n", t.Green(cwOptions.WorkspaceClassID))
134134
}
135-
t.Vprintf("\tCloud %s\n\n", t.Green(cwOptions.WorkspaceGroupID))
136135

137136
s := t.NewSpinner()
138137
s.Suffix = " Creating your instance. Hang tight 🤙"

pkg/cmd/gpucreate/gpucreate.go

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ type GPUCreateStore interface {
105105
GetWorkspace(workspaceID string) (*entity.Workspace, error)
106106
CreateWorkspace(organizationID string, options *store.CreateWorkspacesOptions) (*entity.Workspace, error)
107107
DeleteWorkspace(workspaceID string) (*entity.Workspace, error)
108-
GetAllInstanceTypesWithWorkspaceGroups(orgID string) (*gpusearch.AllInstanceTypesResponse, error)
108+
GetAllInstanceTypesWithCloudCreds(orgID string) (*gpusearch.AllInstanceTypesResponse, error)
109109
GetLaunchable(launchableID string) (*store.LaunchableResponse, error)
110110
GetLaunchableLifeCycleScript(launchableID, scriptID string) (*store.LifeCycleScriptResponse, error)
111111
RedeemCouponCode(organizationID string, code string) (*store.RedeemCouponCodeResponse, error)
@@ -768,11 +768,11 @@ func newCreateContext(t *terminal.Terminal, store GPUCreateStore, opts GPUCreate
768768
}
769769
ctx.org = org
770770

771-
// Fetch instance types with workspace groups
772-
allInstanceTypes, err := store.GetAllInstanceTypesWithWorkspaceGroups(org.ID)
771+
// Fetch instance types with cloud credentials.
772+
allInstanceTypes, err := store.GetAllInstanceTypesWithCloudCreds(org.ID)
773773
if err != nil {
774-
ctx.logf("Warning: could not fetch instance types with workspace groups: %s\n", err.Error())
775-
ctx.logf("Falling back to default workspace group\n")
774+
ctx.logf("Warning: could not fetch instance types with cloud credentials: %s\n", err.Error())
775+
ctx.logf("Falling back to default cloud credential\n")
776776
}
777777
ctx.allInstanceTypes = allInstanceTypes
778778

@@ -791,7 +791,7 @@ func (c *createContext) validateInstanceTypeAvailability(instanceType string) er
791791
if c.allInstanceTypes == nil {
792792
return nil
793793
}
794-
if c.allInstanceTypes.GetWorkspaceGroupID(instanceType) != "" {
794+
if c.allInstanceTypes.GetCloudCredID(instanceType) != "" {
795795
return nil
796796
}
797797
if !c.allInstanceTypes.HasInstanceType(instanceType) {
@@ -1042,8 +1042,8 @@ func (c *createContext) createWorkspace(name string, spec InstanceSpec) (*entity
10421042
}
10431043

10441044
if c.allInstanceTypes != nil {
1045-
if wgID := c.allInstanceTypes.GetWorkspaceGroupID(spec.Type); wgID != "" {
1046-
cwOptions.WorkspaceGroupID = wgID
1045+
if cloudCredID := c.allInstanceTypes.GetCloudCredID(spec.Type); cloudCredID != "" {
1046+
cwOptions.WithCloudCredID(cloudCredID)
10471047
}
10481048
}
10491049

@@ -1057,10 +1057,10 @@ func (c *createContext) createWorkspace(name string, spec InstanceSpec) (*entity
10571057
}
10581058
}
10591059

1060-
if cwOptions.WorkspaceGroupID == "" {
1060+
if cwOptions.CloudCredID == "" {
10611061
if c.allInstanceTypes == nil {
10621062
return nil, breverrors.NewValidationError(fmt.Sprintf(
1063-
"could not resolve workspace group for %q (instance-type listing was unavailable); please retry",
1063+
"could not resolve cloud credential for %q (instance-type listing was unavailable); please retry",
10641064
spec.Type,
10651065
))
10661066
}
@@ -1176,13 +1176,17 @@ func applyLaunchableConfig(cwOptions *store.CreateWorkspacesOptions, launchableI
11761176
return
11771177
}
11781178

1179-
wsReq := info.CreateWorkspaceRequest
1179+
applyLaunchableWorkspaceRequest(cwOptions, info.CreateWorkspaceRequest)
1180+
applyLaunchableBuildRequest(cwOptions, info.BuildRequest)
1181+
applyLaunchableFile(cwOptions, info.File)
1182+
applyLaunchableLabels(cwOptions, launchableID, info)
1183+
}
11801184

1181-
// Use launchable's workspace group if not already resolved from instance types
1182-
if cwOptions.WorkspaceGroupID == "" && wsReq.WorkspaceGroupID != "" {
1183-
cwOptions.WorkspaceGroupID = wsReq.WorkspaceGroupID
1185+
func applyLaunchableWorkspaceRequest(cwOptions *store.CreateWorkspacesOptions, wsReq store.LaunchableWorkspaceRequest) {
1186+
// Use launchable's cloud credential if not already resolved from instance types.
1187+
if cwOptions.CloudCredID == "" && wsReq.CloudCredID != "" {
1188+
cwOptions.WithCloudCredID(wsReq.CloudCredID)
11841189
}
1185-
11861190
// Location / sub-location
11871191
if wsReq.Location != "" {
11881192
cwOptions.Location = wsReq.Location
@@ -1198,8 +1202,13 @@ func applyLaunchableConfig(cwOptions *store.CreateWorkspacesOptions, launchableI
11981202
cwOptions.DiskStorage = normalizeDiskStorage(wsReq.Storage)
11991203
}
12001204

1205+
if len(wsReq.FirewallRules) > 0 {
1206+
cwOptions.FirewallRules = resolveFirewallRulesClientIP(wsReq.FirewallRules, publicIPLookup)
1207+
}
1208+
}
1209+
1210+
func applyLaunchableBuildRequest(cwOptions *store.CreateWorkspacesOptions, build store.LaunchableBuildRequest) {
12011211
// Build configuration from launchable
1202-
build := info.BuildRequest
12031212
switch {
12041213
case build.VMBuild != nil:
12051214
cwOptions.VMBuild = build.VMBuild
@@ -1208,7 +1217,7 @@ func applyLaunchableConfig(cwOptions *store.CreateWorkspacesOptions, launchableI
12081217
cwOptions.CustomContainer = build.CustomContainer
12091218
case build.DockerCompose != nil:
12101219
cwOptions.VMBuild = nil
1211-
cwOptions.DockerCompose = build.DockerCompose
1220+
cwOptions.DockerCompose = normalizeLaunchableDockerCompose(build.DockerCompose)
12121221
}
12131222

12141223
// Port mappings from build request ports
@@ -1219,18 +1228,26 @@ func applyLaunchableConfig(cwOptions *store.CreateWorkspacesOptions, launchableI
12191228
}
12201229
cwOptions.PortMappings = portMappings
12211230
}
1231+
}
12221232

1223-
if len(wsReq.FirewallRules) > 0 {
1224-
cwOptions.FirewallRules = resolveFirewallRulesClientIP(wsReq.FirewallRules, publicIPLookup)
1233+
func normalizeLaunchableDockerCompose(dockerCompose *store.DockerCompose) *store.DockerCompose {
1234+
normalized := *dockerCompose
1235+
if normalized.FileURL != "" {
1236+
normalized.YamlString = ""
12251237
}
1238+
return &normalized
1239+
}
12261240

1241+
func applyLaunchableFile(cwOptions *store.CreateWorkspacesOptions, file *store.LaunchableFile) {
12271242
// Files from launchable
1228-
if info.File != nil {
1243+
if file != nil {
12291244
cwOptions.Files = []map[string]string{
1230-
{"url": info.File.URL, "path": info.File.Path},
1245+
{"url": file.URL, "path": file.Path},
12311246
}
12321247
}
1248+
}
12331249

1250+
func applyLaunchableLabels(cwOptions *store.CreateWorkspacesOptions, launchableID string, info *store.LaunchableResponse) {
12341251
// Labels for tracking and UI rendering — merge with any existing labels
12351252
var labels map[string]string
12361253
if existing, ok := cwOptions.Labels.(map[string]string); ok && existing != nil {
@@ -1239,8 +1256,8 @@ func applyLaunchableConfig(cwOptions *store.CreateWorkspacesOptions, launchableI
12391256
labels = make(map[string]string)
12401257
}
12411258
labels["launchableId"] = launchableID
1242-
labels["launchableInstanceType"] = wsReq.InstanceType
1243-
labels["workspaceGroupId"] = cwOptions.WorkspaceGroupID
1259+
labels["launchableInstanceType"] = info.CreateWorkspaceRequest.InstanceType
1260+
labels["cloudCredId"] = cwOptions.CloudCredID
12441261
labels["launchableCreatedByUserId"] = info.CreatedByUserID
12451262
labels["launchableCreatedByOrgId"] = info.CreatedByOrgID
12461263
labels["launchableRawURL"] = "/launchable/deploy/now?launchableID=" + launchableID

0 commit comments

Comments
 (0)