@@ -179,6 +179,7 @@ func NewCmdGPUCreate(t *terminal.Terminal, gpuCreateStore GPUCreateStore) *cobra
179179 var detached bool
180180 var timeout int
181181 var startupScript string
182+ var dryRun bool
182183 var filters searchFilterFlags
183184
184185 cmd := & cobra.Command {
@@ -203,6 +204,10 @@ func NewCmdGPUCreate(t *terminal.Terminal, gpuCreateStore GPUCreateStore) *cobra
203204
204205 // If no types provided, use search filters (or defaults) to find suitable GPUs
205206 if len (types ) == 0 {
207+ if dryRun {
208+ return runDryRun (t , gpuCreateStore , & filters )
209+ }
210+
206211 types , err = getFilteredInstanceTypes (gpuCreateStore , & filters )
207212 if err != nil {
208213 return breverrors .WrapAndTrace (err )
@@ -256,6 +261,7 @@ func NewCmdGPUCreate(t *terminal.Terminal, gpuCreateStore GPUCreateStore) *cobra
256261 cmd .Flags ().BoolVarP (& detached , "detached" , "d" , false , "Don't wait for instances to be ready" )
257262 cmd .Flags ().IntVar (& timeout , "timeout" , 300 , "Timeout in seconds for each instance to become ready" )
258263 cmd .Flags ().StringVarP (& startupScript , "startup-script" , "s" , "" , "Startup script to run on instance (string or @filepath)" )
264+ cmd .Flags ().BoolVar (& dryRun , "dry-run" , false , "Show matching instance types without creating anything" )
259265
260266 // Search filter flags (same as brev search, used when --type is not specified)
261267 cmd .Flags ().StringVarP (& filters .gpuName , "gpu-name" , "g" , "" , "Filter by GPU name (e.g., A100, H100)" )
@@ -312,22 +318,17 @@ func parseStartupScript(value string) (string, error) {
312318 return value , nil
313319}
314320
315- // getFilteredInstanceTypes fetches GPU instance types using user-provided filters
316- // merged with defaults. When a filter flag is not set, the default value is used.
317- func getFilteredInstanceTypes (s GPUCreateStore , filters * searchFilterFlags ) ([]InstanceSpec , error ) {
321+ // searchInstances fetches and filters GPU instances using user-provided filters merged with defaults
322+ func searchInstances (s GPUCreateStore , filters * searchFilterFlags ) ([]gpusearch.GPUInstanceInfo , float64 , error ) {
318323 response , err := s .GetInstanceTypes ()
319324 if err != nil {
320- return nil , breverrors .WrapAndTrace (err )
325+ return nil , 0 , breverrors .WrapAndTrace (err )
321326 }
322327
323328 if response == nil || len (response .Items ) == 0 {
324- return nil , nil
329+ return nil , 0 , nil
325330 }
326331
327- // Merge user-provided filters with defaults
328- gpuName := filters .gpuName
329- provider := filters .provider
330- minVRAM := filters .minVRAM
331332 minTotalVRAM := orDefault (filters .minTotalVRAM , defaultMinTotalVRAM )
332333 minCapability := orDefault (filters .minCapability , defaultMinCapability )
333334 minDisk := orDefault (filters .minDisk , defaultMinDisk )
@@ -341,10 +342,21 @@ func getFilteredInstanceTypes(s GPUCreateStore, filters *searchFilterFlags) ([]I
341342 }
342343
343344 instances := gpusearch .ProcessInstances (response .Items )
344- filtered := gpusearch .FilterInstances (instances , gpuName , provider , minVRAM , minTotalVRAM , minCapability , minDisk , maxBootTime ,
345- filters .stoppable , filters .rebootable , filters .flexPorts )
345+ filtered := gpusearch .FilterInstances (instances , filters . gpuName , filters . provider , filters . minVRAM ,
346+ minTotalVRAM , minCapability , minDisk , maxBootTime , filters .stoppable , filters .rebootable , filters .flexPorts )
346347 gpusearch .SortInstances (filtered , sortBy , filters .descending )
347348
349+ return filtered , minDisk , nil
350+ }
351+
352+ // getFilteredInstanceTypes fetches GPU instance types using user-provided filters
353+ // merged with defaults. When a filter flag is not set, the default value is used.
354+ func getFilteredInstanceTypes (s GPUCreateStore , filters * searchFilterFlags ) ([]InstanceSpec , error ) {
355+ filtered , minDisk , err := searchInstances (s , filters )
356+ if err != nil {
357+ return nil , breverrors .WrapAndTrace (err )
358+ }
359+
348360 var specs []InstanceSpec
349361 for _ , inst := range filtered {
350362 diskGB := inst .DiskMin
@@ -357,6 +369,17 @@ func getFilteredInstanceTypes(s GPUCreateStore, filters *searchFilterFlags) ([]I
357369 return specs , nil
358370}
359371
372+ // runDryRun shows the instance types that would be used without creating anything
373+ func runDryRun (t * terminal.Terminal , s GPUCreateStore , filters * searchFilterFlags ) error {
374+ filtered , _ , err := searchInstances (s , filters )
375+ if err != nil {
376+ return breverrors .WrapAndTrace (err )
377+ }
378+
379+ piped := isStdoutPiped ()
380+ return gpusearch .DisplayResults (t , filtered , false , piped )
381+ }
382+
360383// orDefault returns val if it's non-zero, otherwise returns def
361384func orDefault (val , def float64 ) float64 {
362385 if val > 0 {
0 commit comments