[lxc-devel] [lxd/master] Export LXC features in API

stgraber on Github lxc-bot at linuxcontainers.org
Wed May 8 21:18:55 UTC 2019


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/20190508/8f8c835d/attachment-0001.bin>
-------------- next part --------------
From f33e1ca2f2a0683cbb05a0139e479c4d7f604165 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 8 May 2019 17:03:32 -0400
Subject: [PATCH 1/5] lxd/sys: Cleanup State struct
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/sys/os.go | 50 ++++++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/lxd/sys/os.go b/lxd/sys/os.go
index e65f4eb173..a880b71214 100644
--- a/lxd/sys/os.go
+++ b/lxd/sys/os.go
@@ -31,25 +31,32 @@ type InotifyInfo struct {
 // OS is a high-level facade for accessing all operating-system
 // level functionality that LXD uses.
 type OS struct {
-	VarDir   string // Data directory (e.g. /var/lib/lxd/).
+	// Directories
 	CacheDir string // Cache directory (e.g. /var/cache/lxd/).
 	LogDir   string // Log directory (e.g. /var/log/lxd).
+	VarDir   string // Data directory (e.g. /var/lib/lxd/).
 
-	// Caches of system characteristics detected at Init() time.
-	Architectures           []int           // Cache of detected system architectures
-	LxcPath                 string          // Path to the $LXD_DIR/containers directory
-	BackingFS               string          // Backing filesystem of $LXD_DIR/containers
-	IdmapSet                *idmap.IdmapSet // Information about user/group ID mapping
-	ExecPath                string          // Absolute path to the LXD executable
-	RunningInUserNS         bool
-	AppArmorAvailable       bool
-	AppArmorStacking        bool
-	AppArmorStacked         bool
-	AppArmorAdmin           bool
-	AppArmorConfined        bool
+	// Daemon environment
+	Architectures   []int           // Cache of detected system architectures
+	BackingFS       string          // Backing filesystem of $LXD_DIR/containers
+	ExecPath        string          // Absolute path to the LXD executable
+	IdmapSet        *idmap.IdmapSet // Information about user/group ID mapping
+	InotifyWatch    InotifyInfo
+	LxcPath         string // Path to the $LXD_DIR/containers directory
+	MockMode        bool   // If true some APIs will be mocked (for testing)
+	RunningInUserNS bool
+
+	// Apparmor features
+	AppArmorAdmin     bool
+	AppArmorAvailable bool
+	AppArmorConfined  bool
+	AppArmorStacked   bool
+	AppArmorStacking  bool
+
+	// Cgroup features
 	CGroupBlkioController   bool
-	CGroupCPUController     bool
 	CGroupCPUacctController bool
+	CGroupCPUController     bool
 	CGroupCPUsetController  bool
 	CGroupDevicesController bool
 	CGroupFreezerController bool
@@ -57,14 +64,13 @@ type OS struct {
 	CGroupNetPrioController bool
 	CGroupPidsController    bool
 	CGroupSwapAccounting    bool
-	InotifyWatch            InotifyInfo
-	NetnsGetifaddrs         bool
-	UeventInjection         bool
-	SeccompListener         bool
-	VFS3Fscaps              bool
-	Shiftfs                 bool
-
-	MockMode bool // If true some APIs will be mocked (for testing)
+
+	// Kernel features
+	NetnsGetifaddrs bool
+	SeccompListener bool
+	Shiftfs         bool
+	UeventInjection bool
+	VFS3Fscaps      bool
 }
 
 // DefaultOS returns a fresh uninitialized OS instance with default values.

From 22650cc76949432a98c822e47ff1450881b965f9 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Wed, 8 May 2019 11:50:07 +0100
Subject: [PATCH 2/5] lxd/api: Add lxc_features to /1.0

Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
 lxd/api_1.0.go |  7 +++++++
 lxd/daemon.go  | 11 +++++++++++
 lxd/sys/os.go  |  3 +++
 3 files changed, 21 insertions(+)

diff --git a/lxd/api_1.0.go b/lxd/api_1.0.go
index f06cd18384..c794c2ff6f 100644
--- a/lxd/api_1.0.go
+++ b/lxd/api_1.0.go
@@ -211,6 +211,13 @@ func api10Get(d *Daemon, r *http.Request) Response {
 		"shiftfs":            fmt.Sprintf("%v", d.os.Shiftfs),
 	}
 
+	if d.os.LXCFeatures != nil {
+		env.LXCFeatures = map[string]string{}
+		for k, v := range d.os.LXCFeatures {
+			env.LXCFeatures[k] = fmt.Sprintf("%v", v)
+		}
+	}
+
 	drivers := readStoragePoolDriversCache()
 	for driver, version := range drivers {
 		if env.Storage != "" {
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 3f9d572a7d..966c562baf 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -21,6 +21,7 @@ import (
 	"github.com/gorilla/mux"
 	"github.com/pkg/errors"
 	"golang.org/x/net/context"
+	"gopkg.in/lxc/go-lxc.v2"
 	"gopkg.in/macaroon-bakery.v2/bakery"
 	"gopkg.in/macaroon-bakery.v2/bakery/checkers"
 	"gopkg.in/macaroon-bakery.v2/bakery/identchecker"
@@ -576,6 +577,16 @@ func (d *Daemon) init() error {
 		logger.Infof(" - shiftfs support: no")
 	}
 
+	// Detect LXC features
+	d.os.LXCFeatures = map[string]bool{}
+	lxcExtensions := []string{
+		"mount_injection_file",
+		"seccomp_notify",
+	}
+	for _, extension := range lxcExtensions {
+		d.os.LXCFeatures[extension] = lxc.HasApiExtension(extension)
+	}
+
 	/* Initialize the database */
 	dump, err := initializeDbObject(d)
 	if err != nil {
diff --git a/lxd/sys/os.go b/lxd/sys/os.go
index a880b71214..8a507f99d7 100644
--- a/lxd/sys/os.go
+++ b/lxd/sys/os.go
@@ -71,6 +71,9 @@ type OS struct {
 	Shiftfs         bool
 	UeventInjection bool
 	VFS3Fscaps      bool
+
+	// LXC features
+	LXCFeatures map[string]bool
 }
 
 // DefaultOS returns a fresh uninitialized OS instance with default values.

From 55292f1d3418f05ff4d9c0cd9c7c3f9354cf1c86 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 8 May 2019 17:11:40 -0400
Subject: [PATCH 3/5] api: Add lxc_features extension
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>
---
 doc/api-extensions.md | 5 +++++
 shared/version/api.go | 1 +
 2 files changed, 6 insertions(+)

diff --git a/doc/api-extensions.md b/doc/api-extensions.md
index d1d803ca77..4320b8509f 100644
--- a/doc/api-extensions.md
+++ b/doc/api-extensions.md
@@ -757,3 +757,8 @@ migration is required.
 If the kernel supports seccomp-based syscall interception LXD can be notified
 by a container that a registered syscall has been performed. LXD can then
 decide to trigger various actions.
+
+## lxc\_features
+This introduces the `lxc_features` section output from the `lxc info` command
+via the `GET /1.0/` route. It outputs the result of checks for key features being present in the
+underlying LXC library.
diff --git a/shared/version/api.go b/shared/version/api.go
index 8a0ee9b1fb..2064b6f86e 100644
--- a/shared/version/api.go
+++ b/shared/version/api.go
@@ -152,6 +152,7 @@ var APIExtensions = []string{
 	"rbac",
 	"cluster_internal_copy",
 	"seccomp_notify",
+	"lxc_features",
 }
 
 // APIExtensionsCount returns the number of available API extensions.

From 772ef987fe487d23b84fd6f2453193897f722b79 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 8 May 2019 17:12:46 -0400
Subject: [PATCH 4/5] shared/api: Add lxc_features
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>
---
 shared/api/server.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/shared/api/server.go b/shared/api/server.go
index b2d961179f..c40b44e410 100644
--- a/shared/api/server.go
+++ b/shared/api/server.go
@@ -16,6 +16,9 @@ type ServerEnvironment struct {
 
 	KernelVersion string `json:"kernel_version" yaml:"kernel_version"`
 
+	// API extension: lxc_features
+	LXCFeatures map[string]string `json:"lxc_features" yaml:"lxc_features"`
+
 	// API extension: projects
 	Project string `json:"project" yaml:"project"`
 

From 080b481baf9482f251eaffa6f122c32024e0c48e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 8 May 2019 17:18:02 -0400
Subject: [PATCH 5/5] lxd: Port from HasApiExtension to LXCFeatures
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/container_lxc.go | 8 ++++----
 lxd/seccomp.go       | 5 ++---
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 508a8db697..995b48961d 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -1802,7 +1802,7 @@ func (c *containerLXC) initLXC(config bool) error {
 	}
 
 	// Setup shmounts
-	if lxc.HasApiExtension("mount_injection_file") {
+	if c.state.OS.LXCFeatures["mount_injection_file"] {
 		err = lxcSetConfigItem(cc, "lxc.mount.auto", fmt.Sprintf("shmounts:%s:/dev/.lxd-mounts", c.ShmountsPath()))
 	} else {
 		err = lxcSetConfigItem(cc, "lxc.mount.entry", fmt.Sprintf("%s dev/.lxd-mounts none bind,create=dir 0 0", c.ShmountsPath()))
@@ -1811,7 +1811,7 @@ func (c *containerLXC) initLXC(config bool) error {
 		return err
 	}
 
-	if !c.IsPrivileged() && !c.state.OS.RunningInUserNS && lxc.HasApiExtension("seccomp_notify") && c.DaemonState().OS.SeccompListener {
+	if !c.IsPrivileged() && !c.state.OS.RunningInUserNS && c.state.OS.LXCFeatures["seccomp_notify"] && c.DaemonState().OS.SeccompListener {
 		// NOTE: Don't fail in cases where liblxc is recent enough but libseccomp isn't
 		//       when we add mount() support with user-configurable
 		//       options, we will want a hard fail if the user configured it
@@ -6604,7 +6604,7 @@ func (c *containerLXC) insertMount(source, target, fstype string, flags int) err
 		return fmt.Errorf("Can't insert mount into stopped container")
 	}
 
-	if lxc.HasApiExtension("mount_injection_file") {
+	if c.state.OS.LXCFeatures["mount_injection_file"] {
 		cname := projectPrefix(c.Project(), c.Name())
 		configPath := filepath.Join(c.LogPath(), "lxc.conf")
 		if fstype == "" {
@@ -6672,7 +6672,7 @@ func (c *containerLXC) removeMount(mount string) error {
 		return fmt.Errorf("Can't remove mount from stopped container")
 	}
 
-	if lxc.HasApiExtension("mount_injection_file") {
+	if c.state.OS.LXCFeatures["mount_injection_file"] {
 		configPath := filepath.Join(c.LogPath(), "lxc.conf")
 		cname := projectPrefix(c.Project(), c.Name())
 
diff --git a/lxd/seccomp.go b/lxd/seccomp.go
index 90a934a750..a20afe4dfb 100644
--- a/lxd/seccomp.go
+++ b/lxd/seccomp.go
@@ -15,8 +15,6 @@ import (
 
 	"golang.org/x/sys/unix"
 
-	"gopkg.in/lxc/go-lxc.v2"
-
 	"github.com/lxc/lxd/lxd/util"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logger"
@@ -253,7 +251,8 @@ func getSeccompProfileContent(c container) (string, error) {
 		policy += DEFAULT_SECCOMP_POLICY
 	}
 
-	if !c.IsPrivileged() && !c.DaemonState().OS.RunningInUserNS && lxc.HasApiExtension("seccomp_notify") && c.DaemonState().OS.SeccompListener {
+	os := c.DaemonState().OS
+	if !c.IsPrivileged() && !os.RunningInUserNS && os.LXCFeatures["seccomp_notify"] && os.SeccompListener {
 		policy += SECCOMP_NOTIFY_POLICY
 	}
 


More information about the lxc-devel mailing list