[lxc-devel] [lxd/master] Support downloading through host LXD
stgraber on Github
lxc-bot at linuxcontainers.org
Wed Jul 25 22:25:29 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 716 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180725/77ddb28f/attachment.bin>
-------------- next part --------------
From 4b99727e9175a9cbd1f9523fc9c494a9eae94074 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 25 Jul 2018 18:06:49 -0400
Subject: [PATCH 1/2] client: Split LXD download code into own function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
client/lxd.go | 4 ++--
client/lxd_containers.go | 14 +++++++-------
client/lxd_images.go | 20 ++++++++++++--------
3 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/client/lxd.go b/client/lxd.go
index 4b386cd30..3f61c84f7 100644
--- a/client/lxd.go
+++ b/client/lxd.go
@@ -121,7 +121,7 @@ func (r *ProtocolLXD) RawOperation(method string, path string, data interface{},
}
// Internal functions
-func (r *ProtocolLXD) parseResponse(resp *http.Response) (*api.Response, string, error) {
+func lxdParseResponse(resp *http.Response) (*api.Response, string, error) {
// Get the ETag
etag := resp.Header.Get("ETag")
@@ -221,7 +221,7 @@ func (r *ProtocolLXD) rawQuery(method string, url string, data interface{}, ETag
}
defer resp.Body.Close()
- return r.parseResponse(resp)
+ return lxdParseResponse(resp)
}
func (r *ProtocolLXD) query(method string, path string, data interface{}, ETag string) (*api.Response, string, error) {
diff --git a/client/lxd_containers.go b/client/lxd_containers.go
index 3eaa2d998..a7df5ba4c 100644
--- a/client/lxd_containers.go
+++ b/client/lxd_containers.go
@@ -762,7 +762,7 @@ func (r *ProtocolLXD) GetContainerFile(containerName string, path string) (io.Re
// Check the return value for a cleaner error
if resp.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(resp)
+ _, _, err := lxdParseResponse(resp)
if err != nil {
return nil, nil, err
}
@@ -861,7 +861,7 @@ func (r *ProtocolLXD) CreateContainerFile(containerName string, path string, arg
}
// Check the return value for a cleaner error
- _, _, err = r.parseResponse(resp)
+ _, _, err = lxdParseResponse(resp)
if err != nil {
return err
}
@@ -1287,7 +1287,7 @@ func (r *ProtocolLXD) GetContainerLogfile(name string, filename string) (io.Read
// Check the return value for a cleaner error
if resp.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(resp)
+ _, _, err := lxdParseResponse(resp)
if err != nil {
return nil, err
}
@@ -1381,7 +1381,7 @@ func (r *ProtocolLXD) GetContainerTemplateFile(containerName string, templateNam
// Check the return value for a cleaner error
if resp.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(resp)
+ _, _, err := lxdParseResponse(resp)
if err != nil {
return nil, err
}
@@ -1421,7 +1421,7 @@ func (r *ProtocolLXD) setContainerTemplateFile(containerName string, templateNam
resp, err := r.http.Do(req)
// Check the return value for a cleaner error
if resp.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(resp)
+ _, _, err := lxdParseResponse(resp)
if err != nil {
return err
}
@@ -1536,7 +1536,7 @@ func (r *ProtocolLXD) GetContainerConsoleLog(containerName string, args *Contain
// Check the return value for a cleaner error
if resp.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(resp)
+ _, _, err := lxdParseResponse(resp)
if err != nil {
return nil, err
}
@@ -1695,7 +1695,7 @@ func (r *ProtocolLXD) GetContainerBackupFile(containerName string, name string,
defer close(doneCh)
if response.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(response)
+ _, _, err := lxdParseResponse(response)
if err != nil {
return nil, err
}
diff --git a/client/lxd_images.go b/client/lxd_images.go
index 9eb7928c5..e3c12f5f4 100644
--- a/client/lxd_images.go
+++ b/client/lxd_images.go
@@ -99,27 +99,31 @@ func (r *ProtocolLXD) GetPrivateImageFile(fingerprint string, secret string, req
return nil, fmt.Errorf("No file requested")
}
- // Prepare the response
- resp := ImageFileResponse{}
-
// Build the URL
uri := fmt.Sprintf("%s/1.0/images/%s/export", r.httpHost, url.QueryEscape(fingerprint))
if secret != "" {
uri = fmt.Sprintf("%s?secret=%s", uri, url.QueryEscape(secret))
}
+ return lxdDownloadImage(fingerprint, uri, r.httpUserAgent, r.http, req)
+}
+
+func lxdDownloadImage(fingerprint string, uri string, userAgent string, client *http.Client, req ImageFileRequest) (*ImageFileResponse, error) {
+ // Prepare the response
+ resp := ImageFileResponse{}
+
// Prepare the download request
request, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, err
}
- if r.httpUserAgent != "" {
- request.Header.Set("User-Agent", r.httpUserAgent)
+ if userAgent != "" {
+ request.Header.Set("User-Agent", userAgent)
}
// Start the request
- response, doneCh, err := cancel.CancelableDownload(req.Canceler, r.http, request)
+ response, doneCh, err := cancel.CancelableDownload(req.Canceler, client, request)
if err != nil {
return nil, err
}
@@ -127,7 +131,7 @@ func (r *ProtocolLXD) GetPrivateImageFile(fingerprint string, secret string, req
defer close(doneCh)
if response.StatusCode != http.StatusOK {
- _, _, err := r.parseResponse(response)
+ _, _, err := lxdParseResponse(response)
if err != nil {
return nil, err
}
@@ -412,7 +416,7 @@ func (r *ProtocolLXD) CreateImage(image api.ImagesPost, args *ImageCreateArgs) (
defer resp.Body.Close()
// Handle errors
- response, _, err := r.parseResponse(resp)
+ response, _, err := lxdParseResponse(resp)
if err != nil {
return nil, err
}
From f80ef7e9c5a935b7f1cb92fa3545567f2ee54fe3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 25 Jul 2018 18:23:02 -0400
Subject: [PATCH 2/2] client: Attempt to fetch through devlxd
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
client/lxd_images.go | 14 ++++++++++++++
client/simplestreams_images.go | 15 +++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/client/lxd_images.go b/client/lxd_images.go
index e3c12f5f4..9927565df 100644
--- a/client/lxd_images.go
+++ b/client/lxd_images.go
@@ -99,6 +99,20 @@ func (r *ProtocolLXD) GetPrivateImageFile(fingerprint string, secret string, req
return nil, fmt.Errorf("No file requested")
}
+ // Attempt to download from host
+ if secret == "" && shared.PathExists("/dev/lxd/sock") && os.Geteuid() == 0 {
+ unixUri := fmt.Sprintf("http://unix.socket/1.0/images/%s/export", url.QueryEscape(fingerprint))
+
+ // Setup the HTTP client
+ devlxdHttp, err := unixHTTPClient(nil, "/dev/lxd/sock")
+ if err == nil {
+ resp, err := lxdDownloadImage(fingerprint, unixUri, r.httpUserAgent, devlxdHttp, req)
+ if err == nil {
+ return resp, nil
+ }
+ }
+ }
+
// Build the URL
uri := fmt.Sprintf("%s/1.0/images/%s/export", r.httpHost, url.QueryEscape(fingerprint))
if secret != "" {
diff --git a/client/simplestreams_images.go b/client/simplestreams_images.go
index 065bedabe..b9f6bf65a 100644
--- a/client/simplestreams_images.go
+++ b/client/simplestreams_images.go
@@ -4,6 +4,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net/url"
"os"
"os/exec"
"strings"
@@ -53,6 +54,20 @@ func (r *ProtocolSimpleStreams) GetImageFile(fingerprint string, req ImageFileRe
return nil, fmt.Errorf("No file requested")
}
+ // Attempt to download from host
+ if shared.PathExists("/dev/lxd/sock") && os.Geteuid() == 0 {
+ unixUri := fmt.Sprintf("http://unix.socket/1.0/images/%s/export", url.QueryEscape(fingerprint))
+
+ // Setup the HTTP client
+ devlxdHttp, err := unixHTTPClient(nil, "/dev/lxd/sock")
+ if err == nil {
+ resp, err := lxdDownloadImage(fingerprint, unixUri, r.httpUserAgent, devlxdHttp, req)
+ if err == nil {
+ return resp, nil
+ }
+ }
+ }
+
// Get the file list
files, err := r.ssClient.GetFiles(fingerprint)
if err != nil {
More information about the lxc-devel
mailing list