summaryrefslogtreecommitdiff
path: root/pkg/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/bindings')
-rw-r--r--pkg/bindings/connection.go62
-rw-r--r--pkg/bindings/containers.go6
-rw-r--r--pkg/bindings/errors.go46
-rw-r--r--pkg/bindings/images.go111
-rw-r--r--pkg/bindings/pods.go3
-rw-r--r--pkg/bindings/volumes.go2
6 files changed, 226 insertions, 4 deletions
diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go
new file mode 100644
index 000000000..551a63c62
--- /dev/null
+++ b/pkg/bindings/connection.go
@@ -0,0 +1,62 @@
+package bindings
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+)
+
+const (
+ defaultConnection string = "http://localhost:8080/v1.24/libpod"
+ pingConnection string = "http://localhost:8080/_ping"
+)
+
+type APIResponse struct {
+ *http.Response
+ Request *http.Request
+}
+
+type Connection struct {
+ url string
+ client *http.Client
+}
+
+func NewConnection(url string) (Connection, error) {
+ if len(url) < 1 {
+ url = defaultConnection
+ }
+ newConn := Connection{
+ url: url,
+ client: &http.Client{},
+ }
+ response, err := http.Get(pingConnection)
+ if err != nil {
+ return newConn, err
+ }
+ if err := response.Body.Close(); err != nil {
+ return newConn, err
+ }
+ return newConn, err
+}
+
+func (c Connection) makeEndpoint(u string) string {
+ return fmt.Sprintf("%s%s", defaultConnection, u)
+}
+
+func (c Connection) newRequest(httpMethod, endpoint string, httpBody io.Reader, params map[string]string) (*APIResponse, error) {
+ e := c.makeEndpoint(endpoint)
+ req, err := http.NewRequest(httpMethod, e, httpBody)
+ if err != nil {
+ return nil, err
+ }
+ if len(params) > 0 {
+ // if more desirable we could use url to form the encoded endpoint with params
+ r := req.URL.Query()
+ for k, v := range params {
+ r.Add(k, v)
+ }
+ req.URL.RawQuery = r.Encode()
+ }
+ response, err := c.client.Do(req) // nolint
+ return &APIResponse{response, req}, err
+}
diff --git a/pkg/bindings/containers.go b/pkg/bindings/containers.go
index cd0b09767..01f68f970 100644
--- a/pkg/bindings/containers.go
+++ b/pkg/bindings/containers.go
@@ -109,12 +109,14 @@ func (c Connection) UnpauseContainer(nameOrID string) error {
}
func (c Connection) WaitContainer(nameOrID string) error {
- _, err := http.Post(c.makeEndpoint(fmt.Sprintf("containers/%s/wait", nameOrID)), "application/json", nil)
+ // TODO when returns are ironed out, we can should use the newRequest approach
+ _, err := http.Post(c.makeEndpoint(fmt.Sprintf("containers/%s/wait", nameOrID)), "application/json", nil) // nolint
return err
}
func (c Connection) ContainerExists(nameOrID string) (bool, error) {
- response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/containers/%s/exists", nameOrID)))
+ response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/containers/%s/exists", nameOrID))) // nolint
+ defer closeResponseBody(response)
if err != nil {
return false, err
}
diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go
new file mode 100644
index 000000000..9a02925a3
--- /dev/null
+++ b/pkg/bindings/errors.go
@@ -0,0 +1,46 @@
+package bindings
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ ErrNotImplemented = errors.New("function not implemented")
+)
+
+func handleError(data []byte) error {
+ e := utils.ErrorModel{}
+ if err := json.Unmarshal(data, &e); err != nil {
+ return err
+ }
+ return e
+}
+
+func (a APIResponse) Process(unmarshalInto interface{}) error {
+ data, err := ioutil.ReadAll(a.Response.Body)
+ if err != nil {
+ return errors.Wrap(err, "unable to process API response")
+ }
+ if a.Response.StatusCode == http.StatusOK {
+ if unmarshalInto != nil {
+ return json.Unmarshal(data, unmarshalInto)
+ }
+ return nil
+ }
+ // TODO should we add a debug here with the response code?
+ return handleError(data)
+}
+
+func closeResponseBody(r *http.Response) {
+ if r != nil {
+ if err := r.Body.Close(); err != nil {
+ logrus.Error(errors.Wrap(err, "unable to close response body"))
+ }
+ }
+}
diff --git a/pkg/bindings/images.go b/pkg/bindings/images.go
new file mode 100644
index 000000000..3abc8c372
--- /dev/null
+++ b/pkg/bindings/images.go
@@ -0,0 +1,111 @@
+package bindings
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "strconv"
+
+ "github.com/containers/libpod/pkg/api/handlers"
+ "github.com/containers/libpod/pkg/inspect"
+)
+
+func (c Connection) ImageExists(nameOrID string) (bool, error) {
+ response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/images/%s/exists", nameOrID))) // nolint
+ defer closeResponseBody(response)
+ if err != nil {
+ return false, err
+ }
+ if response.StatusCode == http.StatusOK {
+ return true, nil
+ }
+ return false, nil
+}
+
+func (c Connection) ListImages() ([]handlers.ImageSummary, error) {
+ imageSummary := []handlers.ImageSummary{}
+ response, err := c.newRequest(http.MethodGet, "/images/json", nil, nil)
+ if err != nil {
+ return imageSummary, err
+ }
+ return imageSummary, response.Process(&imageSummary)
+}
+
+func (c Connection) GetImage(nameOrID string) (*inspect.ImageData, error) {
+ inspectedData := inspect.ImageData{}
+ response, err := c.newRequest(http.MethodGet, fmt.Sprintf("/images/%s/json", nameOrID), nil, nil)
+ if err != nil {
+ return &inspectedData, err
+ }
+ return &inspectedData, response.Process(&inspectedData)
+}
+
+func (c Connection) ImageTree(nameOrId string) error {
+ return ErrNotImplemented
+}
+
+func (c Connection) ImageHistory(nameOrID string) ([]handlers.HistoryResponse, error) {
+ history := []handlers.HistoryResponse{}
+ response, err := c.newRequest(http.MethodGet, fmt.Sprintf("/images/%s/history", nameOrID), nil, nil)
+ if err != nil {
+ return history, err
+ }
+ return history, response.Process(&history)
+}
+
+func (c Connection) LoadImage(r io.Reader) error {
+ // TODO this still needs error handling added
+ _, err := http.Post(c.makeEndpoint("/images/loads"), "application/json", r) //nolint
+ return err
+}
+
+func (c Connection) RemoveImage(nameOrID string, force bool) ([]map[string]string, error) {
+ deletes := []map[string]string{}
+ params := make(map[string]string)
+ params["force"] = strconv.FormatBool(force)
+ response, err := c.newRequest(http.MethodDelete, fmt.Sprintf("/images/%s", nameOrID), nil, params)
+ if err != nil {
+ return nil, err
+ }
+ return deletes, response.Process(&deletes)
+}
+
+func (c Connection) ExportImage(nameOrID string, w io.Writer, format string, compress bool) error {
+ params := make(map[string]string)
+ params["format"] = format
+ params["compress"] = strconv.FormatBool(compress)
+ response, err := c.newRequest(http.MethodGet, fmt.Sprintf("/images/%s/get", nameOrID), nil, params)
+ if err != nil {
+ return err
+ }
+ if err := response.Process(nil); err != nil {
+ return err
+ }
+ _, err = io.Copy(w, response.Body)
+ return err
+}
+
+func (c Connection) PruneImages(all bool, filters []string) ([]string, error) {
+ var (
+ deleted []string
+ )
+ params := make(map[string]string)
+ // FIXME How do we do []strings?
+ //params["filters"] = format
+ response, err := c.newRequest(http.MethodPost, "/images/prune", nil, params)
+ if err != nil {
+ return deleted, err
+ }
+ return deleted, response.Process(nil)
+}
+
+func (c Connection) TagImage(nameOrID string) error {
+ var ()
+ response, err := c.newRequest(http.MethodPost, fmt.Sprintf("/images/%s/tag", nameOrID), nil, nil)
+ if err != nil {
+ return err
+ }
+ return response.Process(nil)
+}
+
+func (c Connection) BuildImage(nameOrId string) {}
diff --git a/pkg/bindings/pods.go b/pkg/bindings/pods.go
index eac9d2ef5..704d71477 100644
--- a/pkg/bindings/pods.go
+++ b/pkg/bindings/pods.go
@@ -14,7 +14,8 @@ func (c Connection) CreatePod() error {
}
func (c Connection) PodExists(nameOrID string) (bool, error) {
- response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/pods/%s/exists", nameOrID)))
+ response, err := http.Get(c.makeEndpoint(fmt.Sprintf("/pods/%s/exists", nameOrID))) // nolint
+ defer closeResponseBody(response)
if err != nil {
return false, err
}
diff --git a/pkg/bindings/volumes.go b/pkg/bindings/volumes.go
index 27e6f9efa..219f924e7 100644
--- a/pkg/bindings/volumes.go
+++ b/pkg/bindings/volumes.go
@@ -52,7 +52,7 @@ func (c Connection) PruneVolumes() ([]string, error) {
func (c Connection) RemoveVolume(nameOrID string, force bool) error {
params := make(map[string]string)
params["force"] = strconv.FormatBool(force)
- response, err := c.newRequest(http.MethodPost, fmt.Sprintf("/volumes/prune", nameOrID), nil, params)
+ response, err := c.newRequest(http.MethodPost, "/volumes/prune", nil, params)
if err != nil {
return err
}