[lxc-devel] [lxd/master] Wester162
wester162 on Github
lxc-bot at linuxcontainers.org
Thu Nov 26 00:40:04 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 915 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20201125/e83a857d/attachment.bin>
-------------- next part --------------
From f74d2cd2be44a6f79e5629b5d50a56af0c9df8b4 Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Sat, 21 Nov 2020 20:17:37 -0600
Subject: [PATCH 1/7] lxd/instance: WIP support for cached drivers in /1.0
Implemented functions based on the storagePoolDriversCache system to create
a cache for the lxd/qemu drivers, working on issue #7869. Because there are
only two drivers to be added at this point, the creation of the cache is
hard-coded to only include LXC/QEMU, though this could be expanded similar
to the storage pool at a later date.
The current implementation's QEMU path is hard-coded to a known functional
value on my local system to ensure that the caching functionality works,
and a final version will need to pull the value of qemuBinary (/qemuPath?)
as described in the issue comments on github.
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/instance.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/lxd/instance.go b/lxd/instance.go
index 45aed86b17..674ffa890e 100644
--- a/lxd/instance.go
+++ b/lxd/instance.go
@@ -8,6 +8,8 @@ import (
"path/filepath"
"strconv"
"strings"
+ "sync"
+ "sync/atomic"
"time"
"github.com/pkg/errors"
@@ -932,3 +934,64 @@ func containerDetermineNextSnapshotName(d *Daemon, c instance.Instance, defaultP
return pattern, nil
}
+
+// Instance Driver Cache
+// I don't forsee anything trying to simultaneously edit/read these values, but in a case of Cargo Cult Programming I'm going to go ahead
+// and use the atomic value setup from the storage cache for the time being. Worst case it's a very tiny performance hit?
+var instanceDriversCacheVal atomic.Value
+var instanceDriversCacheLock sync.Mutex
+
+// Declare qemuBinary so it can be set by qemuStart for use here
+var qemuPath string = "qemu-system-x86_64" //hard coded value is for testing purposes only
+
+//SetQemuPath Setter function for the qemuPath variable
+//Attempts to call this from driver_qemu.go result in it being an undefined function in that scope.
+//Clearly I'm doing something wrong.
+func SetQemuPath(path string) {
+ qemuPath = path
+ return
+}
+
+func readInstanceDriversCache() map[string]string {
+ // Get the cached list of instance drivers in use on this LXD instance
+ // and call Create if the cache is empty.
+
+ drivers := instanceDriversCacheVal.Load()
+ if drivers == nil {
+ createInstanceDriversCache()
+ drivers = instanceDriversCacheVal.Load()
+ }
+
+ return drivers.(map[string]string)
+}
+
+func createInstanceDriversCache() {
+ // Create the list of instance drivers in use on this LXD instance
+ // namely LXC and QEMU. Given that LXC and QEMU cannot update while
+ // the LXD instance is running, this shouldn't ever be called more
+ // than once.
+
+ data := map[string]string{}
+
+ // Get LXC driver information
+ data["lxc"] = liblxc.Version()
+
+ // Get QEMU driver information
+
+ //Need to update this to use qemuBinary properly. There's also likely a more graceful way of doing the byte slice -> string conversion
+ out, err := exec.Command(qemuPath, "--version").Output()
+
+ if err != nil {
+ data["qemu"] = "0"
+ } else {
+ fieldOut := strings.Fields(string(out))
+ data["qemu"] = fieldOut[3]
+ }
+
+ //Store the value in the cache
+ instanceDriversCacheLock.Lock()
+ instanceDriversCacheVal.Store(data)
+ instanceDriversCacheLock.Unlock()
+
+ return
+}
From 72956b3a3dbfefa4225014f21d239c24c4669455 Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Sat, 21 Nov 2020 20:17:59 -0600
Subject: [PATCH 2/7] lxd/api_1.0: Add support for cached driver values
Pulls the Driver and DriverVersion values from a cache to prevent
hitting go-lxc repeatedly. Supports any additional drivers present
in the cache, such as qemu.
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/api_1.0.go | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index 72212579a2..cac3539e4d 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -6,8 +6,6 @@ import (
"os"
"strings"
- liblxc "gopkg.in/lxc/go-lxc.v2"
-
lxd "github.com/lxc/lxd/client"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/config"
@@ -201,8 +199,6 @@ func api10Get(d *Daemon, r *http.Request) response.Response {
Architectures: architectures,
Certificate: certificate,
CertificateFingerprint: certificateFingerprint,
- Driver: "lxc",
- DriverVersion: liblxc.Version(),
Kernel: uname.Sysname,
KernelArchitecture: uname.Machine,
KernelVersion: uname.Release,
@@ -226,6 +222,22 @@ func api10Get(d *Daemon, r *http.Request) response.Response {
"shiftfs": fmt.Sprintf("%v", d.os.Shiftfs),
}
+ instanceDrivers := readInstanceDriversCache()
+ for driver, version := range instanceDrivers {
+ if env.Driver != "" {
+ env.Driver = env.Driver + " | " + driver
+ } else {
+ env.Driver = driver
+ }
+
+ // Get the version of the instance drivers in use.
+ if env.DriverVersion != "" {
+ env.DriverVersion = env.DriverVersion + " | " + version
+ } else {
+ env.DriverVersion = version
+ }
+ }
+
if d.os.LXCFeatures != nil {
env.LXCFeatures = map[string]string{}
for k, v := range d.os.LXCFeatures {
From 79de4e522f0bef3c29803a200b2f02b970a0ec7b Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Wed, 25 Nov 2020 18:04:01 -0600
Subject: [PATCH 3/7] lxd/instance: Add support for Info() to Instance
interface
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/instance/instance_interface.go | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index c096230bf3..d6d94d6d99 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -57,6 +57,7 @@ type Instance interface {
RegisterDevices()
SaveConfigFile() error
+ Info() Info
IsPrivileged() bool
// Snapshots & migration & backups.
@@ -164,3 +165,9 @@ type CriuMigrationArgs struct {
PreDumpDir string
Features liblxc.CriuFeatures
}
+
+// Info represents information about an instance driver.
+type Info struct {
+ Name string // Name of an instance driver, e.g. "lxc"
+ Version string // Version number of a loaded instance driver
+}
From 257cfd19bba4d9bf6d60a29de8e48fa737c8e1ce Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Wed, 25 Nov 2020 18:06:19 -0600
Subject: [PATCH 4/7] lxd/instance/drivers: Implement Info() function
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/instance/drivers/driver_lxc.go | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 054c698372..db680fe9e7 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -7042,3 +7042,11 @@ func (c *lxc) SaveConfigFile() error {
return nil
}
+
+// Returns "lxc" and the currently loaded version of LXC
+func (c *lxc) Info() instance.Info {
+ return instance.Info{
+ Name: "lxc",
+ Version: liblxc.Version(),
+ }
+}
From c159ffb80233550cb6c196fe39aa8137c7d74e32 Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Wed, 25 Nov 2020 18:09:41 -0600
Subject: [PATCH 5/7] lxd/instance/drivers: Add drivers package support for
supported drivers.
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/instance/drivers/load.go | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/lxd/instance/drivers/load.go b/lxd/instance/drivers/load.go
index f478c75ed4..757032f351 100644
--- a/lxd/instance/drivers/load.go
+++ b/lxd/instance/drivers/load.go
@@ -15,6 +15,11 @@ import (
"github.com/lxc/lxd/shared/api"
)
+var instanceDrivers = map[string]func() instance.Instance{
+ "lxc": func() instance.Instance { return &lxc{} },
+ "qemu": func() instance.Instance { return &qemu{} },
+}
+
func init() {
// Expose load to the instance package, to avoid circular imports.
instance.Load = load
@@ -96,3 +101,15 @@ func create(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
return nil, fmt.Errorf("Instance type invalid")
}
+
+// SupportedInstanceDrivers returns a slice of Info structs for all supported drivers
+func SupportedInstanceDrivers() []instance.Info {
+ supportedDrivers := make([]instance.Info, 0, len(instanceDrivers))
+
+ for _, instanceDriver := range instanceDrivers {
+ driver := instanceDriver()
+ supportedDrivers = append(supportedDrivers, driver.Info())
+ }
+
+ return supportedDrivers
+}
From f2f193362cafbd0badef81d7d812f19fa65e3b9e Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Wed, 25 Nov 2020 18:12:35 -0600
Subject: [PATCH 6/7] lxd/main: Remove driver-specific logic from instance.go
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/instance.go | 36 +++++-------------------------------
1 file changed, 5 insertions(+), 31 deletions(-)
diff --git a/lxd/instance.go b/lxd/instance.go
index 674ffa890e..a4813a7922 100644
--- a/lxd/instance.go
+++ b/lxd/instance.go
@@ -21,6 +21,7 @@ import (
"github.com/lxc/lxd/lxd/db"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -935,26 +936,10 @@ func containerDetermineNextSnapshotName(d *Daemon, c instance.Instance, defaultP
return pattern, nil
}
-// Instance Driver Cache
-// I don't forsee anything trying to simultaneously edit/read these values, but in a case of Cargo Cult Programming I'm going to go ahead
-// and use the atomic value setup from the storage cache for the time being. Worst case it's a very tiny performance hit?
var instanceDriversCacheVal atomic.Value
var instanceDriversCacheLock sync.Mutex
-// Declare qemuBinary so it can be set by qemuStart for use here
-var qemuPath string = "qemu-system-x86_64" //hard coded value is for testing purposes only
-
-//SetQemuPath Setter function for the qemuPath variable
-//Attempts to call this from driver_qemu.go result in it being an undefined function in that scope.
-//Clearly I'm doing something wrong.
-func SetQemuPath(path string) {
- qemuPath = path
- return
-}
-
func readInstanceDriversCache() map[string]string {
- // Get the cached list of instance drivers in use on this LXD instance
- // and call Create if the cache is empty.
drivers := instanceDriversCacheVal.Load()
if drivers == nil {
@@ -968,24 +953,13 @@ func readInstanceDriversCache() map[string]string {
func createInstanceDriversCache() {
// Create the list of instance drivers in use on this LXD instance
// namely LXC and QEMU. Given that LXC and QEMU cannot update while
- // the LXD instance is running, this shouldn't ever be called more
- // than once.
+ // the LXD instance is running, only one cache is ever needed.
data := map[string]string{}
- // Get LXC driver information
- data["lxc"] = liblxc.Version()
-
- // Get QEMU driver information
-
- //Need to update this to use qemuBinary properly. There's also likely a more graceful way of doing the byte slice -> string conversion
- out, err := exec.Command(qemuPath, "--version").Output()
-
- if err != nil {
- data["qemu"] = "0"
- } else {
- fieldOut := strings.Fields(string(out))
- data["qemu"] = fieldOut[3]
+ info := drivers.SupportedInstanceDrivers()
+ for _, entry := range info {
+ data[entry.Name] = entry.Version
}
//Store the value in the cache
From ead2141f80ca05346b012c4f0bf59618103f1051 Mon Sep 17 00:00:00 2001
From: Alex Oliver <oliver.alex96 at gmail.com>
Date: Wed, 25 Nov 2020 18:26:30 -0600
Subject: [PATCH 7/7] lxd/instance/drivers: Implement Info() in driver_qemu.go
There seems to be some kind of runtime bug in the code where the
vm.architecture value is 0 when in this function, and as a result
the binary for qemu cannot be found, and the version number cannot
be properly found.
Bug is reproducable on a system with qemu version 4.2.1 installed
Signed-off-by: Alex J Oliver <oliver.alex96 at gmail.com>
---
lxd/instance/drivers/driver_qemu.go | 49 +++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index abd05b2e85..c10c116e97 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -5157,3 +5157,52 @@ func (vm *qemu) writeInstanceData() error {
return nil
}
+
+// Returns "qemu" and the currently loaded qemu version, 0 if not found.
+// Unsure if this is the proper behavior for a not found, but the logic is there.
+// TODO: This seems to be getting a 0 value for vm.architecture, and as a result cannot find the binary, giving a 0 for the version no.
+func (vm *qemu) Info() instance.Info {
+
+ var qemuVersion, qemuBinary, qemuPath string
+ var out []byte
+ var err error
+ qemuBinary, _, err = vm.qemuArchConfig()
+ println("vm architecture ", vm.architecture)
+ println("qemuBinary: " + qemuBinary)
+ if err == nil {
+ qemuPath, err = exec.LookPath(qemuBinary)
+ if err == nil {
+ out, err = exec.Command(qemuPath, "--version").Output()
+ if err != nil {
+ qemuVersion = "0"
+ } else {
+ qemuVersion = strings.Fields(string(out))[3]
+ }
+ } else {
+ qemuVersion = "-1"
+ }
+ } else {
+ qemuVersion = "-2"
+ }
+ // if err != nil {
+ // qemuVersion = "0"
+ // println("QEMUBINARY ERROR %d", err)
+ // }
+
+ // qemuPath, err := exec.LookPath(qemuBinary)
+ // if err != nil {
+ // qemuVersion = "0"
+ // }
+
+ //out, err = exec.Command(qemuPath, "--version").Output()
+ // if err != nil {
+ // qemuVersion = "0"
+ // } else {
+ // qemuVersion = strings.Fields(string(out))[3]
+ // }
+
+ return instance.Info{
+ Name: "qemu",
+ Version: qemuVersion,
+ }
+}
More information about the lxc-devel
mailing list