Merge pull request #43 from monstermunchkin/issues/5-maas

Remove MAAS
This commit is contained in:
Stéphane Graber 2023-08-15 20:51:29 -04:00 committed by GitHub
commit e3f2c5d963
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 29 additions and 1128 deletions

View File

@ -126,7 +126,6 @@ LXC's
LXCFS
LXD
LXD's
MAAS
macOS
macvlan
Makefile

View File

@ -442,13 +442,6 @@ This adds support for optimized memory transfer during live migration.
This adds support to use InfiniBand network devices.
## `maas_network`
This adds support for MAAS network integration.
When configured at the daemon level, it's then possible to attach a `nic`
device to a particular MAAS subnet.
## `devlxd_events`
This adds a WebSocket API to the `devlxd` socket.

View File

@ -72,14 +72,6 @@ If set to `random`, use the random host interface name as the host name; if set
Stores the {ref}`clustering-instance-placement-scriptlet` for custom automatic instance placement logic
```
```{config:option} maas.api.key
:shortdesc: API key to manage MAAS
:type: string
:scope: global
API key to manage MAAS
```
Any other scope is also possible.
This scope shows that you can use formatting, mainly in the short description and the description, and the available options.
@ -135,7 +127,5 @@ Except for server options (default), you must specify the scope.
{config:option}`something:test1`
{config:option}`maas.api.key`
The index is here:
{ref}`config-options`

View File

@ -58,7 +58,6 @@ Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GiB of the new loop device (1GiB minimum) [default=9GiB]:
Do you want to configure a new remote storage pool? (yes/no) [default=no]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]:
Would you like to create a new Fan overlay network? (yes/no) [default=yes]:
What subnet should be used as the Fan underlay? [default=auto]:

View File

@ -26,12 +26,6 @@ Clustering (see {ref}`exp-clustering` and {ref}`cluster-form`)
The default answer is `no`, which means clustering is not enabled.
If you answer `yes`, you can either connect to an existing cluster or create one.
MAAS support (see [`maas.io`](https://maas.io/) and [MAAS - How to manage VM hosts](https://maas.io/docs/install-with-lxd))
: MAAS is an open-source tool that lets you build a data center from bare-metal servers.
The default answer is `no`, which means MAAS support is not enabled.
If you answer `yes`, you can connect to an existing MAAS server and specify the `name`, `URL` and `API key`.
Networking (see {ref}`networks` and {ref}`Network devices <devices-nic>`)
: Provides network access for the instances.

View File

@ -88,8 +88,6 @@ Key | Type | Default | Managed | Description
`limits.egress` | string | - | no | I/O limit in bit/s for outgoing traffic (various suffixes supported, see {ref}`instances-limit-units`)
`limits.ingress` | string | - | no | I/O limit in bit/s for incoming traffic (various suffixes supported, see {ref}`instances-limit-units`)
`limits.max` | string | - | no | I/O limit in bit/s for both incoming and outgoing traffic (same as setting both `limits.ingress` and `limits.egress`)
`maas.subnet.ipv4` | string | - | yes | MAAS IPv4 subnet to register the instance in
`maas.subnet.ipv6` | string | - | yes | MAAS IPv6 subnet to register the instance in
`mtu` | integer | parent MTU | yes | The MTU of the new interface
`name` | string | kernel assigned | no | The name of the interface inside the instance
`network` | string | - | no | The managed network to link the device to (instead of specifying the `nictype` directly)
@ -123,8 +121,6 @@ Key | Type | Default | Managed | Description
`boot.priority` | integer | - | no | Boot priority for VMs (higher value boots first)
`gvrp` | bool | `false` | no | Register VLAN using GARP VLAN Registration Protocol
`hwaddr` | string | randomly assigned | no | The MAC address of the new interface
`maas.subnet.ipv4` | string | - | yes | MAAS IPv4 subnet to register the instance in
`maas.subnet.ipv6` | string | - | yes | MAAS IPv6 subnet to register the instance in
`mtu` | integer | parent MTU | yes | The MTU of the new interface
`name` | string | kernel assigned | no | The name of the interface inside the instance
`network` | string | - | no | The managed network to link the device to (instead of specifying the `nictype` directly)
@ -167,8 +163,6 @@ Key | Type | Default | Managed | Description
:-- | :-- | :-- | :-- | :--
`boot.priority` | integer | - | no | Boot priority for VMs (higher value boots first)
`hwaddr` | string | randomly assigned | no | The MAC address of the new interface
`maas.subnet.ipv4` | string | - | yes | MAAS IPv4 subnet to register the instance in
`maas.subnet.ipv6` | string | - | yes | MAAS IPv6 subnet to register the instance in
`mtu` | integer | kernel assigned | yes | The MTU of the new interface
`name` | string | kernel assigned | no | The name of the interface inside the instance
`network` | string | - | no | The managed network to link the device to (instead of specifying the `nictype` directly)
@ -269,8 +263,6 @@ Key | Type | Default | Managed | Description
`boot.priority` | integer | - | no | Boot priority for VMs (higher value boots first)
`gvrp` | bool | `false` | no | Register VLAN using GARP VLAN Registration Protocol
`hwaddr` | string | randomly assigned | no | The MAC address of the new interface
`maas.subnet.ipv4` | string | - | no | MAAS IPv4 subnet to register the instance in
`maas.subnet.ipv6` | string | - | no | MAAS IPv6 subnet to register the instance in
`mtu` | integer | parent MTU | no | The MTU of the new interface
`name` | string | kernel assigned | no | The name of the interface inside the instance
`network` | string | - | no | The managed network to link the device to (instead of specifying the `nictype` directly)
@ -465,13 +457,3 @@ In such case, a `bridge` device is preferable.
A bridge also lets you use MAC filtering and I/O limits, which cannot be applied to a `macvlan` device.
`ipvlan` is similar to `macvlan`, with the difference being that the forked device has IPs statically assigned to it and inherits the parent's MAC address on the network.
## MAAS integration
If you're using MAAS to manage the physical network under your LXD host and want to attach your instances directly to a MAAS-managed network, LXD can be configured to interact with MAAS so that it can track your instances.
At the daemon level, you must configure `maas.api.url` and `maas.api.key`, and then set the `maas.subnet.ipv4` and/or `maas.subnet.ipv6` keys on the instance or profile's `nic` entry.
With this configuration, LXD registers all your instances with MAAS, giving them proper DHCP leases and DNS records.
If you set the `ipv4.address` or `ipv6.address` keys on the NIC, those are registered as static assignments in MAAS.

View File

@ -46,7 +46,6 @@ The following configuration key namespaces are currently supported for the `brid
- `fan` (configuration specific to the Ubuntu FAN overlay)
- `ipv4` (L3 IPv4 configuration)
- `ipv6` (L3 IPv6 configuration)
- `maas` (MAAS network identification)
- `security` (network ACL configuration)
- `raw` (raw configuration file content)
- `tunnel` (cross-host tunneling configuration)
@ -104,8 +103,6 @@ Key | Type | Condition | Defau
`ipv6.ovn.ranges` | string | - | - | Comma-separated list of IPv6 ranges to use for child OVN network routers (FIRST-LAST format)
`ipv6.routes` | string | IPv6 address | - | Comma-separated list of additional IPv6 CIDR subnets to route to the bridge
`ipv6.routing` | bool | IPv6 address | `true` | Whether to route traffic in and out of the bridge
`maas.subnet.ipv4` | string | IPv4 address | - | MAAS IPv4 subnet to register instances in (when using `network` property on NIC)
`maas.subnet.ipv6` | string | IPv6 address | - | MAAS IPv6 subnet to register instances in (when using `network` property on NIC)
`raw.dnsmasq` | string | - | - | Additional `dnsmasq` configuration to append to the configuration file
`security.acls` | string | - | - | Comma-separated list of Network ACLs to apply to NICs connected to this network (see {ref}`network-acls-bridge-limitations`)
`security.acls.default.egress.action`| string | `security.acls` | `reject` | Action to use for egress traffic that doesn't match any ACL rule

View File

@ -19,7 +19,6 @@ Both the host and the instances can talk to the gateway, but they cannot communi
The following configuration key namespaces are currently supported for the `macvlan` network type:
- `maas` (MAAS network identification)
- `user` (free-form key/value for user metadata)
```{note}
@ -34,6 +33,4 @@ Key | Type | Condition | Default
`mtu` | integer | - | - | The MTU of the new interface
`parent` | string | - | - | Parent interface to create `macvlan` NICs on
`vlan` | integer | - | - | The VLAN ID to attach to
`maas.subnet.ipv4` | string | IPv4 address | - | MAAS IPv4 subnet to register instances in (when using `network` property on NIC)
`maas.subnet.ipv6` | string | IPv6 address | - | MAAS IPv6 subnet to register instances in (when using `network` property on NIC)
`user.*` | string | - | - | User-provided free-form key/value pairs

View File

@ -17,7 +17,6 @@ The following configuration key namespaces are currently supported for the `phys
- `dns` (DNS server and resolution configuration)
- `ipv4` (L3 IPv4 configuration)
- `ipv6` (L3 IPv6 configuration)
- `maas` (MAAS network identification)
- `ovn` (OVN configuration)
- `user` (free-form key/value for user metadata)
@ -46,8 +45,6 @@ Key | Type | Condition | Default
`ipv6.ovn.ranges` | string | - | - | Comma-separated list of IPv6 ranges to use for child OVN network routers (FIRST-LAST format)
`ipv6.routes` | string | IPv6 address | - | Comma-separated list of additional IPv6 CIDR subnets that can be used with child OVN networks `ipv6.routes.external` setting
`ipv6.routes.anycast` | bool | IPv6 address | `false` | Allow the overlapping routes to be used on multiple networks/NIC at the same time
`maas.subnet.ipv4` | string | IPv4 address | - | MAAS IPv4 subnet to register instances in (when using `network` property on NIC)
`maas.subnet.ipv6` | string | IPv6 address | - | MAAS IPv6 subnet to register instances in (when using `network` property on NIC)
`ovn.ingress_mode` | string | standard mode | `l2proxy` | Sets the method how OVN NIC external IPs will be advertised on uplink network: `l2proxy` (proxy ARP/NDP) or `routed`
`user.*` | string | - | - | User-provided free-form key/value pairs

