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 <jhonce@redhat.com>
This commit is contained in:
Jhon Honce 2020-02-19 17:38:43 -07:00
parent 83a9b318e1
commit 0f0b4fd3c2
14 changed files with 231 additions and 213 deletions

View File

@ -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://<user>@<host>[: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
}

1
go.sum
View File

@ -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=

View File

@ -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:<port>
// or unix://run/podman/podman.sock
func NewConnection(uri string) (context.Context, error) {
u, err := url.Parse(uri)
// or unix:///run/podman/podman.sock
// or ssh://<user>@<host>[: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 v, found := os.LookupEnv("PODMAN_SSHKEY"); found {
identity = []string{v}
}
_url, 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
}
if u.Scheme != "tcp" && u.Scheme != "unix" {
return nil, errors.Errorf("%s is not a support schema", u.Scheme)
return nil, errors.Wrapf(err, "Value of PODMAN_HOST is not a valid url: %s", uri)
}
if u.Scheme == "tcp" && !strings.HasPrefix(uri, "tcp://") {
return nil, errors.New("tcp URIs should begin with tcp://")
// 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)
}
address := u.Path
if u.Scheme == "tcp" {
address = u.Host
}
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{
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())
}
return &http.Client{
Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.Dial(scheme, address)
return bastion.Dial("unix", _url.Path)
},
},
}
newConn := Connection{
client: &client,
address: address,
scheme: scheme,
}
return newConn
}}, 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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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())
})

View File

@ -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
}