()
| 271 | } |
| 272 | |
| 273 | func (r *RootCmd) scheduleExtend() *serpent.Command { |
| 274 | extendCmd := &serpent.Command{ |
| 275 | Use: "extend <workspace-name> <duration from now>", |
| 276 | Aliases: []string{"override-stop"}, |
| 277 | Short: "Extend the stop time of a currently running workspace instance.", |
| 278 | Long: scheduleExtendDescriptionLong + "\n" + FormatExamples( |
| 279 | Example{ |
| 280 | Command: "coder schedule extend my-workspace 90m", |
| 281 | }, |
| 282 | ), |
| 283 | Middleware: serpent.Chain( |
| 284 | serpent.RequireNArgs(2), |
| 285 | ), |
| 286 | Handler: func(inv *serpent.Invocation) error { |
| 287 | client, err := r.InitClient(inv) |
| 288 | if err != nil { |
| 289 | return err |
| 290 | } |
| 291 | extendDuration, err := parseDuration(inv.Args[1]) |
| 292 | if err != nil { |
| 293 | return err |
| 294 | } |
| 295 | |
| 296 | workspace, err := client.ResolveWorkspace(inv.Context(), inv.Args[0]) |
| 297 | if err != nil { |
| 298 | return xerrors.Errorf("get workspace: %w", err) |
| 299 | } |
| 300 | |
| 301 | // Deadline extensions are not supported for prebuilt workspaces. |
| 302 | // Prebuild lifecycle is managed by the reconciliation loop, with TTL behavior |
| 303 | // defined per preset at the template level, not per workspace. |
| 304 | if workspace.IsPrebuild { |
| 305 | return xerrors.Errorf("extend configuration is not supported for prebuilt workspaces") |
| 306 | } |
| 307 | |
| 308 | loc, err := tz.TimezoneIANA() |
| 309 | if err != nil { |
| 310 | loc = time.UTC // best effort |
| 311 | } |
| 312 | |
| 313 | if extendDuration < 29*time.Minute { |
| 314 | _, _ = fmt.Fprintf( |
| 315 | inv.Stdout, |
| 316 | "Please specify a duration of at least 30 minutes.\n", |
| 317 | ) |
| 318 | return nil |
| 319 | } |
| 320 | |
| 321 | newDeadline := time.Now().In(loc).Add(extendDuration) |
| 322 | if err := client.PutExtendWorkspace(inv.Context(), workspace.ID, codersdk.PutExtendWorkspaceRequest{ |
| 323 | Deadline: newDeadline, |
| 324 | }); err != nil { |
| 325 | return err |
| 326 | } |
| 327 | |
| 328 | updated, err := client.ResolveWorkspace(inv.Context(), inv.Args[0]) |
| 329 | if err != nil { |
| 330 | return err |
no test coverage detected