Skip to content

Commit

Permalink
client: allow extensibility
Browse files Browse the repository at this point in the history
  • Loading branch information
anpep committed Jul 27, 2023
1 parent 2e66374 commit 7f49900
Show file tree
Hide file tree
Showing 31 changed files with 96 additions and 83 deletions.
8 changes: 4 additions & 4 deletions client/changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ type changeAndData struct {
// Change fetches information about a Change given its ID.
func (client *Client) Change(id string) (*Change, error) {
var chgd changeAndData
_, err := client.doSync("GET", "/v1/changes/"+id, nil, nil, nil, &chgd)
_, err := client.DoSync("GET", "/v1/changes/"+id, nil, nil, nil, &chgd)
if err != nil {
return nil, err
}
Expand All @@ -111,7 +111,7 @@ func (client *Client) Abort(id string) (*Change, error) {
}

var chg Change
if _, err := client.doSync("POST", "/v1/changes/"+id, nil, nil, &body, &chg); err != nil {
if _, err := client.DoSync("POST", "/v1/changes/"+id, nil, nil, &body, &chg); err != nil {
return nil, err
}

Expand Down Expand Up @@ -158,7 +158,7 @@ func (client *Client) Changes(opts *ChangesOptions) ([]*Change, error) {
}

var chgds []changeAndData
_, err := client.doSync("GET", "/v1/changes", query, nil, nil, &chgds)
_, err := client.DoSync("GET", "/v1/changes", query, nil, nil, &chgds)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -190,7 +190,7 @@ func (client *Client) WaitChange(id string, opts *WaitChangeOptions) (*Change, e
query.Set("timeout", opts.Timeout.String())
}

_, err := client.doSync("GET", "/v1/changes/"+id+"/wait", query, nil, nil, &chgd)
_, err := client.DoSync("GET", "/v1/changes/"+id+"/wait", query, nil, nil, &chgd)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion client/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (client *Client) Checks(opts *ChecksOptions) ([]*CheckInfo, error) {
query["names"] = opts.Names
}
var checks []*CheckInfo
_, err := client.doSync("GET", "/v1/checks", query, nil, nil, &checks)
_, err := client.DoSync("GET", "/v1/checks", query, nil, nil, &checks)
if err != nil {
return nil, err
}
Expand Down
19 changes: 14 additions & 5 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ type doer interface {
Do(*http.Request) (*http.Response, error)
}

type ClientGetter interface {
// GetClient obtains a Pebble Client struct.
Client() *Client
}

// Config allows the user to customize client behavior.
type Config struct {
// BaseURL contains the base URL where the Pebble daemon is expected to be.
Expand Down Expand Up @@ -118,6 +123,10 @@ type Client struct {
getWebsocket getWebsocketFunc
}

func (c *Client) Client() *Client {
return c
}

type getWebsocketFunc func(url string) (clientWebsocket, error)

type clientWebsocket interface {
Expand Down Expand Up @@ -326,11 +335,11 @@ func decodeInto(reader io.Reader, v interface{}) error {
return nil
}

// doSync performs a request to the given path using the specified HTTP method.
// DoSync performs a request to the given path using the specified HTTP method.
// It expects a "sync" response from the API and on success decodes the JSON
// response payload into the given value using the "UseNumber" json decoding
// which produces json.Numbers instead of float64 types for numbers.
func (client *Client) doSync(method, path string, query url.Values, headers map[string]string, body io.Reader, v interface{}) (*ResultInfo, error) {
func (client *Client) DoSync(method, path string, query url.Values, headers map[string]string, body io.Reader, v interface{}) (*ResultInfo, error) {
var rsp response
if err := client.do(method, path, query, headers, body, &rsp); err != nil {
return nil, err
Expand Down Expand Up @@ -476,7 +485,7 @@ type SysInfo struct {
func (client *Client) SysInfo() (*SysInfo, error) {
var sysInfo SysInfo

if _, err := client.doSync("GET", "/v1/system-info", nil, nil, nil, &sysInfo); err != nil {
if _, err := client.DoSync("GET", "/v1/system-info", nil, nil, nil, &sysInfo); err != nil {
return nil, fmt.Errorf("cannot obtain system details: %w", err)
}

Expand All @@ -498,7 +507,7 @@ func (client *Client) DebugPost(action string, params interface{}, result interf
return err
}

_, err = client.doSync("POST", "/v1/debug", nil, nil, bytes.NewReader(body), result)
_, err = client.DoSync("POST", "/v1/debug", nil, nil, bytes.NewReader(body), result)
return err
}

Expand All @@ -508,6 +517,6 @@ func (client *Client) DebugGet(action string, result interface{}, params map[str
for k, v := range params {
urlParams.Set(k, v)
}
_, err := client.doSync("GET", "/v1/debug", urlParams, nil, nil, &result)
_, err := client.DoSync("GET", "/v1/debug", urlParams, nil, nil, &result)
return err
}
6 changes: 3 additions & 3 deletions client/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (client *Client) ListFiles(opts *ListFilesOptions) ([]*FileInfo, error) {
}

var results []fileInfoResult
_, err := client.doSync("GET", "/v1/files", q, nil, nil, &results)
_, err := client.DoSync("GET", "/v1/files", q, nil, nil, &results)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -280,7 +280,7 @@ func (client *Client) MakeDir(opts *MakeDirOptions) error {
headers := map[string]string{
"Content-Type": "application/json",
}
if _, err := client.doSync("POST", "/v1/files", nil, headers, &body, &result); err != nil {
if _, err := client.DoSync("POST", "/v1/files", nil, headers, &body, &result); err != nil {
return err
}

Expand Down Expand Up @@ -347,7 +347,7 @@ func (client *Client) RemovePath(opts *RemovePathOptions) error {
headers := map[string]string{
"Content-Type": "application/json",
}
if _, err := client.doSync("POST", "/v1/files", nil, headers, &body, &result); err != nil {
if _, err := client.DoSync("POST", "/v1/files", nil, headers, &body, &result); err != nil {
return err
}

Expand Down
4 changes: 2 additions & 2 deletions client/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (client *Client) AddLayer(opts *AddLayerOptions) error {
if err := json.NewEncoder(&body).Encode(&payload); err != nil {
return err
}
_, err := client.doSync("POST", "/v1/layers", nil, nil, &body, nil)
_, err := client.DoSync("POST", "/v1/layers", nil, nil, &body, nil)
return err
}

Expand All @@ -64,7 +64,7 @@ func (client *Client) PlanBytes(_ *PlanOptions) (data []byte, err error) {
"format": []string{"yaml"},
}
var dataStr string
_, err = client.doSync("GET", "/v1/plan", query, nil, nil, &dataStr)
_, err = client.DoSync("GET", "/v1/plan", query, nil, nil, &dataStr)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion client/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (client *Client) Services(opts *ServicesOptions) ([]*ServiceInfo, error) {
"names": []string{strings.Join(opts.Names, ",")},
}
var services []*ServiceInfo
_, err := client.doSync("GET", "/v1/services", query, nil, nil, &services)
_, err := client.DoSync("GET", "/v1/services", query, nil, nil, &services)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion client/signals.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (client *Client) SendSignal(opts *SendSignalOptions) error {
if err != nil {
return fmt.Errorf("cannot encode JSON payload: %w", err)
}
_, err = client.doSync("POST", "/v1/signals", nil, nil, &body, nil)
_, err = client.DoSync("POST", "/v1/signals", nil, nil, &body, nil)
return err
}

Expand Down
4 changes: 2 additions & 2 deletions client/warnings.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (client *Client) Warnings(opts WarningsOptions) ([]*Warning, error) {
if opts.All {
q.Add("select", "all")
}
_, err := client.doSync("GET", "/v1/warnings", q, nil, nil, &jws)
_, err := client.DoSync("GET", "/v1/warnings", q, nil, nil, &jws)

ws := make([]*Warning, len(jws))
for i, jw := range jws {
Expand All @@ -77,6 +77,6 @@ func (client *Client) Okay(t time.Time) error {
if err := json.NewEncoder(&body).Encode(op); err != nil {
return err
}
_, err := client.doSync("POST", "/v1/warnings", nil, nil, &body, nil)
_, err := client.DoSync("POST", "/v1/warnings", nil, nil, &body, nil)
return err
}
40 changes: 22 additions & 18 deletions internals/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,15 @@ func fixupArg(optName string) string {
}

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

type clientMixin struct {
client *client.Client
type ClientMixin struct {
client.ClientGetter
}

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

type parserSetter interface {
Expand All @@ -163,11 +163,11 @@ type defaultOptions struct {
// Parser creates and populates a fresh parser.
// Since commands have local state a fresh parser is required to isolate tests
// from each other.
func Parser(cli *client.Client) *flags.Parser {
func Parser(cg client.ClientGetter) *flags.Parser {
// Implement --version by default on every command
defaultOpts := defaultOptions{
Version: func() {
printVersions(cli)
printVersions(cg.Client())
panic(&exitStatus{0})
},
}
Expand Down Expand Up @@ -195,7 +195,7 @@ func Parser(cli *client.Client) *flags.Parser {
for _, c := range commands {
obj := c.Builder()
if x, ok := obj.(clientSetter); ok {
x.setClient(cli)
x.setClient(cg)
}
if x, ok := obj.(parserSetter); ok {
x.setParser(parser)
Expand Down Expand Up @@ -276,7 +276,7 @@ func (e *exitStatus) Error() string {
return fmt.Sprintf("internal error: exitStatus{%d} being handled as normal error", e.code)
}

func Run() error {
func RunWithClient(cg client.ClientGetter) error {
defer func() {
if v := recover(); v != nil {
if e, ok := v.(*exitStatus); ok {
Expand All @@ -288,14 +288,7 @@ func Run() error {

logger.SetLogger(logger.New(os.Stderr, "[pebble] "))

_, clientConfig.Socket = getEnvPaths()

cli, err := client.New(&clientConfig)
if err != nil {
return fmt.Errorf("cannot create client: %v", err)
}

parser := Parser(cli)
parser := Parser(cg)
xtra, err := parser.Parse()
if err != nil {
if e, ok := err.(*flags.Error); ok {
Expand Down Expand Up @@ -328,8 +321,19 @@ func Run() error {
return nil
}

maybePresentWarnings(cli.WarningsSummary())
return nil
}

func Run() error {
_, clientConfig.Socket = getEnvPaths()
cli, err := client.New(&clientConfig)
if err != nil {
return fmt.Errorf("cannot create client: %v", err)
}
if err := RunWithClient(cli); err != nil {
return err
}
maybePresentWarnings(cli.WarningsSummary())
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions internals/cli/cmd_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ label (or append if the label is not found).
`

type cmdAdd struct {
clientMixin
ClientMixin
Combine bool `long:"combine"`
Positional struct {
Label string `positional-arg-name:"<label>" required:"1"`
Expand Down Expand Up @@ -64,7 +64,7 @@ func (cmd *cmdAdd) Execute(args []string) error {
Label: cmd.Positional.Label,
LayerData: data,
}
err = cmd.client.AddLayer(&opts)
err = cmd.Client().AddLayer(&opts)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internals/cli/cmd_autostart.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (cmd cmdAutoStart) Execute(args []string) error {
}

servopts := client.ServiceOptions{}
changeID, err := cmd.client.AutoStart(&servopts)
changeID, err := cmd.Client().AutoStart(&servopts)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions internals/cli/cmd_changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The changes command displays a summary of system changes performed recently.
`

type cmdChanges struct {
clientMixin
ClientMixin
timeMixin
Positional struct {
Service string `positional-arg-name:"<service>"`
Expand Down Expand Up @@ -103,7 +103,7 @@ func (c *cmdChanges) Execute(args []string) error {
Selector: client.ChangesAll,
}

changes, err := queryChanges(c.client, &opts)
changes, err := queryChanges(c.Client(), &opts)
if err != nil {
return err
}
Expand Down Expand Up @@ -156,7 +156,7 @@ func queryChange(cli *client.Client, chid string) (*client.Change, error) {
}

func (c *cmdTasks) showChange(chid string) error {
chg, err := queryChange(c.client, chid)
chg, err := queryChange(c.Client(), chid)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions internals/cli/cmd_checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ arguments.
`

type cmdChecks struct {
clientMixin
ClientMixin
Level string `long:"level"`
Positional struct {
Checks []string `positional-arg-name:"<check>"`
Expand Down Expand Up @@ -57,7 +57,7 @@ func (cmd *cmdChecks) Execute(args []string) error {
Level: client.CheckLevel(cmd.Level),
Names: cmd.Positional.Checks,
}
checks, err := cmd.client.Checks(&opts)
checks, err := cmd.Client().Checks(&opts)
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions internals/cli/cmd_enter.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ These subcommands are currently supported:
`

type cmdEnter struct {
clientMixin
ClientMixin
sharedRunEnterOpts
Run bool `long:"run"`
Positional struct {
Expand Down Expand Up @@ -105,7 +105,7 @@ func (cmd *cmdEnter) Execute(args []string) error {
runCmd := cmdRun{
sharedRunEnterOpts: cmd.sharedRunEnterOpts,
}
runCmd.setClient(cmd.client)
runCmd.setClient(cmd.Client())

if len(cmd.Positional.Cmd) == 0 {
runCmd.run(nil)
Expand All @@ -119,7 +119,7 @@ func (cmd *cmdEnter) Execute(args []string) error {
extraArgs []string
)

parser := Parser(cmd.client)
parser := Parser(cmd.Client())
parser.CommandHandler = func(c flags.Commander, a []string) error {
commander = c
extraArgs = a
Expand Down
4 changes: 2 additions & 2 deletions internals/cli/cmd_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pebble exec --timeout 10s -- echo -n foo bar
`

type cmdExec struct {
clientMixin
ClientMixin
WorkingDir string `short:"w"`
Env []string `long:"env"`
UserID *int `long:"uid"`
Expand Down Expand Up @@ -180,7 +180,7 @@ func (cmd *cmdExec) Execute(args []string) error {
}

// Start the command.
process, err := cmd.client.Exec(opts)
process, err := cmd.Client().Exec(opts)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 7f49900

Please sign in to comment.