View File

@ -13,7 +13,6 @@ In this case, the instance NICs can simply set the `network` option to the netwo
The following configuration key namespaces are currently supported for the `sriov` network type:
- `maas` (MAAS network identification)
- `user` (free-form key/value for user metadata)
```{note}
@ -27,6 +26,4 @@ Key | Type | Condition | Default
`mtu` | integer | - | - | The MTU of the new interface
`parent` | string | - | - | Parent interface to create `sriov` NICs on
`vlan` | integer | - | - | The VLAN ID to attach to
`maas.subnet.ipv4` | string | IPv4 address | - | MAAS IPv4 subnet to register instances in (when using `network` property on NIC)
`maas.subnet.ipv6` | string | IPv6 address | - | MAAS IPv6 subnet to register instances in (when using `network` property on NIC)
`user.*` | string | - | - | User-provided free-form key/value pairs

View File

@ -115,7 +115,7 @@ Key | Type | Scope | Default
(server-options-misc)=
## Miscellaneous options
The following server options configure server-specific settings for {ref}`instances`, MAAS integration, {ref}`OVN <network-ovn>` integration, {ref}`Backups <backups>` and {ref}`storage`:
The following server options configure server-specific settings for {ref}`instances`, {ref}`OVN <network-ovn>` integration, {ref}`Backups <backups>` and {ref}`storage`:
```{rst-class} break-col-4 min-width-4-8
```
@ -126,9 +126,6 @@ Key | Type | Scope | Default
`backups.compression_algorithm` | string | global | `gzip` | Compression algorithm to use for backups (`bzip2`, `gzip`, `lzma`, `xz` or `none`)
`instances.nic.host_name` | string | global | `random` | If set to `random`, use the random host interface name as the host name; if set to `mac`, generate a host name in the form `lxd<mac_address>` (MAC without leading two digits)
`instances.placement.scriptlet` | string | global | - | Stores the {ref}`clustering-instance-placement-scriptlet` for custom automatic instance placement logic
`maas.api.key` | string | global | - | API key to manage MAAS
`maas.api.url` | string | global | - | URL of the MAAS server
`maas.machine` | string | local | host name | Name of this LXD host in MAAS
`network.ovn.integration_bridge` | string | global | `br-int` | OVS integration bridge to use for OVN networks
`network.ovn.northbound_connection` | string | global | `unix:/var/run/ovn/ovnnb_db.sock` | OVN northbound database connection string
`storage.backups_volume` | string | local | - | Volume to use to store the backup tarballs (syntax is `POOL/VOLUME`)

8
go.mod
View File

@ -21,7 +21,6 @@ require (
github.com/j-keck/arping v1.0.3
github.com/jaypipes/pcidb v1.0.0
github.com/jochenvg/go-udev v0.0.0-20171110120927-d6b62d56d37b
github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/lxc/go-lxc v0.0.0-20230621012608-be98af2b8b9f
github.com/mattn/go-colorable v0.1.13
@ -80,12 +79,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jkeiser/iter v0.0.0-20200628201005-c8aa0ae784d1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/juju/collections v1.0.4 // indirect
github.com/juju/errors v1.0.0 // indirect
github.com/juju/loggo v1.0.0 // indirect
github.com/juju/mgo/v2 v2.0.2 // indirect
github.com/juju/schema v1.0.1 // indirect
github.com/juju/version v0.0.0-20210303051006-2015802527a8 // indirect
github.com/k-sone/critbitgo v1.4.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
@ -132,6 +125,5 @@ require (
google.golang.org/genproto/googleapis/rpc v0.0.0-20230807174057-1744710a1577 // indirect
google.golang.org/grpc v1.57.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
)

120
go.sum
View File

@ -40,10 +40,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-ntlmssp v0.0.0-20211209120228-48547f28849e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6/go.mod h1:nuWgzSkT5PnyOd+272uUmV0dnAnAn42Mk7PiQC5VzN4=
github.com/Rican7/retry v0.3.0/go.mod h1:CxSDrhAyXmTMeEuRAnArMu1FHu48vtfjLREWqVl7Vw0=
github.com/Rican7/retry v0.3.1 h1:scY4IbO8swckzoA/11HgBwaZRJEyY9vaNJshcdhp1Mc=
github.com/Rican7/retry v0.3.1/go.mod h1:CxSDrhAyXmTMeEuRAnArMu1FHu48vtfjLREWqVl7Vw0=
@ -74,7 +72,6 @@ github.com/cowsql/go-cowsql v1.21.0/go.mod h1:WkRYUxfUogdRwNmmqC/IZhfpKK8C/qR+kj
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -122,7 +119,6 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -207,7 +203,6 @@ github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gosexy/gettext v0.0.0-20160830220431-74466a0a0c4a h1:N2b2mb4Gki1SlF3WuhR9P1YHOpl7oy/b+xxX4A3iM2E=
@ -227,7 +222,6 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -246,12 +240,6 @@ github.com/j-keck/arping v1.0.3 h1:aeVk5WnsK6xPaRsFt5wV6W2x5l/n5XBNp0MMr/FEv2k=
github.com/j-keck/arping v1.0.3/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw=
github.com/jaypipes/pcidb v1.0.0 h1:vtZIfkiCUE42oYbJS0TAq9XSfSmcsgo9IdxSm9qzYU8=
github.com/jaypipes/pcidb v1.0.0/go.mod h1:TnYUvqhPBzCKnH34KrIX22kAeEbDCSRJ9cqLRCuNDfk=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc=
github.com/jkeiser/iter v0.0.0-20200628201005-c8aa0ae784d1 h1:smvLGU3obGU5kny71BtE/ibR0wIXRUiRFDmSn0Nxz1E=
github.com/jkeiser/iter v0.0.0-20200628201005-c8aa0ae784d1/go.mod h1:fP/NdyhRVOv09PLRbVXrSqHhrfQypdZwgE2L4h2U5C8=
@ -263,74 +251,6 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ansiterm v0.0.0-20160907234532-b99631de12cf/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/juju/ansiterm v0.0.0-20210706145210-9283cdf370b5/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA=
github.com/juju/clock v0.0.0-20220202072423-1b0f830854c4/go.mod h1:zDZCPSgCJQINeZtQwHx2/cFk4seaBC8Yiqe8V82xiP0=
github.com/juju/clock v0.0.0-20220203021603-d9deb868a28a/go.mod h1:GZ/FY8Cqw3KHG6DwRVPUKbSPTAwyrU28xFi5cqZnLsc=
github.com/juju/clock v1.0.0/go.mod h1:GZ/FY8Cqw3KHG6DwRVPUKbSPTAwyrU28xFi5cqZnLsc=
github.com/juju/clock v1.0.2 h1:dJFdUGjtR/76l6U5WLVVI/B3i6+u3Nb9F9s1m+xxrxo=
github.com/juju/cmd v0.0.0-20171107070456-e74f39857ca0/go.mod h1:yWJQHl73rdSX4DHVKGqkAip+huBslxRwS8m9CrOLq18=
github.com/juju/cmd/v3 v3.0.0-20220202061353-b1cc80b193b0/go.mod h1:EoGJiEG+vbMwO9l+Es0SDTlaQPjH6nLcnnc4NfZB3cY=
github.com/juju/collections v0.0.0-20200605021417-0d0ec82b7271/go.mod h1:5XgO71dV1JClcOJE+4dzdn4HrI5LiyKd7PlVG6eZYhY=
github.com/juju/collections v0.0.0-20220203020748-febd7cad8a7a/go.mod h1:JWeZdyttIEbkR51z2S13+J+aCuHVe0F6meRy+P0YGDo=
github.com/juju/collections v1.0.0/go.mod h1:JWeZdyttIEbkR51z2S13+J+aCuHVe0F6meRy+P0YGDo=
github.com/juju/collections v1.0.4 h1:GjL+aN512m2rVDqhPII7P6qB0e+iYFubz8sqBhZaZtk=
github.com/juju/collections v1.0.4/go.mod h1:hVrdB0Zwq9wIU1Fl6ItD2+UETeNeOEs+nGvJufVe+0c=
github.com/juju/errors v0.0.0-20150916125642-1b5e39b83d18/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/errors v0.0.0-20200330140219-3fe23663418f/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/errors v0.0.0-20210818161939-5560c4c073ff/go.mod h1:i1eL7XREII6aHpQ2gApI/v6FkVUDEBremNkcBCKYAcY=
github.com/juju/errors v0.0.0-20220203013757-bd733f3c86b9/go.mod h1:TRm7EVGA3mQOqSVcBySRY7a9Y1/gyVhh/WTCnc5sD4U=
github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM=
github.com/juju/errors v1.0.0/go.mod h1:B5x9thDqx0wIMH3+aLIMP9HjItInYWObRovoCFM5Qe8=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767 h1:b59sh8vHY7lke8eyoxKbGKmOM78DlyMtwQ7ryE3Tuuo=
github.com/juju/gomaasapi v0.0.0-20200602032615-aa561369c767/go.mod h1:ppx9XlnQMX/+h/kH+cU9kfDUT6GimqGtNRWdobUZVRE=
github.com/juju/httpprof v0.0.0-20141217160036-14bf14c30767/go.mod h1:+MaLYz4PumRkkyHYeXJ2G5g5cIW0sli2bOfpmbaMV/g=
github.com/juju/loggo v0.0.0-20170605014607-8232ab8918d9/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/loggo v0.0.0-20200526014432-9ce3a2e09b5e/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/loggo v0.0.0-20210728185423-eebad3a902c4/go.mod h1:NIXFioti1SmKAlKNuUwbMenNdef59IF52+ZzuOmHYkg=
github.com/juju/loggo v1.0.0 h1:Y6ZMQOGR9Aj3BGkiWx7HBbIx6zNwNkxhVNOHU2i1bl0=
github.com/juju/loggo v1.0.0/go.mod h1:NIXFioti1SmKAlKNuUwbMenNdef59IF52+ZzuOmHYkg=
github.com/juju/mgo/v2 v2.0.0-20210302023703-70d5d206e208/go.mod h1:0OChplkvPTZ174D2FYZXg4IB9hbEwyHkD+zT+/eK+Fg=
github.com/juju/mgo/v2 v2.0.0-20220111072304-f200228f1090/go.mod h1:N614SE0a4e+ih2rg96Vi2PeC3cTpUOWgCTv3Cgk974c=
github.com/juju/mgo/v2 v2.0.2 h1:ufYtW2OFNjniTuxOngecP3Mk5sSclo8Zl1mnmyGWUWA=
github.com/juju/mgo/v2 v2.0.2/go.mod h1:Z2QbXIrR9JuJcSyankQOw31tINNA5p3qevW73oDoHsM=
github.com/juju/mutex v0.0.0-20171110020013-1fe2a4bf0a3a/go.mod h1:Y3oOzHH8CQ0Ppt0oCKJ2JFO81/EsWenH5AEqigLH+yY=
github.com/juju/mutex/v2 v2.0.0-20220128011612-57176ebdcfa3/go.mod h1:TTCG9BJD9rCC4DZFz3jA0QvCqFDHw8Eqz0jstwY7RTQ=
github.com/juju/mutex/v2 v2.0.0-20220203023141-11eeddb42c6c/go.mod h1:jwCfBs/smYDaeZLqeaCi8CB8M+tOes4yf827HoOEoqk=
github.com/juju/retry v0.0.0-20151029024821-62c620325291/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4=
github.com/juju/retry v0.0.0-20180821225755-9058e192b216/go.mod h1:OohPQGsr4pnxwD5YljhQ+TZnuVRYpa5irjugL1Yuif4=
github.com/juju/retry v1.0.0/go.mod h1:SssN1eYeK3A2qjnFGTiVMbdzGJ2BfluaJblJXvuvgqA=
github.com/juju/schema v1.0.1 h1:GBEiwxZQeoQuXI6gOTG58W/ZpdongMwl9pfZq1KcNgM=
github.com/juju/schema v1.0.1/go.mod h1:Y+ThzXpUJ0E7NYYocAbuvJ7vTivXfrof/IfRPq/0abI=
github.com/juju/testing v0.0.0-20180402130637-44801989f0f7/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/juju/testing v0.0.0-20180517134105-72703b1e95eb/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/juju/testing v0.0.0-20190723135506-ce30eb24acd2/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/juju/testing v0.0.0-20210302031854-2c7ee8570c07/go.mod h1:7lxZW0B50+xdGFkvhAb8bwAGt6IU87JB1H9w4t8MNVM=
github.com/juju/testing v0.0.0-20210324180055-18c50b0c2098/go.mod h1:7lxZW0B50+xdGFkvhAb8bwAGt6IU87JB1H9w4t8MNVM=
github.com/juju/testing v0.0.0-20220202055744-1ad0816210a6/go.mod h1:QgWc2UdIPJ8t3rnvv95tFNOsQDfpXYEZDbP281o3b2c=
github.com/juju/testing v0.0.0-20220203020004-a0ff61f03494/go.mod h1:rUquetT0ALL48LHZhyRGvjjBH8xZaZ8dFClulKK5wK4=
github.com/juju/testing v1.0.0/go.mod h1:rUquetT0ALL48LHZhyRGvjjBH8xZaZ8dFClulKK5wK4=
github.com/juju/testing v1.0.2 h1:OR90RqCd9CJONxXamZAjLknpZdtqDyxqW8IwCbgw3i4=
github.com/juju/utils v0.0.0-20180424094159-2000ea4ff043/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk=
github.com/juju/utils v0.0.0-20200116185830-d40c2fe10647 h1:wQpkHVbIIpz1PCcLYku9KFWsJ7aEMQXHBBmLy3tRBTk=
github.com/juju/utils v0.0.0-20200116185830-d40c2fe10647/go.mod h1:6/KLg8Wz/y2KVGWEpkK9vMNGkOnu4k/cqs8Z1fKjTOk=
github.com/juju/utils/v2 v2.0.0-20200923005554-4646bfea2ef1/go.mod h1:fdlDtQlzundleLLz/ggoYinEt/LmnrpNKcNTABQATNI=
github.com/juju/utils/v3 v3.0.0-20220130232349-cd7ecef0e94a/go.mod h1:LzwbbEN7buYjySp4nqnti6c6olSqRXUk6RkbSUUP1n8=
github.com/juju/utils/v3 v3.0.0-20220202114721-338bb0530e89/go.mod h1:wf5w+8jyTh2IYnSX0sHnMJo4ZPwwuiBWn+xN3DkQg4k=
github.com/juju/utils/v3 v3.0.0-20220203023959-c3fbc78a33b0/go.mod h1:8csUcj1VRkfjNIRzBFWzLFCMLwLqsRWvkmhfVAUwbC4=
github.com/juju/utils/v3 v3.0.0 h1:Gg3n63mGPbBuoXCo+EPJuMi44hGZfloI8nlCIebHu2Q=
github.com/juju/utils/v3 v3.0.0/go.mod h1:8csUcj1VRkfjNIRzBFWzLFCMLwLqsRWvkmhfVAUwbC4=
github.com/juju/version v0.0.0-20161031051906-1f41e27e54f2/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U=
github.com/juju/version v0.0.0-20180108022336-b64dbd566305/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U=
github.com/juju/version v0.0.0-20191219164919-81c1be00b9a6/go.mod h1:kE8gK5X0CImdr7qpSKl3xB2PmpySSmfj7zVbkZFs81U=
github.com/juju/version v0.0.0-20210303051006-2015802527a8 h1:BTo6HzRR0zPBcXbs1Sy08aQNfvdm3ey8O+mBTiO3g00=
github.com/juju/version v0.0.0-20210303051006-2015802527a8/go.mod h1:YUOK6VK9+V4hpmsBYx8ymvOzEXRzoIGjRDKpIezTi60=
github.com/juju/version/v2 v2.0.0-20211007103408-2e8da085dc23/go.mod h1:Ljlbryh9sYaUSGXucslAEDf0A2XUSGvDbHJgW8ps6nc=
github.com/juju/version/v2 v2.0.0/go.mod h1:ZeFjNy+UFEWJDDPdzW7Cm9NeU6dsViGaFYhXzycLQrw=
github.com/julienschmidt/httprouter v1.1.1-0.20151013225520-77a895ad01eb/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/k-sone/critbitgo v1.4.0 h1:l71cTyBGeh6X5ATh6Fibgw3+rtNT80BA0uNNWgkPrbE=
github.com/k-sone/critbitgo v1.4.0/go.mod h1:7E6pyoyADnFxlUBEKcnfS49b7SUAQGMK+OAp/UQvo0s=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
@ -345,37 +265,22 @@ github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a h1:N9zuLhTvBSRt0gWSiJswwQ2HqDmtX/ZCDJURnKUt1Ik=
github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a/go.mod h1:JKx41uQRwqlTZabZc+kILPrO/3jlKnQ2Z8b7YiVw5cE=
github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lxc/go-lxc v0.0.0-20230621012608-be98af2b8b9f h1:998HYS7wwE0Rj+ttuSrj+G8hNBkx/7OwEYt+nTyPKdk=
github.com/lxc/go-lxc v0.0.0-20230621012608-be98af2b8b9f/go.mod h1:663nEzGHUBfl31PNYjvYAjhhJ91i/TPsCnvqqiZKHp0=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/masterzen/azure-sdk-for-go v3.2.0-beta.0.20161014135628-ee4f0065d00c+incompatible/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE=
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc=
github.com/masterzen/winrm v0.0.0-20161014151040-7a535cd943fc/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E=
github.com/masterzen/winrm v0.0.0-20211231115050-232efb40349e/go.mod h1:Iju3u6NzoTAvjuhsGCZc+7fReNnr/Bd6DsWj3WTokIU=
github.com/masterzen/xmlpath v0.0.0-20140218185901-13f4951698ad/go.mod h1:A0zPC53iKKKcXYxr4ROjpQRQ5FgJXtelNdSmHHuq/tY=
github.com/mattn/go-colorable v0.0.6/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.0-20160806122752-66b8e73f3f5c/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
@ -428,7 +333,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM=
github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/osrg/gobgp/v3 v3.17.0 h1:Rh4hLzirQJnAz//57bxpiiDTkhPtsDuJ6oy0aeciJDA=
@ -540,8 +444,6 @@ github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhg
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -567,7 +469,6 @@ go.starlark.net v0.0.0-20230807144010-2aa75752d1da/go.mod h1:jxU+3+j+71eXOW14274
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20180214000028-650f4a345ab4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -577,10 +478,7 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@ -625,7 +523,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -654,7 +551,6 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@ -664,9 +560,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
@ -717,7 +611,6 @@ golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -752,7 +645,6 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -962,30 +854,20 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20160105164936-4f90aeace3a2/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v1 v1.0.0-20161222125816-442357a80af5/go.mod h1:u0ALmqvLRxLI95fkdCEWrE6mhWYZW1aMOJHp5YXLHTg=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/httprequest.v1 v1.1.1/go.mod h1:/CkavNL+g3qLOrpFHVrEx4NKepeqR4XTZWNj4sGGjz0=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20160818015218-f2b6f6c918c4/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs=
gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
gopkg.in/yaml.v2 v2.0.0-20170712054546-1be3d31502d6/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@ -1001,8 +883,6 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
launchpad.net/xmlpath v0.0.0-20130614043138-000000000004/go.mod h1:vqyExLOM3qBx7mvYRkoxjSCF945s0mbe7YynlKYXtsA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -697,7 +697,6 @@ func doApi10Update(d *Daemon, r *http.Request, req api.ServerPut, patch bool) re
func doApi10UpdateTriggers(d *Daemon, nodeChanged, clusterChanged map[string]string, nodeConfig *node.Config, clusterConfig *clusterConfig.Config) error {
s := d.State()
maasChanged := false
bgpChanged := false
dnsChanged := false
lokiChanged := false
@ -715,10 +714,6 @@ func doApi10UpdateTriggers(d *Daemon, nodeChanged, clusterChanged map[string]str
fallthrough
case "core.proxy_ignore_hosts":
daemonConfigSetProxy(d, clusterConfig)
case "maas.api.url":
fallthrough
case "maas.api.key":
maasChanged = true
case "cluster.images_minimal_replica":
err := autoSyncImages(s.ShutdownCtx, s)
if err != nil {
@ -762,8 +757,6 @@ func doApi10UpdateTriggers(d *Daemon, nodeChanged, clusterChanged map[string]str
for key := range nodeChanged {
switch key {
case "maas.machine":
maasChanged = true
case "core.bgp_address":
fallthrough
case "core.bgp_routerid":
@ -838,15 +831,6 @@ func doApi10UpdateTriggers(d *Daemon, nodeChanged, clusterChanged map[string]str
}
}
if maasChanged {
url, key := clusterConfig.MAASController()
machine := nodeConfig.MAASMachine()
err := d.setupMAASController(url, key, machine)
if err != nil {
return err
}
}
if bgpChanged {
address := nodeConfig.BGPAddress()
asn := clusterConfig.BGPASN()

View File

@ -742,24 +742,6 @@ func clusterPutJoin(d *Daemon, r *http.Request, req api.ClusterPut) response.Res
return err
}
var nodeConfig *node.Config
err = s.DB.Node.Transaction(context.TODO(), func(ctx context.Context, tx *db.NodeTx) error {
var err error
nodeConfig, err = node.ConfigLoad(ctx, tx)
return err
})
if err != nil {
return err
}
// Connect to MAAS
url, key := s.GlobalConfig.MAASController()
machine := nodeConfig.MAASMachine()
err = d.setupMAASController(url, key, machine)
if err != nil {
return err
}
// Start up networks so any post-join changes can be applied now that we have a Node ID.
logger.Debug("Starting networks after cluster join")
err = networkStartup(s)

View File

@ -109,13 +109,6 @@ func (c *Config) HTTPSTrustedProxy() string {
return c.m.GetString("core.https_trusted_proxy")
}
// MAASController the configured MAAS url and key, if any.
func (c *Config) MAASController() (string, string) {
url := c.m.GetString("maas.api.url")
key := c.m.GetString("maas.api.key")
return url, key
}
// OfflineThreshold returns the configured heartbeat threshold, i.e. the
// number of seconds before after which an unresponsive node is considered
// offline..
@ -329,8 +322,6 @@ var ConfigSchema = config.Schema{
"loki.labels": {},
"loki.loglevel": {Validator: logLevelValidator, Default: logrus.InfoLevel.String()},
"loki.types": {Validator: validate.Optional(validate.IsListOf(validate.IsOneOf("lifecycle", "logging"))), Default: "lifecycle,logging"},
"maas.api.key": {},
"maas.api.url": {},
"oidc.client.id": {},
"oidc.issuer": {},
"oidc.audience": {},

View File

@ -44,7 +44,6 @@ import (
instanceDrivers "github.com/lxc/incus/incusd/instance/drivers"
"github.com/lxc/incus/incusd/instance/instancetype"
"github.com/lxc/incus/incusd/loki"
"github.com/lxc/incus/incusd/maas"
networkZone "github.com/lxc/incus/incusd/network/zone"
"github.com/lxc/incus/incusd/node"
"github.com/lxc/incus/incusd/request"
@ -75,7 +74,6 @@ type Daemon struct {
os *sys.OS
db *db.DB
firewall firewall.Firewall
maas *maas.Controller
bgp *bgp.Server
dns *dns.Server
@ -378,7 +376,6 @@ func (d *Daemon) State() *state.State {
return &state.State{
ShutdownCtx: d.shutdownCtx,
DB: d.db,
MAAS: d.maas,
BGP: d.bgp,
DNS: d.dns,
OS: d.os,
@ -1194,10 +1191,6 @@ func (d *Daemon) init() error {
dnsAddress := d.localConfig.DNSAddress()
maasAPIURL := ""
maasAPIKey := ""
maasMachine := d.localConfig.MAASMachine()
err = d.db.Cluster.Transaction(d.shutdownCtx, func(ctx context.Context, tx *db.ClusterTx) error {
config, err := clusterConfig.Load(ctx, tx)
if err != nil {
@ -1227,7 +1220,6 @@ func (d *Daemon) init() error {
d.proxy = shared.ProxyFromConfig(d.globalConfig.ProxyHTTPS(), d.globalConfig.ProxyHTTP(), d.globalConfig.ProxyIgnoreHosts())
maasAPIURL, maasAPIKey = d.globalConfig.MAASController()
d.gateway.HeartbeatOfflineThreshold = d.globalConfig.OfflineThreshold()
lokiURL, lokiUsername, lokiPassword, lokiCACert, lokiLabels, lokiLoglevel, lokiTypes := d.globalConfig.LokiServer()
oidcIssuer, oidcClientID, oidcAudience := d.globalConfig.OIDCServer()
@ -1390,36 +1382,6 @@ func (d *Daemon) init() error {
// Read the trusted certificates
updateCertificateCache(d)
// Connect to MAAS
if maasAPIURL != "" {
go func() {
warningAdded := false
for {
err = d.setupMAASController(maasAPIURL, maasAPIKey, maasMachine)
if err == nil {
logger.Info("Connected to MAAS controller", logger.Ctx{"url": maasAPIURL})
break
}
logger.Warn("Unable to connect to MAAS, trying again in a minute", logger.Ctx{"url": maasAPIURL, "err": err})
if !warningAdded {
_ = d.db.Cluster.UpsertWarningLocalNode("", -1, -1, warningtype.UnableToConnectToMAAS, err.Error())
warningAdded = true
}
time.Sleep(time.Minute)
}
// Resolve any previously created warning once connected
if warningAdded {
_ = warnings.ResolveWarningsByLocalNodeAndType(d.db.Cluster, warningtype.UnableToConnectToMAAS)
}
}()
}
}
// Remove volatile.last_state.ready key as LXD doesn't know if the instances are ready.
@ -1717,35 +1679,6 @@ func (d *Daemon) Stop(ctx context.Context, sig os.Signal) error {
return err
}
// Setup MAAS.
func (d *Daemon) setupMAASController(server string, key string, machine string) error {
var err error
d.maas = nil
// Default the machine name to the hostname
if machine == "" {
machine, err = os.Hostname()
if err != nil {
return err
}
}
// We need both URL and key, otherwise disable MAAS
if server == "" || key == "" {
return nil
}
// Get a new controller struct
controller, err := maas.NewController(server, key, machine)
if err != nil {
d.maas = nil
return err
}
d.maas = controller
return nil
}
// Create a database connection and perform any updates needed.
func initializeDbObject(d *Daemon) error {
logger.Info("Initializing local database")

View File

@ -161,10 +161,10 @@ func importPreClusteringData(tx *sql.Tx, dump *Dump) error {
switch table {
case "config":
// Don't migrate the core.https_address and maas.machine config keys,
// Don't migrate the core.https_address config keys,
// which is node-specific and must remain in the node
// database.
keys := []string{"core.https_address", "maas.machine"}
keys := []string{"core.https_address"}
skip := false
for i, column := range columns {
value, ok := row[i].(string)

View File

@ -28,14 +28,12 @@ func TestLoadPreClusteringData(t *testing.T) {
// config
assert.Equal(t, []string{"id", "key", "value"}, dump.Schema["config"])
assert.Len(t, dump.Data["config"], 3)
assert.Len(t, dump.Data["config"], 2)
assert.Equal(t, "1.2.3.4:666", dump.Data["config"][0][2])
rows := []any{int64(1), "core.https_address", "1.2.3.4:666"}
assert.Equal(t, rows, dump.Data["config"][0])
rows = []any{int64(2), "core.trust_password", "sekret"}
assert.Equal(t, rows, dump.Data["config"][1])
rows = []any{int64(3), "maas.machine", "mymaas"}
assert.Equal(t, rows, dump.Data["config"][2])
// networks
assert.Equal(t, []string{"id", "name", "description"}, dump.Schema["networks"])
@ -194,7 +192,6 @@ func newPreClusteringTx(t *testing.T) *sql.Tx {
"INSERT INTO certificates VALUES (1, 'abcd:efgh', 1, 'foo', 'FOO')",
"INSERT INTO config VALUES(1, 'core.https_address', '1.2.3.4:666')",
"INSERT INTO config VALUES(2, 'core.trust_password', 'sekret')",
"INSERT INTO config VALUES(3, 'maas.machine', 'mymaas')",
"INSERT INTO profiles VALUES(1, 'default', 'Default Incus profile')",
"INSERT INTO profiles VALUES(2, 'users', '')",
"INSERT INTO profiles_config VALUES(2, 2, 'boot.autostart', 'false')",

View File

@ -38,8 +38,6 @@ const (
AppArmorNotAvailable
// MissingVirtiofsd represents the missing virtiofsd warning.
MissingVirtiofsd
// UnableToConnectToMAAS represents the unable to connect to MAAS warning.
UnableToConnectToMAAS
// AppArmorDisabledDueToRawDnsmasq represents the disabled AppArmor due to raw.dnsmasq warning.
AppArmorDisabledDueToRawDnsmasq
// LargerIPv6PrefixThanSupported represents the larger IPv6 prefix than supported warning.
@ -78,7 +76,6 @@ var TypeNames = map[Type]string{
ClusterTimeSkew: "Time skew detected between leader and local",
AppArmorNotAvailable: "AppArmor support has been disabled",
MissingVirtiofsd: "Missing virtiofsd",
UnableToConnectToMAAS: "Unable to connect to MAAS",
AppArmorDisabledDueToRawDnsmasq: "Skipping AppArmor for dnsmasq due to raw.dnsmasq being set",
LargerIPv6PrefixThanSupported: "IPv6 networks with a prefix larger than 64 aren't properly supported by dnsmasq",
ProxyBridgeNetfilterNotEnabled: "Proxy bridge netfilter not enabled",
@ -125,8 +122,6 @@ func (t Type) Severity() Severity {
return SeverityLow
case MissingVirtiofsd:
return SeverityLow
case UnableToConnectToMAAS:
return SeverityLow
case AppArmorDisabledDueToRawDnsmasq:
return SeverityLow
case LargerIPv6PrefixThanSupported:

View File

@ -30,8 +30,6 @@ func nicValidationRules(requiredFields []string, optionalFields []string, instCo
"security.ipv4_filtering": validate.IsAny,
"security.ipv6_filtering": validate.IsAny,
"security.port_isolation": validate.Optional(validate.IsBool),
"maas.subnet.ipv4": validate.IsAny,
"maas.subnet.ipv6": validate.IsAny,
"ipv4.address": validate.Optional(validate.IsNetworkAddressV4),
"ipv6.address": validate.Optional(validate.IsNetworkAddressV6),
"ipv4.routes": validate.Optional(validate.IsListOf(validate.IsNetworkV4)),

View File

@ -85,8 +85,6 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
"security.ipv4_filtering",
"security.ipv6_filtering",
"security.port_isolation",
"maas.subnet.ipv4",
"maas.subnet.ipv6",
"boot.priority",
"vlan",
}
@ -202,7 +200,7 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
if d.config["network"] != "" {
requiredFields = append(requiredFields, "network")
bannedKeys := []string{"nictype", "parent", "mtu", "maas.subnet.ipv4", "maas.subnet.ipv6"}
bannedKeys := []string{"nictype", "parent", "mtu"}
for _, bannedKey := range bannedKeys {
if d.config[bannedKey] != "" {
return fmt.Errorf("Cannot use %q property in conjunction with %q property", bannedKey, "network")
@ -232,15 +230,6 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
if netConfig["bridge.mtu"] != "" {
d.config["mtu"] = netConfig["bridge.mtu"]
}
// Copy certain keys verbatim from the network's settings.
inheritKeys := []string{"maas.subnet.ipv4", "maas.subnet.ipv6"}
for _, inheritKey := range inheritKeys {
_, found := netConfig[inheritKey]
if found {
d.config[inheritKey] = netConfig[inheritKey]
}
}
} else {
// If no network property supplied, then parent property is required.
requiredFields = append(requiredFields, "parent")
@ -261,22 +250,18 @@ func (d *nicBridged) validateConfig(instConf instance.ConfigReader) error {
if d.config["ipv4.address"] == "" {
return fmt.Errorf("IPv4 filtering requires a manually specified ipv4.address when using an unmanaged parent bridge")
}
} else {
// If MAAS isn't being used, then static IP cannot be used with unmanaged parent.
if d.config["ipv4.address"] != "" && d.config["maas.subnet.ipv4"] == "" {
return fmt.Errorf("Cannot use manually specified ipv4.address when using unmanaged parent bridge")
}
} else if d.config["ipv4.address"] != "" {
// Static IP cannot be used with unmanaged parent.
return fmt.Errorf("Cannot use manually specified ipv4.address when using unmanaged parent bridge")
}
if shared.IsTrue(d.config["security.ipv6_filtering"]) {
if d.config["ipv6.address"] == "" {
return fmt.Errorf("IPv6 filtering requires a manually specified ipv6.address when using an unmanaged parent bridge")
}
} else {
// If MAAS isn't being used, then static IP cannot be used with unmanaged parent.
if d.config["ipv6.address"] != "" && d.config["maas.subnet.ipv6"] == "" {
return fmt.Errorf("Cannot use manually specified ipv6.address when using unmanaged parent bridge")
}
} else if d.config["ipv6.address"] != "" {
// Static IP cannot be used with unmanaged parent.
return fmt.Errorf("Cannot use manually specified ipv6.address when using unmanaged parent bridge")
}
}
}

View File

@ -49,8 +49,6 @@ func (d *nicMACVLAN) validateConfig(instConf instance.ConfigReader) error {
"mtu",
"hwaddr",
"vlan",
"maas.subnet.ipv4",
"maas.subnet.ipv6",
"boot.priority",
"gvrp",
}
@ -59,7 +57,7 @@ func (d *nicMACVLAN) validateConfig(instConf instance.ConfigReader) error {
if d.config["network"] != "" {
requiredFields = append(requiredFields, "network")
bannedKeys := []string{"nictype", "parent", "mtu", "vlan", "maas.subnet.ipv4", "maas.subnet.ipv6", "gvrp"}
bannedKeys := []string{"nictype", "parent", "mtu", "vlan", "gvrp"}
for _, bannedKey := range bannedKeys {
if d.config[bannedKey] != "" {
return fmt.Errorf("Cannot use %q property in conjunction with %q property", bannedKey, "network")
@ -88,7 +86,7 @@ func (d *nicMACVLAN) validateConfig(instConf instance.ConfigReader) error {
d.config["parent"] = netConfig["parent"]
// Copy certain keys verbatim from the network's settings.
inheritKeys := []string{"mtu", "vlan", "maas.subnet.ipv4", "maas.subnet.ipv6", "gvrp"}
inheritKeys := []string{"mtu", "vlan", "gvrp"}
for _, inheritKey := range inheritKeys {
_, found := netConfig[inheritKey]
if found {

View File

@ -39,8 +39,6 @@ func (d *nicPhysical) validateConfig(instConf instance.ConfigReader) error {
optionalFields := []string{
"parent",
"name",
"maas.subnet.ipv4",
"maas.subnet.ipv6",
"boot.priority",
"gvrp",
}
@ -52,7 +50,7 @@ func (d *nicPhysical) validateConfig(instConf instance.ConfigReader) error {
if d.config["network"] != "" {
requiredFields = append(requiredFields, "network")
bannedKeys := []string{"nictype", "parent", "mtu", "vlan", "maas.subnet.ipv4", "maas.subnet.ipv6", "gvrp"}
bannedKeys := []string{"nictype", "parent", "mtu", "vlan", "gvrp"}
for _, bannedKey := range bannedKeys {
if d.config[bannedKey] != "" {
return fmt.Errorf("Cannot use %q property in conjunction with %q property", bannedKey, "network")

View File

@ -44,8 +44,6 @@ func (d *nicSRIOV) validateConfig(instConf instance.ConfigReader) error {
"hwaddr",
"vlan",
"security.mac_filtering",
"maas.subnet.ipv4",
"maas.subnet.ipv6",
"boot.priority",
}
@ -53,7 +51,7 @@ func (d *nicSRIOV) validateConfig(instConf instance.ConfigReader) error {
if d.config["network"] != "" {
requiredFields = append(requiredFields, "network")
bannedKeys := []string{"nictype", "parent", "mtu", "vlan", "maas.subnet.ipv4", "maas.subnet.ipv6"}
bannedKeys := []string{"nictype", "parent", "mtu", "vlan"}
for _, bannedKey := range bannedKeys {
if d.config[bannedKey] != "" {
return fmt.Errorf("Cannot use %q property in conjunction with %q property", bannedKey, "network")
@ -82,7 +80,7 @@ func (d *nicSRIOV) validateConfig(instConf instance.ConfigReader) error {
d.config["parent"] = netConfig["parent"]
// Copy certain keys verbatim from the network's settings.
inheritKeys := []string{"mtu", "vlan", "maas.subnet.ipv4", "maas.subnet.ipv6"}
inheritKeys := []string{"mtu", "vlan"}
for _, inheritKey := range inheritKeys {
_, found := netConfig[inheritKey]
if found {

View File

@ -26,7 +26,6 @@ import (
"github.com/lxc/incus/incusd/instance/operationlock"
"github.com/lxc/incus/incusd/lifecycle"
"github.com/lxc/incus/incusd/locking"
"github.com/lxc/incus/incusd/maas"
"github.com/lxc/incus/incusd/operations"
"github.com/lxc/incus/incusd/project"
"github.com/lxc/incus/incusd/revert"
@ -822,168 +821,6 @@ func (d *common) getStartupSnapNameAndExpiry(inst instance.Instance) (string, *t
return name, &expiry, nil
}
// Internal MAAS handling.
func (d *common) maasUpdate(inst instance.Instance, oldDevices map[string]map[string]string) error {
// Check if MAAS is configured
maasURL, _ := d.state.GlobalConfig.MAASController()
if maasURL == "" {
return nil
}
// Check if there's something that uses MAAS
interfaces, err := d.maasInterfaces(inst, d.expandedDevices.CloneNative())
if err != nil {
return err
}
var oldInterfaces []maas.ContainerInterface
if oldDevices != nil {
oldInterfaces, err = d.maasInterfaces(inst, oldDevices)
if err != nil {
return err
}
}
if len(interfaces) == 0 && len(oldInterfaces) == 0 {
return nil
}
// See if we're connected to MAAS
if d.state.MAAS == nil {
return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
}
exists, err := d.state.MAAS.DefinedContainer(d)
if err != nil {
return err
}
if exists {
if len(interfaces) == 0 && len(oldInterfaces) > 0 {
return d.state.MAAS.DeleteContainer(d)
}
return d.state.MAAS.UpdateContainer(d, interfaces)
}
return d.state.MAAS.CreateContainer(d, interfaces)
}
func (d *common) maasInterfaces(inst instance.Instance, devices map[string]map[string]string) ([]maas.ContainerInterface, error) {
interfaces := []maas.ContainerInterface{}
for k, m := range devices {
if m["type"] != "nic" {
continue
}
if m["maas.subnet.ipv4"] == "" && m["maas.subnet.ipv6"] == "" {
continue
}
m, err := inst.FillNetworkDevice(k, m)
if err != nil {
return nil, err
}
subnets := []maas.ContainerInterfaceSubnet{}
// IPv4
if m["maas.subnet.ipv4"] != "" {
subnet := maas.ContainerInterfaceSubnet{
Name: m["maas.subnet.ipv4"],
Address: m["ipv4.address"],
}
subnets = append(subnets, subnet)
}
// IPv6
if m["maas.subnet.ipv6"] != "" {
subnet := maas.ContainerInterfaceSubnet{
Name: m["maas.subnet.ipv6"],
Address: m["ipv6.address"],
}
subnets = append(subnets, subnet)
}
iface := maas.ContainerInterface{
Name: m["name"],
MACAddress: m["hwaddr"],
Subnets: subnets,
}
interfaces = append(interfaces, iface)
}
return interfaces, nil
}
func (d *common) maasRename(inst instance.Instance, newName string) error {
maasURL, _ := d.state.GlobalConfig.MAASController()
if maasURL == "" {
return nil
}
interfaces, err := d.maasInterfaces(inst, d.expandedDevices.CloneNative())
if err != nil {
return err
}
if len(interfaces) == 0 {
return nil
}
if d.state.MAAS == nil {
return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
}
exists, err := d.state.MAAS.DefinedContainer(d)
if err != nil {
return err
}
if !exists {
return d.maasUpdate(inst, nil)
}
return d.state.MAAS.RenameContainer(d, newName)
}
func (d *common) maasDelete(inst instance.Instance) error {
maasURL, _ := d.state.GlobalConfig.MAASController()
if maasURL == "" {
return nil
}
interfaces, err := d.maasInterfaces(inst, d.expandedDevices.CloneNative())
if err != nil {
return err
}
if len(interfaces) == 0 {
return nil
}
if d.state.MAAS == nil {
return fmt.Errorf("Can't perform the operation because MAAS is currently unavailable")
}
exists, err := d.state.MAAS.DefinedContainer(d)
if err != nil {
return err
}
if !exists {
return nil
}
return d.state.MAAS.DeleteContainer(d)
}
// validateStartup checks any constraints that would prevent start up from succeeding under normal circumstances.
func (d *common) validateStartup(stateful bool, statusCode api.StatusCode) error {
// Because the root disk is special and is mounted before the root disk device is setup we duplicate the
@ -1317,7 +1154,7 @@ func (d *common) deviceRemove(dev device.Device, instanceRunning bool) error {
return dev.Remove()
}
// devicesAdd adds devices to instance and registers with MAAS.
// devicesAdd adds devices to instance.
func (d *common) devicesAdd(inst instance.Instance, instanceRunning bool) (revert.Hook, error) {
revert := revert.New()
defer revert.Fail()
@ -1352,14 +1189,6 @@ func (d *common) devicesAdd(inst instance.Instance, instanceRunning bool) (rever
revert.Add(func() { _ = d.deviceRemove(dev, instanceRunning) })
}
// Update MAAS (must run after the MAC addresses have been generated).
err := d.maasUpdate(inst, nil)
if err != nil {
return nil, err
}
revert.Add(func() { _ = d.maasDelete(inst) })
cleanup := revert.Clone().Fail
revert.Success()
return cleanup, nil

View File

@ -3699,13 +3699,6 @@ func (d *lxc) delete(force bool) error {
}
}
// Delete the MAAS entry.
err = d.maasDelete(d)
if err != nil {
d.logger.Error("Failed deleting instance MAAS record", logger.Ctx{"err": err})
return err
}
// Run device removal function for each device.
d.devicesRemove(d)
@ -3835,14 +3828,6 @@ func (d *lxc) Rename(newName string, applyTemplateTrigger bool) error {
}
}
// Rename the MAAS entry.
if !d.IsSnapshot() {
err = d.maasRename(d, newName)
if err != nil {
return err
}
}
revert := revert.New()
defer revert.Fail()
@ -4105,7 +4090,7 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
}
// Diff the devices
removeDevices, addDevices, updateDevices, allUpdatedKeys := oldExpandedDevices.Update(d.expandedDevices, func(oldDevice deviceConfig.Device, newDevice deviceConfig.Device) []string {
removeDevices, addDevices, updateDevices, _ := oldExpandedDevices.Update(d.expandedDevices, func(oldDevice deviceConfig.Device, newDevice deviceConfig.Device) []string {
// This function needs to return a list of fields that are excluded from differences
// between oldDevice and newDevice. The result of this is that as long as the
// devices are otherwise identical except for the fields returned here, then the
@ -4250,22 +4235,6 @@ func (d *lxc) Update(args db.InstanceArgs, userRequested bool) error {
return err
}
// Update MAAS (must run after the MAC addresses have been generated).
updateMAAS := false
for _, key := range []string{"maas.subnet.ipv4", "maas.subnet.ipv6", "ipv4.address", "ipv6.address"} {
if shared.StringInSlice(key, allUpdatedKeys) {
updateMAAS = true
break
}
}
if !d.IsSnapshot() && updateMAAS {
err = d.maasUpdate(d, oldExpandedDevices.CloneNative())
if err != nil {
return err
}
}
// Apply the live changes
if isRunning {
cc, err := d.initLXC(false)

View File

@ -4809,14 +4809,6 @@ func (d *qemu) Rename(newName string, applyTemplateTrigger bool) error {
}
}
// Rename the MAAS entry.
if !d.IsSnapshot() {
err = d.maasRename(d, newName)
if err != nil {
return err
}
}
revert := revert.New()
defer revert.Fail()
@ -5048,7 +5040,7 @@ func (d *qemu) Update(args db.InstanceArgs, userRequested bool) error {
}
// Diff the devices.
removeDevices, addDevices, updateDevices, allUpdatedKeys := oldExpandedDevices.Update(d.expandedDevices, func(oldDevice deviceConfig.Device, newDevice deviceConfig.Device) []string {
removeDevices, addDevices, updateDevices, _ := oldExpandedDevices.Update(d.expandedDevices, func(oldDevice deviceConfig.Device, newDevice deviceConfig.Device) []string {
// This function needs to return a list of fields that are excluded from differences
// between oldDevice and newDevice. The result of this is that as long as the
// devices are otherwise identical except for the fields returned here, then the
@ -5208,22 +5200,6 @@ func (d *qemu) Update(args db.InstanceArgs, userRequested bool) error {
}
}
// Update MAAS (must run after the MAC addresses have been generated).
updateMAAS := false
for _, key := range []string{"maas.subnet.ipv4", "maas.subnet.ipv6", "ipv4.address", "ipv6.address"} {
if shared.StringInSlice(key, allUpdatedKeys) {
updateMAAS = true
break
}
}
if !d.IsSnapshot() && updateMAAS {
err = d.maasUpdate(d, oldExpandedDevices.CloneNative())
if err != nil {
return err
}
}
if d.architectureSupportsUEFI(d.architecture) && (shared.StringInSlice("security.secureboot", changedConfig) || shared.StringInSlice("security.csm", changedConfig)) {
// Re-generate the NVRAM.
err = d.setupNvram()
@ -5638,13 +5614,6 @@ func (d *qemu) delete(force bool) error {
}
}
// Delete the MAAS entry.
err = d.maasDelete(d)
if err != nil {
d.logger.Error("Failed deleting instance MAAS record", logger.Ctx{"err": err})
return err
}
// Run device removal function for each device.
d.devicesRemove(d)

View File

@ -1,449 +0,0 @@
package maas
import (
"fmt"
"net/url"
"strings"
"github.com/juju/gomaasapi"
"github.com/lxc/incus/incusd/project"
"github.com/lxc/incus/shared/api"
)
// Instance is a MAAS specific instance interface.
// This is used rather than instance.Instance to avoid import loops.
type Instance interface {
Name() string
Project() api.Project
}
// Controller represents a MAAS server's machine functions.
type Controller struct {
url string
srv gomaasapi.Controller
srvRaw gomaasapi.Client
machine gomaasapi.Machine
}
// ContainerInterface represents a MAAS connected network interface on the container.
type ContainerInterface struct {
Name string
MACAddress string
Subnets []ContainerInterfaceSubnet
}
// ContainerInterfaceSubnet represents an interface's subscription to a MAAS subnet.
type ContainerInterfaceSubnet struct {
Name string
Address string
}
func parseInterfaces(interfaces []ContainerInterface) (map[string]ContainerInterface, error) {
// Quick checks.
if len(interfaces) == 0 {
return nil, fmt.Errorf("At least one interface must be provided")
}
// Parse the MACs and interfaces
macInterfaces := map[string]ContainerInterface{}
for _, iface := range interfaces {
_, ok := macInterfaces[iface.MACAddress]
if ok {
return nil, fmt.Errorf("MAAS doesn't allow duplicate MAC addresses")
}
if iface.MACAddress == "" {
return nil, fmt.Errorf("Interfaces must have a MAC address")
}
if len(iface.Subnets) == 0 {
return nil, fmt.Errorf("Interfaces must have at least one subnet")
}
macInterfaces[iface.MACAddress] = iface
}
return macInterfaces, nil
}
// NewController returns a new Controller using the specific MAAS server and machine.
func NewController(url string, key string, machine string) (*Controller, error) {
baseURL := fmt.Sprintf("%s/api/2.0/", url)
// Connect to MAAS
srv, err := gomaasapi.NewController(gomaasapi.ControllerArgs{
BaseURL: baseURL,
APIKey: key,
})
if err != nil {
// Juju errors aren't user-friendly, try to extract what actually happened
if !strings.Contains(err.Error(), "unsupported version") {
return nil, err
}
return nil, fmt.Errorf("Unable to connect MAAS at '%s': %v", baseURL,
strings.Split(strings.Split(err.Error(), "unsupported version: ")[1], " (")[0])
}
srvRaw, err := gomaasapi.NewAuthenticatedClient(baseURL, key)
if err != nil {
return nil, err
}
// Find the right machine
machines, err := srv.Machines(gomaasapi.MachinesArgs{Hostnames: []string{machine}})
if err != nil {
return nil, err
}
if len(machines) != 1 {
return nil, fmt.Errorf("Couldn't find the specified machine: %s", machine)
}
// Setup the struct
c := Controller{}
c.srv = srv
c.srvRaw = *srvRaw
c.machine = machines[0]
c.url = baseURL
return &c, err
}
func (c *Controller) getDomain(inst Instance) string {
fields := strings.Split(c.machine.FQDN(), ".")
domain := strings.Join(fields[1:], ".")
if inst.Project().Name == project.Default {
return domain
}
return fmt.Sprintf("%s.%s", inst.Project().Name, domain)
}
func (c *Controller) getDevice(name string, domain string) (gomaasapi.Device, error) {
devs, err := c.machine.Devices(gomaasapi.DevicesArgs{
Hostname: []string{name},
Domain: domain,
})
if err != nil {
return nil, err
}
if len(devs) != 1 {
return nil, fmt.Errorf("Couldn't find the specified instance: %s", name)
}
return devs[0], nil
}
func (c *Controller) getSubnets() (map[string]gomaasapi.Subnet, error) {
// Get all the spaces
spaces, err := c.srv.Spaces()
if err != nil {
return nil, err
}
// Get all the subnets
subnets := map[string]gomaasapi.Subnet{}
for _, space := range spaces {
for _, subnet := range space.Subnets() {
subnets[subnet.Name()] = subnet
}
}
return subnets, nil
}
// CreateContainer defines a new MAAS device for the controller.
func (c *Controller) CreateContainer(inst Instance, interfaces []ContainerInterface) error {
// Parse the provided interfaces
macInterfaces, err := parseInterfaces(interfaces)
if err != nil {
return err
}
// Get all the subnets
subnets, err := c.getSubnets()
if err != nil {
return err
}
// Validation
if len(interfaces) < 1 {
return fmt.Errorf("Empty list of MAAS interface provided")
}
for _, iface := range interfaces {
if len(iface.Subnets) < 1 {
return fmt.Errorf("Bad subnet provided for interface '%s'", iface.Name)
}
for _, subnet := range iface.Subnets {
_, ok := subnets[subnet.Name]
if !ok {
return fmt.Errorf("Subnet '%s' doesn't exist in MAAS", interfaces[0].Subnets[0].Name)
}
}
}
// Create the device and first interface
device, err := c.machine.CreateDevice(gomaasapi.CreateMachineDeviceArgs{
Hostname: inst.Name(),
Domain: c.getDomain(inst),
InterfaceName: interfaces[0].Name,
MACAddress: interfaces[0].MACAddress,
VLAN: subnets[interfaces[0].Subnets[0].Name].VLAN(),
})
if err != nil {
return err
}
// Wipe the container entry if anything fails
success := false
defer func() {
if success {
return
}
_ = c.DeleteContainer(inst)
}()
// Create the rest of the interfaces
for _, iface := range interfaces[1:] {
_, err := device.CreateInterface(gomaasapi.CreateInterfaceArgs{
Name: iface.Name,
MACAddress: iface.MACAddress,
VLAN: subnets[iface.Subnets[0].Name].VLAN(),
})
if err != nil {
return err
}
}
// Get a fresh copy of the device
device, err = c.getDevice(inst.Name(), c.getDomain(inst))
if err != nil {
return err
}
// Setup the interfaces
for _, entry := range device.InterfaceSet() {
// Get our record
iface, ok := macInterfaces[entry.MACAddress()]
if !ok {
return fmt.Errorf("MAAS created an interface with a bad MAC: %s", entry.MACAddress())
}
// Add the subnets
for _, subnet := range iface.Subnets {
err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
Mode: gomaasapi.LinkModeStatic,
Subnet: subnets[subnet.Name],
IPAddress: subnet.Address,
})
if err != nil {
return err
}
}
}
success = true
return nil
}
// DefinedContainer returns true if the container is defined in MAAS.
func (c *Controller) DefinedContainer(inst Instance) (bool, error) {
devs, err := c.machine.Devices(gomaasapi.DevicesArgs{
Hostname: []string{inst.Name()},
Domain: c.getDomain(inst),
})
if err != nil {
return false, err
}
if len(devs) == 1 {
return true, nil
}
return false, nil
}
// UpdateContainer updates the MAAS device's interfaces with the new provided state.
func (c *Controller) UpdateContainer(inst Instance, interfaces []ContainerInterface) error {
// Parse the provided interfaces
macInterfaces, err := parseInterfaces(interfaces)
if err != nil {
return err
}
// Get all the subnets
subnets, err := c.getSubnets()
if err != nil {
return err
}
device, err := c.getDevice(inst.Name(), c.getDomain(inst))
if err != nil {
return err
}
// Validation
if len(interfaces) < 1 {
return fmt.Errorf("Empty list of MAAS interface provided")
}
for _, iface := range interfaces {
if len(iface.Subnets) < 1 {
return fmt.Errorf("Bad subnet provided for interface '%s'", iface.Name)
}
for _, subnet := range iface.Subnets {
_, ok := subnets[subnet.Name]
if !ok {
return fmt.Errorf("Subnet '%s' doesn't exist in MAAS", interfaces[0].Subnets[0].Name)
}
}
}
// Iterate over existing interfaces, drop all removed ones and update existing ones
existingInterfaces := map[string]gomaasapi.Interface{}
for _, entry := range device.InterfaceSet() {
// Check if the interface has been removed from the container
iface, ok := macInterfaces[entry.MACAddress()]
if !ok {
// Delete the interface in MAAS
err = entry.Delete()
if err != nil {
return err
}
continue
}
// Update the subnets
existingSubnets := map[string]gomaasapi.Subnet{}
for _, link := range entry.Links() {
// Check if the MAAS subnet matches any of the container's
found := false
for _, subnet := range iface.Subnets {
if subnet.Name == link.Subnet().Name() {
if subnet.Address == "" || subnet.Address == link.IPAddress() {
found = true
}
break
}
}
// If no exact match could be found, remove it from MAAS
if !found {
err = entry.UnlinkSubnet(link.Subnet())
if err != nil {
return err
}
continue
}
// Record the existing up to date subnet
existingSubnets[link.Subnet().Name()] = link.Subnet()
}
// Add any missing (or updated) subnet to MAAS
for _, subnet := range iface.Subnets {
// Check that it's not configured yet
_, ok := existingSubnets[subnet.Name]
if ok {
continue
}
// Add the link
err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
Mode: gomaasapi.LinkModeStatic,
Subnet: subnets[subnet.Name],
IPAddress: subnet.Address,
})
if err != nil {
return err
}
}
// Record the interface has being configured
existingInterfaces[entry.MACAddress()] = entry
}
// Iterate over expected interfaces, add any missing one
for _, iface := range macInterfaces {
_, ok := existingInterfaces[iface.MACAddress]
if ok {
// We already have it so just move on
continue
}
// Create the new interface
entry, err := device.CreateInterface(gomaasapi.CreateInterfaceArgs{
Name: iface.Name,
MACAddress: iface.MACAddress,
VLAN: subnets[iface.Subnets[0].Name].VLAN(),
})
if err != nil {
return err
}
// Add the subnets
for _, subnet := range iface.Subnets {
err := entry.LinkSubnet(gomaasapi.LinkSubnetArgs{
Mode: gomaasapi.LinkModeStatic,
Subnet: subnets[subnet.Name],
IPAddress: subnet.Address,
})
if err != nil {
return err
}
}
}
return nil
}
// RenameContainer renames the MAAS device for the container without releasing any allocation.
func (c *Controller) RenameContainer(inst Instance, newName string) error {
device, err := c.getDevice(inst.Name(), c.getDomain(inst))
if err != nil {
return err
}
// FIXME: We should convince the Juju folks to implement an Update() method on Device
uri, err := url.Parse(fmt.Sprintf("%s/devices/%s/", c.url, device.SystemID()))
if err != nil {
return err
}
values := url.Values{}
values.Set("hostname", newName)
_, err = c.srvRaw.Put(uri, values)
if err != nil {
return err
}
return nil
}
// DeleteContainer removes the MAAS device for the container.
func (c *Controller) DeleteContainer(inst Instance) error {
device, err := c.getDevice(inst.Name(), c.getDomain(inst))
if err != nil {
return err
}
err = device.Delete()
if err != nil {
return err
}
return nil
}

View File

@ -57,12 +57,6 @@ func (c *cmdInit) RunInteractive(cmd *cobra.Command, args []string, d incus.Inst
return nil, err
}
// MAAS
err = c.askMAAS(&config, d)
if err != nil {
return nil, err
}
// Networking
err = c.askNetworking(&config, d)
if err != nil {
@ -366,38 +360,6 @@ func (c *cmdInit) askClustering(config *api.InitPreseed, d incus.InstanceServer,
return nil
}
func (c *cmdInit) askMAAS(config *api.InitPreseed, d incus.InstanceServer) error {
maas, err := cli.AskBool("Would you like to connect to a MAAS server? (yes/no) [default=no]: ", "no")
if err != nil {
return err
}
if !maas {
return nil
}
maasHostname, err := cli.AskString(fmt.Sprintf("What's the name of this host in MAAS? [default=%s]: ", c.defaultHostname()), c.defaultHostname(), nil)
if err != nil {
return err
}
if maasHostname != c.defaultHostname() {
config.Node.Config["maas.machine"] = maasHostname
}
config.Node.Config["maas.api.url"], err = cli.AskString("URL of your MAAS server (e.g. http://1.2.3.4:5240/MAAS): ", "", nil)
if err != nil {
return err
}
config.Node.Config["maas.api.key"], err = cli.AskString("API key for your MAAS server: ", "", nil)
if err != nil {
return err
}
return nil
}
func (c *cmdInit) askNetworking(config *api.InitPreseed, d incus.InstanceServer) error {
var err error
localBridgeCreate := false
@ -448,33 +410,6 @@ func (c *cmdInit) askNetworking(config *api.InitPreseed, d incus.InstanceServer)
config.Node.Profiles[0].Devices["eth0"]["nictype"] = "bridged"
}
if config.Node.Config["maas.api.url"] != nil {
maasConnect, err := cli.AskBool("Is this interface connected to your MAAS server? (yes/no) [default=yes]: ", "yes")
if err != nil {
return err
}
if maasConnect {
maasSubnetV4, err := cli.AskString("MAAS IPv4 subnet name for this interface (empty for no subnet): ", "", validate.Optional())
if err != nil {
return err
}
if maasSubnetV4 != "" {
config.Node.Profiles[0].Devices["eth0"]["maas.subnet.ipv4"] = maasSubnetV4
}
maasSubnetV6, err := cli.AskString("MAAS IPv6 subnet name for this interface (empty for no subnet): ", "", validate.Optional())
if err != nil {
return err
}
if maasSubnetV6 != "" {
config.Node.Profiles[0].Devices["eth0"]["maas.subnet.ipv6"] = maasSubnetV6
}
}
}
break
}
} else if config.Cluster != nil && fanKernel {

View File

@ -268,8 +268,6 @@ func (n *bridge) Validate(config map[string]string) error {
"dns.zone.reverse.ipv4": validate.IsAny,
"dns.zone.reverse.ipv6": validate.IsAny,
"raw.dnsmasq": validate.IsAny,
"maas.subnet.ipv4": validate.IsAny,
"maas.subnet.ipv6": validate.IsAny,
"security.acls": validate.IsAny,
"security.acls.default.ingress.action": validate.Optional(validate.IsOneOf(acl.ValidActions...)),
"security.acls.default.egress.action": validate.Optional(validate.IsOneOf(acl.ValidActions...)),

View File

@ -24,12 +24,10 @@ func (n *macvlan) DBType() db.NetworkType {
// Validate network config.
func (n *macvlan) Validate(config map[string]string) error {
rules := map[string]func(value string) error{
"parent": validate.Required(validate.IsNotEmpty, validate.IsInterfaceName),
"mtu": validate.Optional(validate.IsNetworkMTU),
"vlan": validate.Optional(validate.IsNetworkVLAN),
"gvrp": validate.Optional(validate.IsBool),
"maas.subnet.ipv4": validate.IsAny,
"maas.subnet.ipv6": validate.IsAny,
"parent": validate.Required(validate.IsNotEmpty, validate.IsInterfaceName),
"mtu": validate.Optional(validate.IsNetworkMTU),
"vlan": validate.Optional(validate.IsNetworkVLAN),
"gvrp": validate.Optional(validate.IsBool),
}
err := n.validate(config, rules)

View File

@ -34,8 +34,6 @@ func (n *physical) Validate(config map[string]string) error {
"mtu": validate.Optional(validate.IsNetworkMTU),
"vlan": validate.Optional(validate.IsNetworkVLAN),
"gvrp": validate.Optional(validate.IsBool),
"maas.subnet.ipv4": validate.IsAny,
"maas.subnet.ipv6": validate.IsAny,
"ipv4.gateway": validate.Optional(validate.IsNetworkAddressCIDRV4),
"ipv6.gateway": validate.Optional(validate.IsNetworkAddressCIDRV6),
"ipv4.ovn.ranges": validate.Optional(validate.IsListOf(validate.IsNetworkRangeV4)),

View File

@ -24,11 +24,9 @@ func (n *sriov) DBType() db.NetworkType {
// Validate network config.
func (n *sriov) Validate(config map[string]string) error {
rules := map[string]func(value string) error{
"parent": validate.Required(validate.IsNotEmpty, validate.IsInterfaceName),
"mtu": validate.Optional(validate.IsNetworkMTU),
"vlan": validate.Optional(validate.IsNetworkVLAN),
"maas.subnet.ipv4": validate.IsAny,
"maas.subnet.ipv6": validate.IsAny,
"parent": validate.Required(validate.IsNotEmpty, validate.IsInterfaceName),
"mtu": validate.Optional(validate.IsNetworkMTU),
"vlan": validate.Optional(validate.IsNetworkVLAN),
}
err := n.validate(config, rules)

View File

@ -92,12 +92,6 @@ func (c *Config) MetricsAddress() string {
return metricsAddress
}
// MAASMachine returns the MAAS machine this instance is associated with, if
// any.
func (c *Config) MAASMachine() string {
return c.m.GetString("maas.machine")
}
// StorageBucketsAddress returns the address and port to setup the storage buckets listener on.
func (c *Config) StorageBucketsAddress() string {
objectAddress := c.m.GetString("core.storage_buckets_address")
@ -179,9 +173,6 @@ var ConfigSchema = config.Schema{
// Network address for the storage buckets server
"core.storage_buckets_address": {Validator: validate.Optional(validate.IsListenAddress(true, true, false))},
// MAAS machine this LXD instance is associated with
"maas.machine": {},
// Storage volumes to store backups/images on
"storage.backups_volume": {},
"storage.images_volume": {},

View File

@ -17,7 +17,6 @@ import (
"github.com/lxc/incus/incusd/firewall"
"github.com/lxc/incus/incusd/fsmonitor"
"github.com/lxc/incus/incusd/instance/instancetype"
"github.com/lxc/incus/incusd/maas"
"github.com/lxc/incus/incusd/node"
"github.com/lxc/incus/incusd/sys"
"github.com/lxc/incus/shared"
@ -33,9 +32,6 @@ type State struct {
// Databases
DB *db.DB
// MAAS server
MAAS *maas.Controller
// BGP server
BGP *bgp.Server

View File

@ -84,7 +84,7 @@ _have lxc && {
core.debug_address cluster.offline_threshold \
images.auto_update_cached images.auto_update_interval \
images.compression_algorithm images.remote_cache_expiry \
maas.api.url maas.api.key maas.machine cluster.images_minimal_replica \
cluster.images_minimal_replica \
network.ovn.integration_bridge network.ovn.northbound_connection \
oidc.client.id oidc.issuer oidc.audience \
storage.backups_volume storage.images_volume"
@ -124,7 +124,7 @@ _have lxc && {
device_keys="limits.ingress limits.egress ipv4.routes \
ipv4.routes.external ipv6.routes ipv6.routes.external parent \
name mtu hwaddr vlan maas.subnet.ipv4 maas.subnet.ipv6 nictype \
name mtu hwaddr vlan nictype \
host_name limits.max \
ipv4.address ipv6.address ipv4.host_address ipv6.host_address ipv4.gateway ipv6.gateway \
security.mac_filtering security.ipv4_filtering security.ipv6_filtering vlan limits.read \
@ -139,7 +139,7 @@ _have lxc && {
ipv4.dhcp.ranges ipv4.firewall ipv4.nat ipv4.nat.address ipv4.nat.order ipv4.ovn.ranges \
ipv4.routes ipv4.routing ipv6.address ipv6.dhcp ipv6.dhcp.expiry ipv6.dhcp.ranges \
ipv6.dhcp.stateful ipv6.firewall ipv6.nat ipv6.nat.address ipv6.nat.order ipv6.ovn.ranges \
ipv6.routes ipv6.routing maas.subnet.ipv4 maas.subnet.ipv6 mtu network parent raw.dnsmasq vlan"
ipv6.routes ipv6.routing mtu network parent raw.dnsmasq vlan"
project_keys="features.images features.profiles features.storage.volumes \
limits.containers limits.virtual-machines limits.memory limits.processes limits.cpu \

View File

@ -88,7 +88,6 @@ var APIExtensions = []string{
"restrict_devlxd",
"migration_pre_copy",
"infiniband",
"maas_network",
"devlxd_events",
"proxy",
"network_dhcp_gateway",

View File

@ -501,8 +501,6 @@ test_container_devices_nic_bridged() {
# Can't use some settings when network is set.
! incus profile device set "${ctName}" eth0 nictype="bridged"
! incus profile device set "${ctName}" eth0 mtu="1400"
! incus profile device set "${ctName}" eth0 maas.subnet.ipv4="test"
! incus profile device set "${ctName}" eth0 maas.subnet.ipv6="test"
# Can't set static IP that isn't part of network's subnet.
! incus profile device set "${ctName}" eth0 ipv4.address="192.0.4.2"

View File

@ -20,7 +20,6 @@ no
yes
my-storage-pool
dir
no
yes
inct$$
auto