[lxc-devel] [lxd/master] Implement patches mechanism
stgraber on Github
lxc-bot at linuxcontainers.org
Fri Jun 3 05:23:30 UTC 2016
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160603/0dddd375/attachment.bin>
-------------- next part --------------
From 5e831b86be5aa1b589b6de7f821cb26373fe3cc2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Thu, 2 Jun 2016 23:47:51 -0400
Subject: [PATCH 1/3] patches: Add new table and schema update
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>
---
lxd/db.go | 8 +++++++-
lxd/db_update.go | 19 +++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/lxd/db.go b/lxd/db.go
index abd450f..17fc137 100644
--- a/lxd/db.go
+++ b/lxd/db.go
@@ -34,7 +34,7 @@ type Profile struct {
// Profiles will contain a list of all Profiles.
type Profiles []Profile
-const DB_CURRENT_VERSION int = 31
+const DB_CURRENT_VERSION int = 32
// CURRENT_SCHEMA contains the current SQLite SQL Schema.
const CURRENT_SCHEMA string = `
@@ -135,6 +135,12 @@ CREATE TABLE IF NOT EXISTS images_source (
alias VARCHAR(255) NOT NULL,
FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE
);
+CREATE TABLE IF NOT EXISTS patches (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ applied_at DATETIME NOT NULL,
+ UNIQUE (name)
+);
CREATE TABLE IF NOT EXISTS profiles (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name VARCHAR(255) NOT NULL,
diff --git a/lxd/db_update.go b/lxd/db_update.go
index d8056d8..95ed4d3 100644
--- a/lxd/db_update.go
+++ b/lxd/db_update.go
@@ -17,6 +17,19 @@ import (
log "gopkg.in/inconshreveable/log15.v2"
)
+func dbUpdateFromV31(db *sql.DB) error {
+ stmt := `
+CREATE TABLE IF NOT EXISTS patches (
+ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ applied_at DATETIME NOT NULL,
+ UNIQUE (name)
+);
+INSERT INTO schema (version, updated_at) VALUES (?, strftime("%s"));`
+ _, err := db.Exec(stmt, 32)
+ return err
+}
+
func dbUpdateFromV30(db *sql.DB, mockMode bool) error {
if mockMode {
stmt := `INSERT INTO schema (version, updated_at) VALUES (?, strftime("%s"));`
@@ -1072,6 +1085,12 @@ func dbUpdate(d *Daemon, prevVersion int) error {
return err
}
}
+ if prevVersion < 32 {
+ err = dbUpdateFromV31(db)
+ if err != nil {
+ return err
+ }
+ }
return nil
}
From dc09db92ba6e3203755865630e10ad52e7893334 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 3 Jun 2016 00:57:06 -0400
Subject: [PATCH 2/3] patches: Initial implementation
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>
---
lxd/daemon.go | 8 ++++++-
lxd/db_patches.go | 30 +++++++++++++++++++++++++
lxd/patches.go | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 102 insertions(+), 1 deletion(-)
create mode 100644 lxd/db_patches.go
create mode 100644 lxd/patches.go
diff --git a/lxd/daemon.go b/lxd/daemon.go
index d8bf79d..0215f0d 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -738,12 +738,18 @@ func (d *Daemon) Init() error {
return err
}
- /* Setup the storage driver */
if !d.MockMode {
+ /* Setup the storage driver */
err = d.SetupStorageDriver()
if err != nil {
return fmt.Errorf("Failed to setup storage: %s", err)
}
+
+ /* Apply all patches */
+ err = patchesApplyAll(d)
+ if err != nil {
+ return err
+ }
}
/* Log expiry */
diff --git a/lxd/db_patches.go b/lxd/db_patches.go
new file mode 100644
index 0000000..cd2876a
--- /dev/null
+++ b/lxd/db_patches.go
@@ -0,0 +1,30 @@
+package main
+
+import (
+ "database/sql"
+ "fmt"
+)
+
+func dbPatches(db *sql.DB) ([]string, error) {
+ inargs := []interface{}{}
+ outfmt := []interface{}{""}
+
+ query := fmt.Sprintf("SELECT name FROM patches")
+ result, err := dbQueryScan(db, query, inargs, outfmt)
+ if err != nil {
+ return []string{}, err
+ }
+
+ response := []string{}
+ for _, r := range result {
+ response = append(response, r[0].(string))
+ }
+
+ return response, nil
+}
+
+func dbPatchesMarkApplied(db *sql.DB, patch string) error {
+ stmt := `INSERT INTO patches (name, applied_at) VALUES (?, strftime("%s"));`
+ _, err := db.Exec(stmt, patch)
+ return err
+}
diff --git a/lxd/patches.go b/lxd/patches.go
new file mode 100644
index 0000000..b0174c7
--- /dev/null
+++ b/lxd/patches.go
@@ -0,0 +1,65 @@
+package main
+
+import (
+ "github.com/lxc/lxd/shared"
+)
+
+/* Patches are one-time actions that are sometimes needed to update
+ existing container configuration or move things around on the
+ filesystem.
+
+ Those patches are applied at startup time after the database schema
+ has been fully updated. Patches can therefore assume a working database.
+
+ At the time the patches are applied, the containers aren't started
+ yet and the daemon isn't listening to requests.
+
+ DO NOT use this mechanism for database update. Schema updates must be
+ done through the separate schema update mechanism.
+
+
+ Only append to the patches list, never remove entries and never re-order them.
+*/
+
+var patches = []patch{}
+
+type patch struct {
+ name string
+ run func(name string, d *Daemon) error
+}
+
+func (p *patch) apply(d *Daemon) error {
+ shared.Debugf("Applying patch: %s", p.name)
+
+ err := p.run(p.name, d)
+ if err != nil {
+ return err
+ }
+
+ err = dbPatchesMarkApplied(d.db, p.name)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func patchesApplyAll(d *Daemon) error {
+ appliedPatches, err := dbPatches(d.db)
+ if err != nil {
+ return err
+ }
+
+ for _, patch := range patches {
+ if shared.StringInSlice(patch.name, appliedPatches) {
+ continue
+ }
+
+ err := patch.apply(d)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
From 3d00e39f80698dc9c600453e831c4e3fdb75a6f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Fri, 3 Jun 2016 01:03:05 -0400
Subject: [PATCH 3/3] Tiny optimization in db_update
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>
---
lxd/db_update.go | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/lxd/db_update.go b/lxd/db_update.go
index 95ed4d3..73ec867 100644
--- a/lxd/db_update.go
+++ b/lxd/db_update.go
@@ -892,12 +892,14 @@ INSERT INTO schema (version, updated_at) VALUES (?, strftime("%s"));`
func dbUpdate(d *Daemon, prevVersion int) error {
db := d.db
- if prevVersion < 0 || prevVersion > DB_CURRENT_VERSION {
- return fmt.Errorf("Bad database version: %d", prevVersion)
- }
if prevVersion == DB_CURRENT_VERSION {
return nil
}
+
+ if prevVersion < 0 || prevVersion > DB_CURRENT_VERSION {
+ return fmt.Errorf("Bad database version: %d", prevVersion)
+ }
+
var err error
if prevVersion < 1 {
err = dbUpdateFromV0(db)
More information about the lxc-devel
mailing list