Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): enable extended client access #285

Merged
merged 8 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 11 additions & 26 deletions internals/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ const defaultPebbleDir = "/var/lib/pebble/default"
// ErrExtraArgs is returned if extra arguments to a command are found
var ErrExtraArgs = fmt.Errorf("too many arguments for command")

// CmdOptions contains state that's required during each command execution.
anpep marked this conversation as resolved.
Show resolved Hide resolved
type CmdOptions struct {
// Client is the Pebble client instance
Client *client.Client
// Parser is the instance of the flags.Parser that processed the command.
anpep marked this conversation as resolved.
Show resolved Hide resolved
Parser *flags.Parser
}

// CmdInfo holds information needed by the CLI to execute commands and
// populate entries in the help manual.
type CmdInfo struct {
Expand All @@ -67,9 +75,8 @@ type CmdInfo struct {
// command, and in the Pebble man page.
Description string

// Builder is a function that creates a new instance of the command
// struct containing an Execute(args []string) implementation.
Builder func() flags.Commander
// New is a function that creates a new instance of the command.
New func(*CmdOptions) flags.Commander
flotter marked this conversation as resolved.
Show resolved Hide resolved

// ArgsHelp (optional) contains help about the command-line arguments
// (including options) supported by the command.
Expand Down Expand Up @@ -139,22 +146,6 @@ func fixupArg(optName string) string {
return optName
}

type clientSetter interface {
setClient(*client.Client)
}

type clientMixin struct {
client *client.Client
}

func (ch *clientMixin) setClient(cli *client.Client) {
ch.client = cli
}

type parserSetter interface {
setParser(*flags.Parser)
}

type defaultOptions struct {
Version func() `long:"version" hidden:"yes" description:"Print the version and exit"`
}
Expand Down Expand Up @@ -192,13 +183,7 @@ func Parser(cli *client.Client) *flags.Parser {

// Add all commands
for _, c := range commands {
obj := c.Builder()
if x, ok := obj.(clientSetter); ok {
x.setClient(cli)
}
if x, ok := obj.(parserSetter); ok {
x.setParser(parser)
}
obj := c.New(&CmdOptions{Client: cli, Parser: parser})
anpep marked this conversation as resolved.
Show resolved Hide resolved

var target *flags.Command
if c.Debug {
Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ label (or append if the label is not found).
`

type cmdAdd struct {
clientMixin
Combine bool `long:"combine"`
Positional struct {
Label string `positional-arg-name:"<label>" required:"1"`
LayerPath string `positional-arg-name:"<layer-path>" required:"1"`
} `positional-args:"yes"`

client *client.Client
flotter marked this conversation as resolved.
Show resolved Hide resolved
}

func init() {
Expand All @@ -48,7 +49,9 @@ func init() {
ArgsHelp: map[string]string{
"--combine": "Combine the new layer with an existing layer that has the given label (default is to append)",
},
Builder: func() flags.Commander { return &cmdAdd{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdAdd{client: opts.Client}
},
})
}

Expand Down
6 changes: 5 additions & 1 deletion internals/cli/cmd_autostart.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ func init() {
Summary: cmdAutoStartSummary,
Description: cmdAutoStartDescription,
ArgsHelp: waitArgsHelp,
Builder: func() flags.Commander { return &cmdAutoStart{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdAutoStart{
waitMixin: waitMixin{client: opts.Client},
}
},
})
}

Expand Down
13 changes: 10 additions & 3 deletions internals/cli/cmd_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ The changes command displays a summary of system changes performed recently.
`

type cmdChanges struct {
clientMixin
timeMixin
Positional struct {
Service string `positional-arg-name:"<service>"`
} `positional-args:"yes"`

client *client.Client
}

const cmdTasksSummary = "List a change's tasks"
Expand All @@ -54,14 +55,20 @@ func init() {
Summary: cmdChangesSummary,
Description: cmdChangesDescription,
ArgsHelp: timeArgsHelp,
Builder: func() flags.Commander { return &cmdChanges{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdChanges{client: opts.Client}
},
})
AddCommand(&CmdInfo{
Name: "tasks",
Summary: cmdTasksSummary,
Description: cmdTasksDescription,
ArgsHelp: merge(changeIDMixinArgsHelp, timeArgsHelp),
Builder: func() flags.Commander { return &cmdTasks{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdTasks{
changeIDMixin: changeIDMixin{client: opts.Client},
}
},
})
}

Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ arguments.
`

type cmdChecks struct {
clientMixin
Level string `long:"level"`
Positional struct {
Checks []string `positional-arg-name:"<check>"`
} `positional-args:"yes"`

client *client.Client
}

func init() {
Expand All @@ -45,7 +46,9 @@ func init() {
ArgsHelp: map[string]string{
"--level": `Check level to filter for ("alive" or "ready")`,
},
Builder: func() flags.Commander { return &cmdChecks{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdChecks{client: opts.Client}
},
})
}

Expand Down
14 changes: 7 additions & 7 deletions internals/cli/cmd_enter.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/canonical/go-flags"

"github.com/canonical/pebble/client"
"github.com/canonical/pebble/internals/logger"
)

Expand Down Expand Up @@ -46,12 +47,13 @@ These subcommands are currently supported:
`

type cmdEnter struct {
clientMixin
sharedRunEnterOpts
Run bool `long:"run"`
Positional struct {
Cmd []string `positional-arg-name:"<subcommand>"`
} `positional-args:"yes"`

client *client.Client
parser *flags.Parser
}

Expand All @@ -60,7 +62,9 @@ func init() {
Name: "enter",
Summary: cmdEnterSummary,
Description: cmdEnterDescription,
Builder: func() flags.Commander { return &cmdEnter{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdEnter{client: opts.Client, parser: opts.Parser}
},
ArgsHelp: merge(sharedRunEnterArgsHelp, map[string]string{
"--run": "Start default services before executing subcommand",
}),
Expand Down Expand Up @@ -104,8 +108,8 @@ func (cmd *cmdEnter) Execute(args []string) error {

runCmd := cmdRun{
sharedRunEnterOpts: cmd.sharedRunEnterOpts,
client: cmd.client,
}
runCmd.setClient(cmd.client)

if len(cmd.Positional.Cmd) == 0 {
runCmd.run(nil)
Expand Down Expand Up @@ -195,7 +199,3 @@ func (cmd *cmdEnter) Execute(args []string) error {

return err
}

func (cmd *cmdEnter) setParser(parser *flags.Parser) {
cmd.parser = parser
}
7 changes: 5 additions & 2 deletions internals/cli/cmd_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ pebble exec --timeout 10s -- echo -n foo bar
`

type cmdExec struct {
clientMixin
WorkingDir string `short:"w"`
Env []string `long:"env"`
UserID *int `long:"uid"`
Expand All @@ -59,6 +58,8 @@ type cmdExec struct {
Positional struct {
Command string `positional-arg-name:"<command>" required:"1"`
} `positional-args:"yes"`

client *client.Client
}

func init() {
Expand All @@ -81,7 +82,9 @@ func init() {
"-I": "Disable interactive mode and use a pipe for stdin",
},
PassAfterNonOption: true,
Builder: func() flags.Commander { return &cmdExec{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdExec{client: opts.Client}
},
})
}

Expand Down
4 changes: 3 additions & 1 deletion internals/cli/cmd_help.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ func init() {
"--all": "Show a short summary of all commands",
"--man": "Generate the manpage",
},
Builder: func() flags.Commander { return &cmdHelp{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdHelp{parser: opts.Parser}
},
})
}

Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ if none are specified) and displays them in chronological order.
`

type cmdLogs struct {
clientMixin
Follow bool `short:"f" long:"follow"`
Format string `long:"format"`
N string `short:"n"`
Positional struct {
Services []string `positional-arg-name:"<service>"`
} `positional-args:"yes"`

client *client.Client
}

func init() {
Expand All @@ -53,7 +54,9 @@ func init() {
"--format": "Output format: \"text\" (default) or \"json\" (JSON lines).",
"-n": "Number of logs to show (before following); defaults to 30.\nIf 'all', show all buffered logs.",
},
Builder: func() flags.Commander { return &cmdLogs{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdLogs{client: opts.Client}
},
})
}

Expand Down
7 changes: 5 additions & 2 deletions internals/cli/cmd_ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ may be specified for the last path element.
`

type cmdLs struct {
clientMixin
timeMixin

Directory bool `short:"d"`
Expand All @@ -42,6 +41,8 @@ type cmdLs struct {
Positional struct {
Path string `positional-arg-name:"<path>"`
} `positional-args:"yes" required:"yes"`

client *client.Client
}

func init() {
Expand All @@ -53,7 +54,9 @@ func init() {
"-d": "List matching entries themselves, not directory contents",
"-l": "Use a long listing format",
}),
Builder: func() flags.Commander { return &cmdLs{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdLs{client: opts.Client}
},
})
}

Expand Down
8 changes: 5 additions & 3 deletions internals/cli/cmd_mkdir.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ The mkdir command creates the specified directory.
`

type cmdMkdir struct {
clientMixin

MakeParents bool `short:"p"`
Permissions string `short:"m"`
UserID *int `long:"uid"`
Expand All @@ -42,14 +40,15 @@ type cmdMkdir struct {
Positional struct {
Path string `positional-arg-name:"<path>"`
} `positional-args:"yes" required:"yes"`

client *client.Client
}

func init() {
AddCommand(&CmdInfo{
Name: "mkdir",
Summary: cmdMkdirSummary,
Description: cmdMkdirDescription,
Builder: func() flags.Commander { return &cmdMkdir{} },
ArgsHelp: map[string]string{
"-p": "Create parent directories as needed",
"-m": "Set permissions (e.g. 0644)",
Expand All @@ -58,6 +57,9 @@ func init() {
"--gid": "Use specified group ID",
"--group": "Use specified group name",
},
New: func(opts *CmdOptions) flags.Commander {
return &cmdMkdir{client: opts.Client}
},
})
}

Expand Down
6 changes: 4 additions & 2 deletions internals/cli/cmd_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,17 @@ format. Layers are combined according to the override rules defined in them.
`

type cmdPlan struct {
clientMixin
client *client.Client
}

func init() {
AddCommand(&CmdInfo{
Name: "plan",
Summary: cmdPlanSummary,
Description: cmdPlanDescription,
Builder: func() flags.Commander { return &cmdPlan{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdPlan{client: opts.Client}
},
})
}

Expand Down
6 changes: 5 additions & 1 deletion internals/cli/cmd_replan.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ func init() {
Summary: cmdReplanSummary,
Description: cmdReplanDescription,
ArgsHelp: waitArgsHelp,
Builder: func() flags.Commander { return &cmdReplan{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdReplan{
waitMixin: waitMixin{client: opts.Client},
}
},
})
}

Expand Down
6 changes: 5 additions & 1 deletion internals/cli/cmd_restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ func init() {
Summary: cmdRestartSummary,
Description: cmdRestartDescription,
ArgsHelp: waitArgsHelp,
Builder: func() flags.Commander { return &cmdRestart{} },
New: func(opts *CmdOptions) flags.Commander {
return &cmdRestart{
waitMixin: waitMixin{client: opts.Client},
}
},
})
}

Expand Down
Loading
Loading