The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/2130
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From b2039dd030efb39ef011df51ee90aaf81d838e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Thu, 16 Jun 2016 15:56:59 -0400 Subject: [PATCH 1/4] Fail to add an existing certificate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/certificates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/certificates.go b/lxd/certificates.go index a0502aa..f40ae02 100644 --- a/lxd/certificates.go +++ b/lxd/certificates.go @@ -141,7 +141,7 @@ func certificatesPost(d *Daemon, r *http.Request) Response { fingerprint := certGenerateFingerprint(cert) for _, existingCert := range d.clientCerts { if fingerprint == certGenerateFingerprint(&existingCert) { - return EmptySyncResponse + return BadRequest(fmt.Errorf("Certificate already in trust store")) } } From 8555723c814bc0b00b03ad8213cfb9d73819ca77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Thu, 16 Jun 2016 16:25:13 -0400 Subject: [PATCH 2/4] Fix failure to restore on btrfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #2058 Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage_btrfs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go index 2710c0c..f1b6a7d 100644 --- a/lxd/storage_btrfs.go +++ b/lxd/storage_btrfs.go @@ -249,7 +249,7 @@ func (s *storageBtrfs) ContainerRestore( } else { // Remove the backup, we made if s.isSubvolume(sourceBackupPath) { - return s.subvolDelete(sourceBackupPath) + return s.subvolsDelete(sourceBackupPath) } os.RemoveAll(sourceBackupPath) } From 129040d89359484376808fe8e542ea8aa993db16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Thu, 16 Jun 2016 16:40:08 -0400 Subject: [PATCH 3/4] Set Location on sync POST requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #2092 Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/certificates.go | 17 ++++++++--------- lxd/images.go | 4 ++-- lxd/profiles.go | 4 ++-- lxd/response.go | 10 ++++++++++ 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lxd/certificates.go b/lxd/certificates.go index f40ae02..021b48f 100644 --- a/lxd/certificates.go +++ b/lxd/certificates.go @@ -96,20 +96,25 @@ func saveCert(d *Daemon, host string, cert *x509.Certificate) error { } func certificatesPost(d *Daemon, r *http.Request) Response { + // Parse the request req := certificatesPostBody{} - if err := shared.ReadToJSON(r.Body, &req); err != nil { return BadRequest(err) } + // Access check + if !d.isTrustedClient(r) && d.PasswordCheck(req.Password) != nil { + return Forbidden + } + if req.Type != "client" { return BadRequest(fmt.Errorf("Unknown request type %s", req.Type)) } + // Extract the certificate var cert *x509.Certificate var name string if req.Certificate != "" { - data, err := base64.StdEncoding.DecodeString(req.Certificate) if err != nil { return BadRequest(err) @@ -120,9 +125,7 @@ func certificatesPost(d *Daemon, r *http.Request) Response { return BadRequest(err) } name = req.Name - } else if r.TLS != nil { - if len(r.TLS.PeerCertificates) < 1 { return BadRequest(fmt.Errorf("No client certificate provided")) } @@ -145,10 +148,6 @@ func certificatesPost(d *Daemon, r *http.Request) Response { } } - if !d.isTrustedClient(r) && d.PasswordCheck(req.Password) != nil { - return Forbidden - } - err := saveCert(d, name, cert) if err != nil { return SmartError(err) @@ -156,7 +155,7 @@ func certificatesPost(d *Daemon, r *http.Request) Response { d.clientCerts = append(d.clientCerts, *cert) - return EmptySyncResponse + return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/certificates/%s", shared.APIVersion, fingerprint)) } var certificatesCmd = Command{ diff --git a/lxd/images.go b/lxd/images.go index 8118d8f..b5d8e31 100644 --- a/lxd/images.go +++ b/lxd/images.go @@ -1093,7 +1093,7 @@ func aliasesPost(d *Daemon, r *http.Request) Response { return InternalError(err) } - return EmptySyncResponse + return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/images/aliases/%s", shared.APIVersion, req.Name)) } func aliasesGet(d *Daemon, r *http.Request) Response { @@ -1211,7 +1211,7 @@ func aliasPost(d *Daemon, r *http.Request) Response { return SmartError(err) } - return EmptySyncResponse + return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/images/aliases/%s", shared.APIVersion, req.Name)) } func imageExport(d *Daemon, r *http.Request) Response { diff --git a/lxd/profiles.go b/lxd/profiles.go index 32a498a..13ac836 100644 --- a/lxd/profiles.go +++ b/lxd/profiles.go @@ -83,7 +83,7 @@ func profilesPost(d *Daemon, r *http.Request) Response { fmt.Errorf("Error inserting %s into database: %s", req.Name, err)) } - return EmptySyncResponse + return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, req.Name)) } var profilesCmd = Command{ @@ -259,7 +259,7 @@ func profilePost(d *Daemon, r *http.Request) Response { return InternalError(err) } - return EmptySyncResponse + return SyncResponseLocation(true, nil, fmt.Sprintf("/%s/profiles/%s", shared.APIVersion, req.Name)) } // The handler for the delete operation. diff --git a/lxd/response.go b/lxd/response.go index 2aa9a05..fc37f9c 100644 --- a/lxd/response.go +++ b/lxd/response.go @@ -41,6 +41,7 @@ type syncResponse struct { success bool etag interface{} metadata interface{} + location string } func (r *syncResponse) Render(w http.ResponseWriter) error { @@ -58,6 +59,11 @@ func (r *syncResponse) Render(w http.ResponseWriter) error { status = shared.Failure } + if r.location != "" { + w.Header().Set("Location", r.location) + w.WriteHeader(201) + } + resp := syncResp{Type: lxd.Sync, Status: status.String(), StatusCode: status, Metadata: r.metadata} return WriteJSON(w, resp) } @@ -78,6 +84,10 @@ func SyncResponseETag(success bool, metadata interface{}, etag interface{}) Resp return &syncResponse{success: success, metadata: metadata, etag: etag} } +func SyncResponseLocation(success bool, metadata interface{}, location string) Response { + return &syncResponse{success: success, metadata: metadata, location: location} +} + var EmptySyncResponse = &syncResponse{success: true, metadata: make(map[string]interface{})} // File transfer response From 634990c8c95add4fc79e6f2380674b8a85c7d8f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Thu, 16 Jun 2016 16:42:47 -0400 Subject: [PATCH 4/4] Clarify ZFS snapshot shortcomings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #2055 Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- doc/storage-backends.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/storage-backends.md b/doc/storage-backends.md index 4b4ce0e..0c6e2e8 100644 --- a/doc/storage-backends.md +++ b/doc/storage-backends.md @@ -63,3 +63,11 @@ rsync is used to transfer the container content across. one. You can however create new containers from older snapshots which makes it possible to confirm the snapshots is indeed what you want to restore before you remove the newer snapshots. + + Also note that container copies use ZFS snapshots, so you also cannot + restore a container to a snapshot taken before the last copy without + having to also delete container copies. + + Copying the wanted snapshot into a new container and then deleting + the old container does however work, at the cost of loosing any other + snapshot the container may have had.
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel