From 0f0b4fd3c2fc448bdc46169dbb9656c32bb53ebb Mon Sep 17 00:00:00 2001 From: Jhon Honce Date: Wed, 19 Feb 2020 17:38:43 -0700 Subject: Add support for ssh:// and unix:// podman clients * Make context keys package safe * Add support for PODMAN_HOST and PODMAN_SSHKEY * Add slight increasing delay when client connections fail * Remove usages of path.Join(), added JoinURL(). '/' is not OS dependent. Signed-off-by: Jhon Honce --- cmd/cli/main.go | 113 ---------------- go.sum | 1 + pkg/bindings/connection.go | 234 +++++++++++++++++++++++++-------- pkg/bindings/containers/containers.go | 24 ++-- pkg/bindings/containers/create.go | 2 +- pkg/bindings/containers/healthcheck.go | 2 +- pkg/bindings/containers/mount.go | 6 +- pkg/bindings/images/images.go | 18 +-- pkg/bindings/images/search.go | 2 +- pkg/bindings/network/network.go | 6 +- pkg/bindings/pods/pods.go | 22 ++-- pkg/bindings/test/common_test.go | 2 +- pkg/bindings/test/images_test.go | 2 +- pkg/bindings/volumes/volumes.go | 8 +- 14 files changed, 230 insertions(+), 212 deletions(-) delete mode 100644 cmd/cli/main.go diff --git a/cmd/cli/main.go b/cmd/cli/main.go deleted file mode 100644 index 4eec05ef2..000000000 --- a/cmd/cli/main.go +++ /dev/null @@ -1,113 +0,0 @@ -package main - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net" - "net/http" - "net/url" - "os" - - "golang.org/x/crypto/ssh" -) - -// remote PODMAN_HOST=ssh://@[:port]/run/podman/podman.sock -// local PODMAN_HOST=unix://run/podman/podman.sock - -var ( - DefaultURL = "unix://root@localhost/run/podman/podman.sock" -) - -func main() { - connectionURL := DefaultURL - if value, found := os.LookupEnv("PODMAN_HOST"); found { - connectionURL = value - } - - _url, err := url.Parse(connectionURL) - if err != nil { - die("Value of PODMAN_HOST is not a valid url: %s\n", connectionURL) - } - - if _url.Scheme != "ssh" && _url.Scheme != "unix" { - die("Scheme from PODMAN_HOST is not supported: %s\n", _url.Scheme) - } - - // Now we setup the http client to use the connection above - client := &http.Client{} - if _url.Scheme == "ssh" { - var auth ssh.AuthMethod - if value, found := os.LookupEnv("PODMAN_SSHKEY"); found { - auth, err = publicKey(value) - if err != nil { - die("Failed to parse %s: %v\n", value, err) - } - } else { - die("PODMAN_SSHKEY was not defined\n") - } - - // Connect to sshd - bastion, err := ssh.Dial("tcp", - net.JoinHostPort(_url.Hostname(), _url.Port()), - &ssh.ClientConfig{ - User: _url.User.Username(), - Auth: []ssh.AuthMethod{auth}, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), - }, - ) - if err != nil { - die("Failed to build ssh tunnel") - } - defer bastion.Close() - - client.Transport = &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - // Now we make the connection to the unix domain socket on the server using the ssh tunnel - return bastion.Dial("unix", _url.Path) - }, - } - } else { - client.Transport = &http.Transport{ - DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { - d := net.Dialer{} - return d.DialContext(ctx, "unix", _url.Path) - }, - DisableCompression: true, - } - } - - resp, err := client.Get("http://localhost/v1.24/images/json") - if err != nil { - die(err.Error()) - } - defer resp.Body.Close() - body, _ := ioutil.ReadAll(resp.Body) - - var output bytes.Buffer - _ = json.Indent(&output, body, "", " ") - fmt.Printf("%s\n", output.String()) - os.Exit(0) -} - -func die(format string, a ...interface{}) { - fmt.Fprintf(os.Stderr, format, a...) - fmt.Fprintf(os.Stderr, "\n") - os.Exit(1) -} - -func publicKey(path string) (ssh.AuthMethod, error) { - key, err := ioutil.ReadFile(path) - if err != nil { - return nil, err - } - - signer, err := ssh.ParsePrivateKey(key) - if err != nil { - return nil, err - } - - return ssh.PublicKeys(signer), nil -} diff --git a/go.sum b/go.sum index 4fc380adf..a1cf437a8 100644 --- a/go.sum +++ b/go.sum @@ -638,6 +638,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72 h1:bw9doJza/SFBEweII/rHQh338oozWyiFsBRHtrflcws= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index f270060a6..75f1fc6a5 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -1,22 +1,34 @@ package bindings import ( + "bufio" "context" "fmt" "io" + "io/ioutil" "net" "net/http" "net/url" + "os" "path/filepath" + "strconv" "strings" + "time" "github.com/containers/libpod/pkg/api/handlers" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "golang.org/x/crypto/ssh" + "k8s.io/client-go/util/homedir" ) var ( - defaultConnectionPath string = filepath.Join(fmt.Sprintf("v%s", handlers.MinimalApiVersion), "libpod") + basePath = &url.URL{ + Scheme: "http", + Host: "d", + Path: "/v" + handlers.MinimalApiVersion + "/libpod", + } ) type APIResponse struct { @@ -25,9 +37,28 @@ type APIResponse struct { } type Connection struct { - scheme string - address string - client *http.Client + _url *url.URL + client *http.Client +} + +type valueKey string + +const ( + clientKey = valueKey("client") +) + +// GetClient from context build by NewConnection() +func GetClient(ctx context.Context) (*Connection, error) { + c, ok := ctx.Value(clientKey).(*Connection) + if !ok { + return nil, errors.Errorf("ClientKey not set in context") + } + return c, nil +} + +// JoinURL elements with '/' +func JoinURL(elements ...string) string { + return strings.Join(elements, "/") } // NewConnection takes a URI as a string and returns a context with the @@ -36,46 +67,81 @@ type Connection struct { // // A valid URI connection should be scheme:// // For example tcp://localhost: -// or unix://run/podman/podman.sock -func NewConnection(uri string) (context.Context, error) { - u, err := url.Parse(uri) - if err != nil { - return nil, err - } - // TODO once ssh is implemented, remove this block and - // add it to the conditional beneath it - if u.Scheme == "ssh" { - return nil, ErrNotImplemented +// or unix:///run/podman/podman.sock +// or ssh://@[:port]/run/podman/podman.sock?secure=True +func NewConnection(ctx context.Context, uri string, identity ...string) (context.Context, error) { + var ( + err error + secure bool + ) + if v, found := os.LookupEnv("PODMAN_HOST"); found { + uri = v } - if u.Scheme != "tcp" && u.Scheme != "unix" { - return nil, errors.Errorf("%s is not a support schema", u.Scheme) + + if v, found := os.LookupEnv("PODMAN_SSHKEY"); found { + identity = []string{v} } - if u.Scheme == "tcp" && !strings.HasPrefix(uri, "tcp://") { - return nil, errors.New("tcp URIs should begin with tcp://") + _url, err := url.Parse(uri) + if err != nil { + return nil, errors.Wrapf(err, "Value of PODMAN_HOST is not a valid url: %s", uri) } - address := u.Path - if u.Scheme == "tcp" { - address = u.Host + // Now we setup the http client to use the connection above + var client *http.Client + switch _url.Scheme { + case "ssh": + secure, err = strconv.ParseBool(_url.Query().Get("secure")) + if err != nil { + secure = false + } + client, err = sshClient(_url, identity[0], secure) + case "unix": + if !strings.HasPrefix(uri, "unix:///") { + // autofix unix://path_element vs unix:///path_element + _url.Path = JoinURL(_url.Host, _url.Path) + _url.Host = "" + } + client, err = unixClient(_url) + case "tcp": + if !strings.HasPrefix(uri, "tcp://") { + return nil, errors.New("tcp URIs should begin with tcp://") + } + client, err = tcpClient(_url) + default: + return nil, errors.Errorf("%s is not a support schema", _url.Scheme) + } + if err != nil { + return nil, errors.Wrapf(err, "Failed to create %sClient", _url.Scheme) } - newConn := newConnection(u.Scheme, address) - ctx := context.WithValue(context.Background(), "conn", &newConn) + + ctx = context.WithValue(ctx, clientKey, &Connection{_url, client}) if err := pingNewConnection(ctx); err != nil { return nil, err } return ctx, nil } +func tcpClient(_url *url.URL) (*http.Client, error) { + return &http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return net.Dial("tcp", _url.Path) + }, + DisableCompression: true, + }, + }, nil +} + // pingNewConnection pings to make sure the RESTFUL service is up // and running. it should only be used where initializing a connection func pingNewConnection(ctx context.Context) error { - conn, err := GetConnectionFromContext(ctx) + client, err := GetClient(ctx) if err != nil { return err } // the ping endpoint sits at / in this case - response, err := conn.DoRequest(nil, http.MethodGet, "../../../_ping", nil) + response, err := client.DoRequest(nil, http.MethodGet, "../../../_ping", nil) if err != nil { return err } @@ -85,26 +151,58 @@ func pingNewConnection(ctx context.Context) error { return errors.Errorf("ping response was %q", response.StatusCode) } -// newConnection takes a scheme and address and creates a connection from it -func newConnection(scheme, address string) Connection { - client := http.Client{ - Transport: &http.Transport{ - DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { - return net.Dial(scheme, address) +func sshClient(_url *url.URL, identity string, secure bool) (*http.Client, error) { + auth, err := publicKey(identity) + if err != nil { + return nil, errors.Wrapf(err, "Failed to parse identity %s: %v\n", _url.String(), identity) + } + + callback := ssh.InsecureIgnoreHostKey() + if secure { + key := hostKey(_url.Hostname()) + if key != nil { + callback = ssh.FixedHostKey(key) + } + } + + bastion, err := ssh.Dial("tcp", + net.JoinHostPort(_url.Hostname(), _url.Port()), + &ssh.ClientConfig{ + User: _url.User.Username(), + Auth: []ssh.AuthMethod{auth}, + HostKeyCallback: callback, + HostKeyAlgorithms: []string{ + ssh.KeyAlgoRSA, + ssh.KeyAlgoDSA, + ssh.KeyAlgoECDSA256, + ssh.KeyAlgoECDSA384, + ssh.KeyAlgoECDSA521, + ssh.KeyAlgoED25519, }, + Timeout: 5 * time.Second, }, + ) + if err != nil { + return nil, errors.Wrapf(err, "Connection to bastion host (%s) failed.", _url.String()) } - newConn := Connection{ - client: &client, - address: address, - scheme: scheme, - } - return newConn + return &http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return bastion.Dial("unix", _url.Path) + }, + }}, nil } -func (c *Connection) makeEndpoint(u string) string { - // The d character in the url is discarded and is meaningless - return fmt.Sprintf("http://d/%s%s", defaultConnectionPath, u) +func unixClient(_url *url.URL) (*http.Client, error) { + return &http.Client{ + Transport: &http.Transport{ + DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { + d := net.Dialer{} + return d.DialContext(ctx, "unix", _url.Path) + }, + DisableCompression: true, + }, + }, nil } // DoRequest assembles the http request and returns the response @@ -121,7 +219,7 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string, // Lets eventually use URL for this which might lead to safer // usage safeEndpoint := fmt.Sprintf(endpoint, safePathValues...) - e := c.makeEndpoint(safeEndpoint) + e := basePath.String() + safeEndpoint req, err := http.NewRequest(httpMethod, e, httpBody) if err != nil { return nil, err @@ -140,21 +238,11 @@ func (c *Connection) DoRequest(httpBody io.Reader, httpMethod, endpoint string, if err == nil { break } + time.Sleep(time.Duration(i*100) * time.Millisecond) } return &APIResponse{response, req}, err } -// GetConnectionFromContext returns a bindings connection from the context -// being passed into each method. -func GetConnectionFromContext(ctx context.Context) (*Connection, error) { - c := ctx.Value("conn") - if c == nil { - return nil, errors.New("unable to get connection from context") - } - conn := c.(*Connection) - return conn, nil -} - // FiltersToString converts our typical filter format of a // map[string][]string to a query/html safe string. func FiltersToString(filters map[string][]string) (string, error) { @@ -189,3 +277,45 @@ func (h *APIResponse) IsClientError() bool { func (h *APIResponse) IsServerError() bool { return h.Response.StatusCode/100 == 5 } + +func publicKey(path string) (ssh.AuthMethod, error) { + key, err := ioutil.ReadFile(path) + if err != nil { + return nil, err + } + + signer, err := ssh.ParsePrivateKey(key) + if err != nil { + return nil, err + } + + return ssh.PublicKeys(signer), nil +} + +func hostKey(host string) ssh.PublicKey { + // parse OpenSSH known_hosts file + // ssh or use ssh-keyscan to get initial key + known_hosts := filepath.Join(homedir.HomeDir(), ".ssh", "known_hosts") + fd, err := os.Open(known_hosts) + if err != nil { + logrus.Error(err) + return nil + } + + scanner := bufio.NewScanner(fd) + for scanner.Scan() { + _, hosts, key, _, _, err := ssh.ParseKnownHosts(scanner.Bytes()) + if err != nil { + logrus.Errorf("Failed to parse known_hosts: %s", scanner.Text()) + continue + } + + for _, h := range hosts { + if h == host { + return key + } + } + } + + return nil +} diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index 04f7f8802..a437e9a9b 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -16,7 +16,7 @@ import ( // size information should also be included. Finally, the sync bool synchronizes the OCI runtime and // container state. func List(ctx context.Context, filters map[string][]string, all *bool, last *int, pod, size, sync *bool) ([]lpapiv2.ListContainer, error) { // nolint:typecheck - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -59,7 +59,7 @@ func Prune(ctx context.Context, filters map[string][]string) ([]string, error) { var ( pruneResponse []string ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func Prune(ctx context.Context, filters map[string][]string) ([]string, error) { // that the container should be removed forcibly (example, even it is running). The volumes // bool dictates that a container's volumes should also be removed. func Remove(ctx context.Context, nameOrID string, force, volumes *bool) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -105,7 +105,7 @@ func Remove(ctx context.Context, nameOrID string, force, volumes *bool) error { // should be calculated. Calculating the size of a container requires extra work from the filesystem and // is therefore slower. func Inspect(ctx context.Context, nameOrID string, size *bool) (*libpod.InspectContainerData, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -125,7 +125,7 @@ func Inspect(ctx context.Context, nameOrID string, size *bool) (*libpod.InspectC // representation of a signal like 'SIGKILL'. The nameOrID can be a container name // or a partial/full ID func Kill(ctx context.Context, nameOrID string, signal string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -143,7 +143,7 @@ func Logs() {} // Pause pauses a given container. The nameOrID can be a container name // or a partial/full ID. func Pause(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -158,7 +158,7 @@ func Pause(ctx context.Context, nameOrID string) error { // or a partial/full ID. The optional timeout specifies the number of seconds to wait // for the running container to stop before killing it. func Restart(ctx context.Context, nameOrID string, timeout *int) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -177,7 +177,7 @@ func Restart(ctx context.Context, nameOrID string, timeout *int) error { // or a partial/full ID. The optional parameter for detach keys are to override the default // detach key sequence. func Start(ctx context.Context, nameOrID string, detachKeys *string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -198,7 +198,7 @@ func Top() {} // Unpause resumes the given paused container. The nameOrID can be a container name // or a partial/full ID. func Unpause(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -213,7 +213,7 @@ func Unpause(ctx context.Context, nameOrID string) error { // or a partial/full ID. func Wait(ctx context.Context, nameOrID string) (int32, error) { var exitCode int32 - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return exitCode, err } @@ -228,7 +228,7 @@ func Wait(ctx context.Context, nameOrID string) (int32, error) { // exists in local storage. The nameOrID can be a container name // or a partial/full ID. func Exists(ctx context.Context, nameOrID string) (bool, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return false, err } @@ -243,7 +243,7 @@ func Exists(ctx context.Context, nameOrID string) (bool, error) { // or a partial/full ID func Stop(ctx context.Context, nameOrID string, timeout *int) error { params := make(map[string]string) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } diff --git a/pkg/bindings/containers/create.go b/pkg/bindings/containers/create.go index 18b32335b..2943cb522 100644 --- a/pkg/bindings/containers/create.go +++ b/pkg/bindings/containers/create.go @@ -13,7 +13,7 @@ import ( func CreateWithSpec(ctx context.Context, s specgen.SpecGenerator) (utils.ContainerCreateResponse, error) { var ccr utils.ContainerCreateResponse - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return ccr, err } diff --git a/pkg/bindings/containers/healthcheck.go b/pkg/bindings/containers/healthcheck.go index 9ed7f858d..dc607c1b3 100644 --- a/pkg/bindings/containers/healthcheck.go +++ b/pkg/bindings/containers/healthcheck.go @@ -11,7 +11,7 @@ import ( // RunHealthCheck executes the container's healthcheck and returns the health status of the // container. func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckStatus, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } diff --git a/pkg/bindings/containers/mount.go b/pkg/bindings/containers/mount.go index d68dee981..e0627d9a3 100644 --- a/pkg/bindings/containers/mount.go +++ b/pkg/bindings/containers/mount.go @@ -10,7 +10,7 @@ import ( // Mount mounts an existing container to the filesystem. It returns the path // of the mounted container in string format. func Mount(ctx context.Context, nameOrID string) (string, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return "", err } @@ -27,7 +27,7 @@ func Mount(ctx context.Context, nameOrID string) (string, error) { // Unmount unmounts a container from the filesystem. The container must not be running // or the unmount will fail. func Unmount(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -40,7 +40,7 @@ func Unmount(ctx context.Context, nameOrID string) error { // GetMountedContainerPaths returns a map of mounted containers and their mount locations. func GetMountedContainerPaths(ctx context.Context) (map[string]string, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go index b19482943..271d58952 100644 --- a/pkg/bindings/images/images.go +++ b/pkg/bindings/images/images.go @@ -14,7 +14,7 @@ import ( // Exists a lightweight way to determine if an image exists in local storage. It returns a // boolean response. func Exists(ctx context.Context, nameOrID string) (bool, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return false, err } @@ -29,7 +29,7 @@ func Exists(ctx context.Context, nameOrID string) (bool, error) { // ways to alter the image query. func List(ctx context.Context, all *bool, filters map[string][]string) ([]*handlers.ImageSummary, error) { var imageSummary []*handlers.ImageSummary - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -54,7 +54,7 @@ func List(ctx context.Context, all *bool, filters map[string][]string) ([]*handl // Get performs an image inspect. To have the on-disk size of the image calculated, you can // use the optional size parameter. func GetImage(ctx context.Context, nameOrID string, size *bool) (*inspect.ImageData, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -77,7 +77,7 @@ func ImageTree(ctx context.Context, nameOrId string) error { // History returns the parent layers of an image. func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse, error) { var history []*handlers.HistoryResponse - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -89,7 +89,7 @@ func History(ctx context.Context, nameOrID string) ([]*handlers.HistoryResponse, } func Load(ctx context.Context, r io.Reader) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -103,7 +103,7 @@ func Load(ctx context.Context, r io.Reader) error { // the image by removing all all containers, including those that are Running, first. func Remove(ctx context.Context, nameOrID string, force *bool) ([]map[string]string, error) { var deletes []map[string]string - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -121,7 +121,7 @@ func Remove(ctx context.Context, nameOrID string, force *bool) ([]map[string]str // Export saves an image from local storage as a tarball or image archive. The optional format // parameter is used to change the format of the output. func Export(ctx context.Context, nameOrID string, w io.Writer, format *string, compress *bool) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -149,7 +149,7 @@ func Prune(ctx context.Context, filters map[string][]string) ([]string, error) { var ( deleted []string ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -170,7 +170,7 @@ func Prune(ctx context.Context, filters map[string][]string) ([]string, error) { // Tag adds an additional name to locally-stored image. Both the tag and repo parameters are required. func Tag(ctx context.Context, nameOrID, tag, repo string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } diff --git a/pkg/bindings/images/search.go b/pkg/bindings/images/search.go index 58b25425b..dca1b0e63 100644 --- a/pkg/bindings/images/search.go +++ b/pkg/bindings/images/search.go @@ -16,7 +16,7 @@ func Search(ctx context.Context, term string, limit *int, filters map[string][]s var ( searchResults []image.SearchResult ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go index 97bbb8c42..c95b22953 100644 --- a/pkg/bindings/network/network.go +++ b/pkg/bindings/network/network.go @@ -10,7 +10,7 @@ import ( func Create() {} func Inspect(ctx context.Context, nameOrID string) (map[string]interface{}, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -23,7 +23,7 @@ func Inspect(ctx context.Context, nameOrID string) (map[string]interface{}, erro } func Remove(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -38,7 +38,7 @@ func List(ctx context.Context) ([]*libcni.NetworkConfigList, error) { var ( netList []*libcni.NetworkConfigList ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } diff --git a/pkg/bindings/pods/pods.go b/pkg/bindings/pods/pods.go index 69d7f21bc..838b22e43 100644 --- a/pkg/bindings/pods/pods.go +++ b/pkg/bindings/pods/pods.go @@ -16,7 +16,7 @@ func CreatePod() error { // Exists is a lightweight method to determine if a pod exists in local storage func Exists(ctx context.Context, nameOrID string) (bool, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return false, err } @@ -29,7 +29,7 @@ func Exists(ctx context.Context, nameOrID string) (bool, error) { // Inspect returns low-level information about the given pod. func Inspect(ctx context.Context, nameOrID string) (*libpod.PodInspect, error) { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -44,7 +44,7 @@ func Inspect(ctx context.Context, nameOrID string) (*libpod.PodInspect, error) { // Kill sends a SIGTERM to all the containers in a pod. The optional signal parameter // can be used to override SIGTERM. func Kill(ctx context.Context, nameOrID string, signal *string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -61,7 +61,7 @@ func Kill(ctx context.Context, nameOrID string, signal *string) error { // Pause pauses all running containers in a given pod. func Pause(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -74,7 +74,7 @@ func Pause(ctx context.Context, nameOrID string) error { // Prune removes all non-running pods in local storage. func Prune(ctx context.Context) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -91,7 +91,7 @@ func List(ctx context.Context, filters map[string][]string) ([]*libpod.PodInspec var ( inspect []*libpod.PodInspect ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -112,7 +112,7 @@ func List(ctx context.Context, filters map[string][]string) ([]*libpod.PodInspec // Restart restarts all containers in a pod. func Restart(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -126,7 +126,7 @@ func Restart(ctx context.Context, nameOrID string) error { // Remove deletes a Pod from from local storage. The optional force parameter denotes // that the Pod can be removed even if in a running state. func Remove(ctx context.Context, nameOrID string, force *bool) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -143,7 +143,7 @@ func Remove(ctx context.Context, nameOrID string, force *bool) error { // Start starts all containers in a pod. func Start(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -162,7 +162,7 @@ func Stats() error { // Stop stops all containers in a Pod. The optional timeout parameter can be // used to override the timeout before the container is killed. func Stop(ctx context.Context, nameOrID string, timeout *int) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } @@ -184,7 +184,7 @@ func Top() error { // Unpause unpauses all paused containers in a Pod. func Unpause(ctx context.Context, nameOrID string) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go index 8d008d53c..98d64bbaa 100644 --- a/pkg/bindings/test/common_test.go +++ b/pkg/bindings/test/common_test.go @@ -114,7 +114,7 @@ func newBindingTest() *bindingTest { runRoot: filepath.Join(tmpPath, "run"), artifactDirPath: "", imageCacheDir: "", - sock: fmt.Sprintf("unix:%s", filepath.Join(tmpPath, "api.sock")), + sock: fmt.Sprintf("unix://%s", filepath.Join(tmpPath, "api.sock")), tempDirPath: tmpPath, } return &b diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go index 483b6b42d..0b51c8c9e 100644 --- a/pkg/bindings/test/images_test.go +++ b/pkg/bindings/test/images_test.go @@ -38,7 +38,7 @@ var _ = Describe("Podman images", func() { bt.RestoreImagesFromCache() s = bt.startAPIService() time.Sleep(1 * time.Second) - connText, err = bindings.NewConnection(bt.sock) + connText, err = bindings.NewConnection(context.Background(), bt.sock) Expect(err).To(BeNil()) }) diff --git a/pkg/bindings/volumes/volumes.go b/pkg/bindings/volumes/volumes.go index 05a4f73fd..8313a7460 100644 --- a/pkg/bindings/volumes/volumes.go +++ b/pkg/bindings/volumes/volumes.go @@ -16,7 +16,7 @@ func Create(ctx context.Context, config handlers.VolumeCreateConfig) (string, er var ( volumeID string ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return "", err } @@ -32,7 +32,7 @@ func Inspect(ctx context.Context, nameOrID string) (*libpod.InspectVolumeData, e var ( inspect libpod.InspectVolumeData ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -55,7 +55,7 @@ func Prune(ctx context.Context) ([]string, error) { var ( pruned []string ) - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return nil, err } @@ -69,7 +69,7 @@ func Prune(ctx context.Context) ([]string, error) { // Remove deletes the given volume from storage. The optional force parameter // is used to remove a volume even if it is being used by a container. func Remove(ctx context.Context, nameOrID string, force *bool) error { - conn, err := bindings.GetConnectionFromContext(ctx) + conn, err := bindings.GetClient(ctx) if err != nil { return err } -- cgit v1.2.3-54-g00ecf