[lxc-devel] [lxc/lxc] 26ea55: conf: fix block-device based rootfs mounting

2020-12-14 Thread Stéphane Graber
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: 26ea5533c941baee14923dfc3edfb9c91666d245
  https://github.com/lxc/lxc/commit/26ea5533c941baee14923dfc3edfb9c91666d245
  Author: Christian Brauner 
  Date:   2020-12-14 (Mon, 14 Dec 2020)

  Changed paths:
M src/lxc/conf.c

  Log Message:
  ---
  conf: fix block-device based rootfs mounting

Fixes: #3598
Cc: stable-4.0
Signed-off-by: Christian Brauner 


  Commit: 8a0e2272ac584b0af8febf26772f11a2d8396a6d
  https://github.com/lxc/lxc/commit/8a0e2272ac584b0af8febf26772f11a2d8396a6d
  Author: Stéphane Graber 
  Date:   2020-12-14 (Mon, 14 Dec 2020)

  Changed paths:
M src/lxc/conf.c

  Log Message:
  ---
  Merge pull request #3601 from brauner/2020-12-14/bugfixes

conf: fix block-device based rootfs mounting


Compare: https://github.com/lxc/lxc/compare/970c8d964db6...8a0e2272ac58
___
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel


[lxc-devel] [lxc/master] Support nftables using symbolic links to run nftables commands in legacy mode

2020-12-14 Thread comannnnndooooo on Github
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/3602

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) ===
This implementation uses the update-alternatives command to set nftables to be running in legacy mode when iptables commands need to be run. Then unsets the symbolic link after finishing the ensure there's no unintended behavior afterwards.
From ed53286daf4dec3668fa23410d2aeaff2e5498a8 Mon Sep 17 00:00:00 2001
From: Kyle Colburn 
Date: Mon, 14 Dec 2020 19:24:30 -0600
Subject: [PATCH] Used symbolic links to run nftables in legacy mode to support
 iptables commands when nftables is present.

Signed-off-by: Kyle Colburn 
---
 config/init/common/lxc-net.in | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/config/init/common/lxc-net.in b/config/init/common/lxc-net.in
