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:
parent
83a9b318e1
commit
0f0b4fd3c2
113
cmd/cli/main.go
113
cmd/cli/main.go
|
|
@ -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
1
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=
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue