Skip to content

Commit d91157f

Browse files
committed
fix: simplify CLI --protected flag to accept optional duration
- Change --protected from bool to string flag accepting duration - Remove separate --protection-duration flag - Usage: --protected (default duration), --protected=1440 (1 day), --protected=0 (forever), --protected=false (disable) - Fix lint error by using constant for default warning minutes
1 parent 3fda0d1 commit d91157f

3 files changed

Lines changed: 49 additions & 26 deletions

File tree

engine/cmd/cli/commands/clone/actions.go

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"net/url"
1313
"os"
1414
"path"
15+
"strconv"
1516
"strings"
1617
"sync"
1718

@@ -25,6 +26,33 @@ import (
2526
"gitlab.com/postgres-ai/database-lab/v3/pkg/models"
2627
)
2728

29+
// parseProtectionFlag parses the --protected flag value.
30+
// Returns (isProtected, durationMinutes, error).
31+
// durationMinutes is nil if default duration should be used.
32+
func parseProtectionFlag(cliCtx *cli.Context) (bool, *uint, error) {
33+
if !cliCtx.IsSet("protected") {
34+
return false, nil, nil
35+
}
36+
37+
value := cliCtx.String("protected")
38+
39+
switch strings.ToLower(value) {
40+
case "", "true":
41+
return true, nil, nil
42+
case "false":
43+
return false, nil, nil
44+
default:
45+
duration, err := strconv.ParseUint(value, 10, 64)
46+
if err != nil {
47+
return false, nil, errors.Errorf("invalid protection duration: %s (expected number of minutes or 'true'/'false')", value)
48+
}
49+
50+
d := uint(duration)
51+
52+
return true, &d, nil
53+
}
54+
}
55+
2856
// list runs a request to list clones of an instance.
2957
func list(cliCtx *cli.Context) error {
3058
dblabClient, err := commands.ClientByCLIContext(cliCtx)
@@ -96,9 +124,15 @@ func create(cliCtx *cli.Context) error {
96124
return err
97125
}
98126

127+
isProtected, protectionDuration, err := parseProtectionFlag(cliCtx)
128+
if err != nil {
129+
return err
130+
}
131+
99132
cloneRequest := types.CloneCreateRequest{
100-
ID: cliCtx.String("id"),
101-
Protected: cliCtx.Bool("protected"),
133+
ID: cliCtx.String("id"),
134+
Protected: isProtected,
135+
ProtectionDurationMinutes: protectionDuration,
102136
DB: &types.DatabaseRequest{
103137
Username: cliCtx.String("username"),
104138
Password: cliCtx.String("password"),
@@ -108,11 +142,6 @@ func create(cliCtx *cli.Context) error {
108142
Branch: cliCtx.String("branch"),
109143
}
110144

111-
if cliCtx.IsSet("protection-duration") {
112-
duration := cliCtx.Uint("protection-duration")
113-
cloneRequest.ProtectionDurationMinutes = &duration
114-
}
115-
116145
if cliCtx.IsSet("snapshot-id") {
117146
cloneRequest.Snapshot = &types.SnapshotCloneFieldRequest{ID: cliCtx.String("snapshot-id")}
118147
}
@@ -189,13 +218,14 @@ func update(cliCtx *cli.Context) error {
189218
return err
190219
}
191220

192-
updateRequest := types.CloneUpdateRequest{
193-
Protected: cliCtx.Bool("protected"),
221+
isProtected, protectionDuration, err := parseProtectionFlag(cliCtx)
222+
if err != nil {
223+
return err
194224
}
195225

196-
if cliCtx.IsSet("protection-duration") {
197-
duration := cliCtx.Uint("protection-duration")
198-
updateRequest.ProtectionDurationMinutes = &duration
226+
updateRequest := types.CloneUpdateRequest{
227+
Protected: isProtected,
228+
ProtectionDurationMinutes: protectionDuration,
199229
}
200230

201231
cloneID := cliCtx.Args().First()

engine/cmd/cli/commands/clone/command_list.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,11 @@ func CommandList() []*cli.Command {
6868
Name: "branch",
6969
Usage: "branch name (optional)",
7070
},
71-
&cli.BoolFlag{
71+
&cli.StringFlag{
7272
Name: "protected",
73-
Usage: "mark instance as protected from deletion",
73+
Usage: "enable deletion protection; optionally specify duration in minutes (e.g., --protected=1440 for 1 day, 0 for forever)",
7474
Aliases: []string{"p"},
7575
},
76-
&cli.UintFlag{
77-
Name: "protection-duration",
78-
Usage: "protection duration in minutes (0 = forever, requires --protected)",
79-
},
8076
&cli.BoolFlag{
8177
Name: "async",
8278
Usage: "run the command asynchronously",
@@ -95,15 +91,11 @@ func CommandList() []*cli.Command {
9591
Before: checkCloneIDBefore,
9692
Action: update,
9793
Flags: []cli.Flag{
98-
&cli.BoolFlag{
94+
&cli.StringFlag{
9995
Name: "protected",
100-
Usage: "mark instance as protected from deletion",
96+
Usage: "enable deletion protection; optionally specify duration in minutes (e.g., --protected=1440 for 1 day, 0 for forever, false to disable)",
10197
Aliases: []string{"p"},
10298
},
103-
&cli.UintFlag{
104-
Name: "protection-duration",
105-
Usage: "protection duration in minutes (0 = forever)",
106-
},
10799
},
108100
},
109101
{

engine/internal/cloning/base.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ import (
3434
)
3535

3636
const (
37-
idleCheckDuration = 5 * time.Minute
37+
idleCheckDuration = 5 * time.Minute
38+
defaultWarningMinutes uint = 24 * 60 // 24 hours
3839
)
3940

4041
// Config contains a cloning configuration.
@@ -920,7 +921,7 @@ func (c *Base) runProtectionLeaseCheck(ctx context.Context) {
920921
func (c *Base) checkProtectionLeases(ctx context.Context) {
921922
warningMinutes := c.config.ProtectionExpiryWarningMinutes
922923
if warningMinutes == 0 {
923-
warningMinutes = 24 * 60
924+
warningMinutes = defaultWarningMinutes
924925
}
925926

926927
warningDuration := time.Duration(warningMinutes) * time.Minute

0 commit comments

Comments
 (0)