index a7dfa6f199..ea4732669a 100644
--- a/config/init/common/lxc-net.in
+++ b/config/init/common/lxc-net.in
@@ -91,6 +91,11 @@ start() {
 
 _ifup
 
+nftables_ver_output=$(nft --version)
+if [$nftables_ver_output != *"not found"*]; then
+update-alternatives --set iptables /usr/sbin/iptables-legacy
+fi
+
 LXC_IPV6_ARG=""
 if [ -n "$LXC_IPV6_ADDR" ] && [ -n "$LXC_IPV6_MASK" ] && [ -n 
"$LXC_IPV6_NETWORK" ]; then
 echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
@@ -110,6 +115,10 @@ start() {
 iptables $use_iptables_lock -t nat -A POSTROUTING -s ${LXC_NETWORK} ! -d 
${LXC_NETWORK} -j MASQUERADE
 iptables $use_iptables_lock -t mangle -A POSTROUTING -o ${LXC_BRIDGE} -p 
udp -m udp --dport 68 -j CHECKSUM --checksum-fill
 
+if [$nftables_ver_output != *"not found"*]; then
+update-alternatives --remove iptables /usr/sbin/iptables-legacy
+fi
+
 LXC_DOMAIN_ARG=""
 if [ -n "$LXC_DOMAIN" ]; then
 LXC_DOMAIN_ARG="-s $LXC_DOMAIN -S /$LXC_DOMAIN/"
@@ -152,6 +161,12 @@ stop() {
 
 if [ -d /sys/class/net/${LXC_BRIDGE} ]; then
 _ifdown 
+
+nftables_ver_output=$(nft --version)
+if [$nftables_ver_output != *"not found"*]; then
+update-alternatives --set iptables /usr/sbin/iptables-legacy
+fi
+
 iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 
67 -j ACCEPT
 iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p tcp --dport 
67 -j ACCEPT
 iptables $use_iptables_lock -D INPUT -i ${LXC_BRIDGE} -p udp --dport 
53 -j ACCEPT
@@ -165,6 +180,10 @@ stop() {
 ip6tables $use_iptables_lock -t nat -D POSTROUTING -s 
${LXC_IPV6_NETWORK} ! -d ${LXC_IPV6_NETWORK} -j MASQUERADE
 fi
 
+if [$nftables_ver_output != *"not found"*]; then
+update-alternatives --remove iptables /usr/sbin/iptables-legacy
+fi
+
 pid=`cat "${varrun}"/dnsmasq.pid 2>/dev/null` && kill -9 $pid
 rm -f "${varrun}"/dnsmasq.pid
 # if $LXC_BRIDGE has attached interfaces, don't destroy the bridge
___
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel


[lxc-devel] [pylxd/master] Update version to 2.3.0a1

2020-12-14 Thread albertodonato on Github
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/pylxd/pull/442

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) ===
Signed-off-by: Alberto Donato 
From 2a9d182ae3239fa59a883f10caa04c932c77839e Mon Sep 17 00:00:00 2001
From: Alberto Donato 
Date: Mon, 14 Dec 2020 18:18:59 +0100
Subject: [PATCH] Update version to 2.3.0a1

Signed-off-by: Alberto Donato 
---
 setup.cfg | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.cfg b/setup.cfg
index 994ee92c..f41812f9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = pylxd
-version = 2.2.12
+version = 2.3.0a1
 description = python library for LXD
 long_description = file: README.rst
 author = Paul Hummer and others (see CONTRIBUTORS.rst)
___
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel


[lxc-devel] [lxc/master] conf: fix block-device based rootfs mounting

2020-12-14 Thread brauner on Github
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/3601

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) ===
Fixes: #3598
Cc: stable-4.0
Signed-off-by: Christian Brauner 
From 26ea5533c941baee14923dfc3edfb9c91666d245 Mon Sep 17 00:00:00 2001
From: Christian Brauner 
Date: Mon, 14 Dec 2020 17:52:44 +0100
Subject: [PATCH] conf: fix block-device based rootfs mounting

Fixes: #3598
Cc: stable-4.0
Signed-off-by: Christian Brauner 
---
 src/lxc/conf.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 9f631e0c23..27f9706687 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3135,6 +3135,10 @@ int lxc_setup_rootfs_prepare_root(struct lxc_conf *conf, 
const char *name,
if (ret < 0)
return log_error(-1, "Failed to bind mount container / 
onto itself");
 
+   conf->rootfs.mntpt_fd = openat(-EBADF, path, O_RDONLY | 
O_CLOEXEC | O_DIRECTORY | O_PATH | O_NOCTTY);
+   if (conf->rootfs.mntpt_fd < 0)
+   return log_error_errno(-errno, errno, "Failed to open 
file descriptor for container rootfs");
+
return log_trace(0, "Bind mounted container / onto itself");
}
 
___
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel


[lxc-devel] [lxd/master] Fixes to code quality

2020-12-14 Thread de-sh on Github
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8251

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) ===
Hey folks, 
I recently ran the [DeepSource](https://deepsource.io) static analyser on the lxd code repository, and it [generated this report]([https://deepsource.io/gh/de-sh/lxd](https://deepsource.io/gh/de-sh/lxd)) that I think you should check out!

I am opening this PR to fix a few of the highlighted issues, as mentioned below:
- Omit comparison with boolean constant
- Remove unnecessary fmt.Sprintf() on string
- Replace .Sub(time.Now()) with time.Until() handler
- Use result of type assertion to simplify cases
- Add .deepsource.toml
From c731e3e5ae3af292f15aa7e6e9cf8425a715c813 Mon Sep 17 00:00:00 2001
From: Devdutt Shenoi 
Date: Sat, 12 Dec 2020 21:54:56 +0530
Subject: [PATCH 1/5] Add DeepSource config

Signed-off-by: Devdutt Shenoi 
---
 .deepsource.toml | 20 
 1 file changed, 20 insertions(+)
 create mode 100644 .deepsource.toml

diff --git a/.deepsource.toml b/.deepsource.toml
new file mode 100644
index 00..8588c35be6
--- /dev/null
+++ b/.deepsource.toml
@@ -0,0 +1,20 @@
+version = 1
+
+test_patterns = [
+"test/**",
+"*_test.go"
+]
+
+[[analyzers]]
+name = "python"
+enabled = true
+
+  [analyzers.meta]
+  runtime_version = "3.x.x"
+
+[[analyzers]]
+name = "go"
+enabled = true
+
+  [analyzers.meta]
+  import_paths = ["github.com/lxd/lxd"]
\ No newline at end of file

From 8d6f3f891766ee0b41eee498d5be9cc22adf7c31 Mon Sep 17 00:00:00 2001
From: Devdutt Shenoi 
Date: Sat, 12 Dec 2020 21:55:56 +0530
Subject: [PATCH 2/5] Use result of type assertion to simplify cases

Signed-off-by: Devdutt Shenoi 
---
 client/lxd.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/client/lxd.go b/client/lxd.go
index 220f7bc900..77ec3e80f7 100644
--- a/client/lxd.go
+++ b/client/lxd.go
@@ -179,10 +179,10 @@ func (r *ProtocolLXD) rawQuery(method string, url string, 
data interface{}, ETag
 
// Get a new HTTP request setup
if data != nil {
-   switch data.(type) {
+   switch data := data.(type) {
case io.Reader:
// Some data to be sent along with the request
-   req, err = http.NewRequest(method, url, 
data.(io.Reader))
+   req, err = http.NewRequest(method, url, data)
if err != nil {
return nil, "", err
}

From 584599931a5759911c1a9226b2ea8a64199b543a Mon Sep 17 00:00:00 2001
From: Devdutt Shenoi 
Date: Sat, 12 Dec 2020 21:56:28 +0530
Subject: [PATCH 3/5] Replace .Sub(time.Now()) with time.Until() handler

Signed-off-by: Devdutt Shenoi 
---
 lxc/utils/progress.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxc/utils/progress.go b/lxc/utils/progress.go
index 1a548d7539..815354f2bb 100644
--- a/lxc/utils/progress.go
+++ b/lxc/utils/progress.go
@@ -83,7 +83,7 @@ func (p *ProgressRenderer) Done(msg string) {
 // Update changes the status message to the provided string
 func (p *ProgressRenderer) Update(status string) {
// Wait if needed
-   timeout := p.wait.Sub(time.Now())
+   timeout := time.Until(p.wait)
if timeout.Seconds() > 0 {
time.Sleep(timeout)
}

From 07828469f9c6520ef07a48905483832c6fcec495 Mon Sep 17 00:00:00 2001
From: Devdutt Shenoi 
Date: Sat, 12 Dec 2020 21:56:58 +0530
Subject: [PATCH 4/5] Remove unnecessary fmt.Sprintf() on string

Signed-off-by: Devdutt Shenoi 
---
 lxc/query.go  | 2 +-
 lxc/utils/progress.go | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxc/query.go b/lxc/query.go
index 29e58de88a..498b93d9cb 100644
--- a/lxc/query.go
+++ b/lxc/query.go
@@ -55,7 +55,7 @@ func (c *cmdQuery) pretty(input interface{}) string {
return fmt.Sprintf("%v", input)
}
 
-   return fmt.Sprintf("%s", pretty.String())
+   return pretty.String()
 }
 
 func (c *cmdQuery) Run(cmd *cobra.Command, args []string) error {
diff --git a/lxc/utils/progress.go b/lxc/utils/progress.go
index 815354f2bb..9b7ef1892d 100644
--- a/lxc/utils/progress.go
+++ b/lxc/utils/progress.go
@@ -153,7 +153,7 @@ func (p *ProgressRenderer) Warn(status string, timeout 
time.Duration) {
 
// Render the new message
p.wait = time.Now().Add(timeout)
-   msg := fmt.Sprintf("%s", status)
+   msg := status
 
// Truncate msg to terminal length
msg = "\r" + p.truncate(msg)

From efd22b81c3741d0d30bae86ea9e6151371240bb1 Mon Sep 17 00:00:00 2001
From: Devdutt Shenoi 
Date: Sat, 12 Dec 2020 21:57:31 +0530
Subject: [PATCH 5/5] Omit comparison with boolean constant

Signed-off-by: Devdutt Shenoi 
---
 lxc/delete.go | 2 +-
 lxc/image.go  | 2 +-

[lxc-devel] [lxd/master] Storage: Clustering state avoid duplicate global config when doing re-create

2020-12-14 Thread tomponline on Github
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/8250

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) ===
- Restructures storage pool creation to align with network creation process.
- Adds detection for duplicate storage pool config.
- Adds rejection of global config when performing a storage pool re-create attempt.
- Reinstates the Errored storage pool status so that we can detect re-create attempts even when no global config supplied.
From f5d6d54f2b257002e100e989faeb651c9ba02cdb Mon Sep 17 00:00:00 2001
From: Thomas Parrott 
Date: Fri, 11 Dec 2020 17:19:49 +
Subject: [PATCH 01/32] lxd/db/networks: Adds duplicate key detection to
 getNetworkConfig

Signed-off-by: Thomas Parrott 
---
 lxd/db/networks.go | 5 +
 1 file changed, 5 insertions(+)

diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index dece3638a6..e6f75119ca 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -670,6 +670,11 @@ func (c *Cluster) getNetworkConfig(id int64) 
(map[string]string, error) {
key = r[0].(string)
value = r[1].(string)
 
+   _, found := config[key]
+   if found {
+   return nil, fmt.Errorf("Duplicate config row found for 
key %q for network ID %d", key, id)
+   }
+
config[key] = value
}
 

From 849aabe23e60d7186a9f56c93606f903297da988 Mon Sep 17 00:00:00 2001
From: Thomas Parrott 
Date: Mon, 14 Dec 2020 10:06:57 +
Subject: [PATCH 02/32] lxd/db/networks: Adds NetworkErrored function

Signed-off-by: Thomas Parrott 
---
 lxd/db/networks.go | 5 +
 1 file changed, 5 insertions(+)

diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index e6f75119ca..dbc6e93a14 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -323,6 +323,11 @@ func (c *ClusterTx) NetworkCreated(project string, name 
string) error {
return c.networkState(project, name, networkCreated)
 }
 
+// NetworkErrored sets the state of the given network to networkErrored.
+func (c *ClusterTx) NetworkErrored(project string, name string) error {
+   return c.networkState(project, name, networkErrored)
+}
+
 func (c *ClusterTx) networkState(project string, name string, state 
NetworkState) error {
stmt := "UPDATE networks SET state=? WHERE project_id = (SELECT id FROM 
projects WHERE name = ?) AND name=?"
result, err := c.tx.Exec(stmt, state, project, name)

From ffc6845170d5e31b6df042a052c2518b4e464c83 Mon Sep 17 00:00:00 2001
From: Thomas Parrott 
Date: Mon, 14 Dec 2020 10:07:11 +
Subject: [PATCH 03/32] lxd/db/networks: Changes UpdateNetwork to not set
 created status

We shouldn't be allowing updates on non-created networks anyway.

Signed-off-by: Thomas Parrott 
---
 lxd/db/networks.go | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/lxd/db/networks.go b/lxd/db/networks.go
index dbc6e93a14..a675b01f0c 100644
--- a/lxd/db/networks.go
+++ b/lxd/db/networks.go
@@ -725,7 +725,7 @@ func (c *Cluster) CreateNetwork(projectName string, name 
string, description str
 
 // UpdateNetwork updates the network with the given name.
 func (c *Cluster) UpdateNetwork(project string, name, description string, 
config map[string]string) error {
-   id, netInfo, _, err := c.GetNetworkInAnyState(project, name)
+   id, _, _, err := c.GetNetworkInAnyState(project, name)
if err != nil {
return err
}
@@ -736,14 +736,6 @@ func (c *Cluster) UpdateNetwork(project string, name, 
description string, config
return err
}
 
-   // Update network status if change applied successfully.
-   if netInfo.Status == api.NetworkStatusErrored {
-   err = tx.NetworkCreated(project, name)
-   if err != nil {
-   return err
-   }
-   }
-
return nil
})
 

From 9f070059265055cbf509e0b75c78a04315e2fa67 Mon Sep 17 00:00:00 2001
From: Thomas Parrott 
Date: Fri, 11 Dec 2020 17:20:04 +
Subject: [PATCH 04/32] lxd/network/driver/ovn: Reject instance port start if
 cannot find DHCP options

Signed-off-by: Thomas Parrott 
---
 lxd/network/driver_ovn.go | 8 
 1 file changed, 8 insertions(+)

diff --git a/lxd/network/driver_ovn.go b/lxd/network/driver_ovn.go
index 4d7a6a3851..6cd162accb 100644
--- a/lxd/network/driver_ovn.go
+++ b/lxd/network/driver_ovn.go
@@ -2151,6 +2151,10 @@ func (n *ovn) InstanceDevicePortAdd(instanceUUID string, 
instanceName string, de
if err != nil {
return "", err
}
+
+   if dhcpV4ID == "" {
+   return "", fmt.Errorf("Could not find DHCPv4 options 
for instance port")
+ 

[lxc-devel] [lxc/lxc] e8b9c9: unmounted proc/sys/net if dropping CAP_NET_ADMIN

2020-12-14 Thread Christian Brauner
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: e8b9c9ec6fb99e32a9d9efacf8c1f6694a2341c4
  https://github.com/lxc/lxc/commit/e8b9c9ec6fb99e32a9d9efacf8c1f6694a2341c4
  Author: zhenr667 <44516803+zhenr...@users.noreply.github.com>
  Date:   2020-12-13 (Sun, 13 Dec 2020)

  Changed paths:
M src/lxc/conf.c

  Log Message:
  ---
  unmounted proc/sys/net if dropping CAP_NET_ADMIN
Signed-off-by: Henry Zhang 


  Commit: 970c8d964db64bb2cd6814fe2e37d3ab3783661f
  https://github.com/lxc/lxc/commit/970c8d964db64bb2cd6814fe2e37d3ab3783661f
  Author: Christian Brauner 
  Date:   2020-12-14 (Mon, 14 Dec 2020)

  Changed paths:
M src/lxc/conf.c

  Log Message:
  ---
  Merge pull request #3600 from zhenr667/3091

unmounted proc/sys/net by dropping CAP_NET_ADMIN


Compare: https://github.com/lxc/lxc/compare/3aa3407f34c3...970c8d964db6
___
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel


[lxc-devel] [pylxd/master] add support for Network.state()

2020-12-14 Thread albertodonato on Github
The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/pylxd/pull/441

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 1485daefc9eacffe915361207db4bc3b97bdb83f Mon Sep 17 00:00:00 2001
From: Alberto Donato 
Date: Mon, 14 Dec 2020 12:52:05 +0100
Subject: [PATCH 1/2] Extract InstanceState logic to AttributeDict

Signed-off-by: Alberto Donato 
---
 pylxd/models/_model.py   | 12 
 pylxd/models/instance.py |  8 ++--
 pylxd/tests/models/test_model.py | 12 
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/pylxd/models/_model.py b/pylxd/models/_model.py
index f05f4eae..65d3a11d 100644
--- a/pylxd/models/_model.py
+++ b/pylxd/models/_model.py
@@ -13,12 +13,24 @@
 #under the License.
 import os
 import warnings
+from copy import deepcopy
 
 from pylxd import exceptions
 
 MISSING = object()
 
 
+class AttributeDict:
+"""Wrap a dict making keys accessible as attributes."""
+
+def __init__(self, dct):
+for key, value in dct.items():
+setattr(self, key, value)
+
+def _asdict(self):
+return deepcopy(self.__dict__)
+
+
 class Attribute:
 """A metadata class for model attributes."""
 
diff --git a/pylxd/models/instance.py b/pylxd/models/instance.py
index 01ed452b..afb748bd 100644
--- a/pylxd/models/instance.py
+++ b/pylxd/models/instance.py
@@ -34,13 +34,9 @@
 from pylxd.models.operation import Operation
 
 
-class InstanceState:
+class InstanceState(model.AttributeDict):
 """A simple object for representing instance state."""
 
-def __init__(self, **kwargs):
-for key, value in kwargs.items():
-setattr(self, key, value)
-
 
 _InstanceExecuteResult = collections.namedtuple(
 "InstanceExecuteResult", ["exit_code", "stdout", "stderr"]
@@ -357,7 +353,7 @@ def _set_state(self, state, timeout=30, force=True, 
wait=False):
 
 def state(self):
 response = self.api.state.get()
-state = InstanceState(**response.json()["metadata"])
+state = InstanceState(response.json()["metadata"])
 return state
 
 def start(self, timeout=30, force=True, wait=False):
diff --git a/pylxd/tests/models/test_model.py b/pylxd/tests/models/test_model.py
index 1b626132..cda5182f 100644
--- a/pylxd/tests/models/test_model.py
+++ b/pylxd/tests/models/test_model.py
@@ -33,6 +33,18 @@ class ChildItem(Item):
 """A fake model child class."""
 
 
+class TestAttributeDict:
+def test_from_dict(self):
+a = model.AttributeDict({"foo": "bar", "baz": "bza"})
+assert a.foo == "bar"
+assert a.baz == "bza"
+
+def test_as_dict(self):
+d = {"foo": "bar", "baz": "bza"}
+a = model.AttributeDict(d)
+assert a._asdict() == d
+
+
 class TestModel(testing.PyLXDTestCase):
 """Tests for pylxd.model.Model."""
 

From f414b151370a3652ef4159121b15e437137c68fe Mon Sep 17 00:00:00 2001
From: Alberto Donato 
Date: Mon, 14 Dec 2020 13:09:02 +0100
Subject: [PATCH 2/2] add Network.state()

Signed-off-by: Alberto Donato 
---
 pylxd/models/network.py| 10 
 pylxd/tests/models/test_network.py | 40 ++
 2 files changed, 50 insertions(+)

diff --git a/pylxd/models/network.py b/pylxd/models/network.py
index 61b3a0c8..84cdce59 100644
--- a/pylxd/models/network.py
+++ b/pylxd/models/network.py
@@ -16,6 +16,10 @@
 from pylxd.models import _model as model
 
 
+class NetworkState(model.AttributeDict):
+"""A simple object for representing a network state."""
+
+
 class Network(model.Model):
 """Model representing a LXD network."""
 
@@ -125,6 +129,12 @@ def save(self, *args, **kwargs):
 self.client.assert_has_api_extension("network")
 super().save(*args, **kwargs)
 
+def state(self):
+"""Get network state."""
+response = self.api.state.get()
+state = NetworkState(response.json()["metadata"])
+return state
+
 @property
 def api(self):
 return self.client.api.networks[self.name]
diff --git a/pylxd/tests/models/test_network.py 
b/pylxd/tests/models/test_network.py
index 3c67533b..148950f6 100644
--- a/pylxd/tests/models/test_network.py
+++ b/pylxd/tests/models/test_network.py
@@ -216,6 +216,46 @@ def test_delete(self):
 
 network.delete()
 
+def test_state(self):
+state = {
+"addresses": [
+{
+"family": "inet",
+"address": "10.87.252.1",
+"netmask": "24",
+"scope": "global",
+},
+{
+"family": "inet6",
+"address": "fd42:6e0e:6542:a212::1",
+"netmask": "64",
+"scope": "global",
+},
+],
+"co