The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6480
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 2a5182f52015de80678532a46ec2ae7db02848f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 20 Nov 2019 14:54:37 -0500 Subject: [PATCH 1/4] lxd/storage: Rename storagePoolVolumeUsedByContainersGet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage.go | 2 +- lxd/storage_btrfs.go | 2 +- lxd/storage_ceph.go | 2 +- lxd/storage_cephfs.go | 2 +- lxd/storage_dir.go | 2 +- lxd/storage_lvm.go | 2 +- lxd/storage_volumes_utils.go | 10 +++++----- lxd/storage_zfs.go | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lxd/storage.go b/lxd/storage.go index 163bff5435..138f7d144f 100644 --- a/lxd/storage.go +++ b/lxd/storage.go @@ -488,7 +488,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str logger.Debugf("Shifting storage volume") if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) { - volumeUsedBy, err := storagePoolVolumeUsedByContainersGet(s, "default", poolName, volumeName) + volumeUsedBy, err := storagePoolVolumeUsedByInstancesGet(s, "default", poolName, volumeName) if err != nil { return nil, err } diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go index 1d31793083..99ef097b09 100644 --- a/lxd/storage_btrfs.go +++ b/lxd/storage_btrfs.go @@ -747,7 +747,7 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error { return err } - usedBy, err := storagePoolVolumeUsedByContainersGet(s.s, "default", s.pool.Name, s.volume.Name) + usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", s.pool.Name, s.volume.Name) if err != nil { return err } diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go index 20d619fe22..45a21a4f19 100644 --- a/lxd/storage_ceph.go +++ b/lxd/storage_ceph.go @@ -675,7 +675,7 @@ func (s *storageCeph) StoragePoolVolumeRename(newName string) error { return err } - usedBy, err := storagePoolVolumeUsedByContainersGet(s.s, "default", s.pool.Name, s.volume.Name) + usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", s.pool.Name, s.volume.Name) if err != nil { return err } diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go index b0b5622297..495165b75d 100644 --- a/lxd/storage_cephfs.go +++ b/lxd/storage_cephfs.go @@ -588,7 +588,7 @@ func (s *storageCephFs) StoragePoolVolumeRename(newName string) error { logger.Infof(`Renaming CEPHFS storage volume on storage pool "%s" from "%s" to "%s`, s.pool.Name, s.volume.Name, newName) // Sanity check - usedBy, err := storagePoolVolumeUsedByContainersGet(s.s, "default", s.pool.Name, s.volume.Name) + usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", s.pool.Name, s.volume.Name) if err != nil { return err } diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go index 9355713cc2..71073bb63d 100644 --- a/lxd/storage_dir.go +++ b/lxd/storage_dir.go @@ -468,7 +468,7 @@ func (s *storageDir) StoragePoolVolumeRename(newName string) error { return err } - usedBy, err := storagePoolVolumeUsedByContainersGet(s.s, "default", s.pool.Name, s.volume.Name) + usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", s.pool.Name, s.volume.Name) if err != nil { return err } diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index ce7aa01137..2f0166193d 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -885,7 +885,7 @@ func (s *storageLvm) StoragePoolVolumeRename(newName string) error { return err } - usedBy, err := storagePoolVolumeUsedByContainersGet(s.s, "default", s.pool.Name, s.volume.Name) + usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", s.pool.Name, s.volume.Name) if err != nil { return err } diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go index 2774cd4b30..464b90a0c7 100644 --- a/lxd/storage_volumes_utils.go +++ b/lxd/storage_volumes_utils.go @@ -214,13 +214,13 @@ func storagePoolVolumeUpdate(state *state.State, poolName string, volumeName str return nil } -func storagePoolVolumeUsedByContainersGet(s *state.State, project, poolName string, volumeName string) ([]string, error) { +func storagePoolVolumeUsedByInstancesGet(s *state.State, project, poolName string, volumeName string) ([]string, error) { insts, err := instanceLoadByProject(s, project) if err != nil { return []string{}, err } - ctsUsingVolume := []string{} + instUsingVolume := []string{} for _, inst := range insts { for _, dev := range inst.LocalDevices() { if dev["type"] != "disk" { @@ -228,13 +228,13 @@ func storagePoolVolumeUsedByContainersGet(s *state.State, project, poolName stri } if dev["pool"] == poolName && dev["source"] == volumeName { - ctsUsingVolume = append(ctsUsingVolume, inst.Name()) + instUsingVolume = append(instUsingVolume, inst.Name()) break } } } - return ctsUsingVolume, nil + return instUsingVolume, nil } func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string, @@ -436,7 +436,7 @@ func storagePoolVolumeUsedByGet(s *state.State, project, poolName string, volume } // Look for containers using this volume - ctsUsingVolume, err := storagePoolVolumeUsedByContainersGet(s, project, poolName, volumeName) + ctsUsingVolume, err := storagePoolVolumeUsedByInstancesGet(s, project, poolName, volumeName) if err != nil { return []string{}, err } diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go index 26c5b4af2d..a19e435b4a 100644 --- a/lxd/storage_zfs.go +++ b/lxd/storage_zfs.go @@ -729,7 +729,7 @@ func (s *storageZfs) StoragePoolVolumeRename(newName string) error { logger.Infof(`Renaming ZFS storage volume on storage pool "%s" from "%s" to "%s`, s.pool.Name, s.volume.Name, newName) - usedBy, err := storagePoolVolumeUsedByContainersGet(s.s, "default", s.pool.Name, s.volume.Name) + usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", s.pool.Name, s.volume.Name) if err != nil { return err } From 3eba8b03cff2e534e4029eaacfe3d27d774dc239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 20 Nov 2019 14:54:57 -0500 Subject: [PATCH 2/4] lxd/storage: Rename storagePoolVolumeUsedByRunningInstancesWithProfilesGet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/storage_volumes.go | 4 ++-- lxd/storage_volumes_utils.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 0e04c9b611..9c8954091d 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -596,7 +596,7 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request, volumeTypeName string } // Check if a running container is using it. - ctsUsingVolume, err := storagePoolVolumeUsedByRunningContainersWithProfilesGet(d.State(), poolName, volumeName, volumeTypeName, true) + ctsUsingVolume, err := storagePoolVolumeUsedByRunningInstancesWithProfilesGet(d.State(), poolName, volumeName, volumeTypeName, true) if err != nil { return response.SmartError(err) } @@ -1010,7 +1010,7 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string) } else { if req.Restore != "" { - ctsUsingVolume, err := storagePoolVolumeUsedByRunningContainersWithProfilesGet(d.State(), poolName, vol.Name, storagePoolVolumeTypeNameCustom, true) + ctsUsingVolume, err := storagePoolVolumeUsedByRunningInstancesWithProfilesGet(d.State(), poolName, vol.Name, storagePoolVolumeTypeNameCustom, true) if err != nil { return response.InternalError(err) } diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go index 464b90a0c7..dd5a672b34 100644 --- a/lxd/storage_volumes_utils.go +++ b/lxd/storage_volumes_utils.go @@ -43,7 +43,7 @@ var supportedVolumeTypesExceptImages = []int{storagePoolVolumeTypeContainer, sto var supportedVolumeTypes = append(supportedVolumeTypesExceptImages, storagePoolVolumeTypeImage) func init() { - storagePools.VolumeUsedByInstancesWithProfiles = storagePoolVolumeUsedByRunningContainersWithProfilesGet + storagePools.VolumeUsedByInstancesWithProfiles = storagePoolVolumeUsedByRunningInstancesWithProfilesGet } func storagePoolVolumeTypeNameToAPIEndpoint(volumeTypeName string) (string, error) { @@ -178,7 +178,7 @@ func storagePoolVolumeUpdate(state *state.State, poolName string, volumeName str // Confirm that no containers are running when changing shifted state if newConfig["security.shifted"] != oldConfig["security.shifted"] { - ctsUsingVolume, err := storagePoolVolumeUsedByRunningContainersWithProfilesGet(state, poolName, volumeName, storagePoolVolumeTypeNameCustom, true) + ctsUsingVolume, err := storagePoolVolumeUsedByRunningInstancesWithProfilesGet(state, poolName, volumeName, storagePoolVolumeTypeNameCustom, true) if err != nil { return err } @@ -371,7 +371,7 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string, return nil } -func storagePoolVolumeUsedByRunningContainersWithProfilesGet(s *state.State, +func storagePoolVolumeUsedByRunningInstancesWithProfilesGet(s *state.State, poolName string, volumeName string, volumeTypeName string, runningOnly bool) ([]string, error) { insts, err := instanceLoadAll(s) @@ -379,7 +379,7 @@ func storagePoolVolumeUsedByRunningContainersWithProfilesGet(s *state.State, return []string{}, err } - ctsUsingVolume := []string{} + instUsingVolume := []string{} volumeNameWithType := fmt.Sprintf("%s/%s", volumeTypeName, volumeName) for _, inst := range insts { if runningOnly && !inst.IsRunning() { @@ -399,12 +399,12 @@ func storagePoolVolumeUsedByRunningContainersWithProfilesGet(s *state.State, // "container////bla" but only against "container/bla". cleanSource := filepath.Clean(dev["source"]) if cleanSource == volumeName || cleanSource == volumeNameWithType { - ctsUsingVolume = append(ctsUsingVolume, inst.Name()) + instUsingVolume = append(instUsingVolume, inst.Name()) } } } - return ctsUsingVolume, nil + return instUsingVolume, nil } // volumeUsedBy = append(volumeUsedBy, fmt.Sprintf("/%s/containers/%s", version.APIVersion, ct)) From 6cc59b1729a06008a646090a2aa1a1796dc24e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 20 Nov 2019 14:56:27 -0500 Subject: [PATCH 3/4] lxd: Have instanceLoadByProject return all instances MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/container.go | 2 +- lxd/container_lxc.go | 4 ++++ lxd/networks.go | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lxd/container.go b/lxd/container.go index 55aaed404c..1b25779c21 100644 --- a/lxd/container.go +++ b/lxd/container.go @@ -1172,7 +1172,7 @@ func instanceLoadByProject(s *state.State, project string) ([]Instance, error) { err := s.Cluster.Transaction(func(tx *db.ClusterTx) error { filter := db.InstanceFilter{ Project: project, - Type: instancetype.Container, + Type: instancetype.Any, } var err error cts, err = tx.InstanceList(filter) diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go index 1c800c0b08..9cd60ca5ae 100644 --- a/lxd/container_lxc.go +++ b/lxd/container_lxc.go @@ -745,6 +745,10 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase mapentries := idmap.ByHostid{} for _, container := range cts { + if container.Type() != instancetype.Container { + continue + } + name := container.Name() /* Don't change our map Just Because. */ diff --git a/lxd/networks.go b/lxd/networks.go index dfcb831a65..e94f8e879f 100644 --- a/lxd/networks.go +++ b/lxd/networks.go @@ -735,6 +735,11 @@ func networkLeasesGet(d *Daemon, r *http.Request) response.Response { if err != nil { continue } + } else if inst.Type() == instancetype.VM { + d, err = inst.(*vmQemu).fillNetworkDevice(k, d) + if err != nil { + continue + } } // Record the MAC From 252776eecc29b58ef1f40e14b584978ec2823b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com> Date: Wed, 20 Nov 2019 16:40:24 -0500 Subject: [PATCH 4/4] lxd/vm: Use leases to get IP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Graber <stgra...@ubuntu.com> --- lxd/networks.go | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ lxd/vm_qemu.go | 59 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/lxd/networks.go b/lxd/networks.go index e94f8e879f..9505777088 100644 --- a/lxd/networks.go +++ b/lxd/networks.go @@ -863,6 +863,77 @@ func networkLeasesGet(d *Daemon, r *http.Request) response.Response { return response.SyncResponse(true, leases) } +func networkGetLeaseAddresses(s *state.State, network string, hwaddr string) ([]api.InstanceStateNetworkAddress, error) { + addresses := []api.InstanceStateNetworkAddress{} + + leaseFile := shared.VarPath("networks", network, "dnsmasq.leases") + if !shared.PathExists(leaseFile) { + return addresses, nil + } + + dbInfo, err := networkLoadByName(s, network) + if err != nil { + return nil, err + } + + content, err := ioutil.ReadFile(leaseFile) + if err != nil { + return nil, err + } + + for _, lease := range strings.Split(string(content), "\n") { + fields := strings.Fields(lease) + if len(fields) < 5 { + continue + } + + // Parse the MAC + mac := networkGetMacSlice(fields[1]) + macStr := strings.Join(mac, ":") + + if len(macStr) < 17 && fields[4] != "" { + macStr = fields[4][len(fields[4])-17:] + } + + if macStr != hwaddr { + continue + } + + // Parse the IP + addr := api.InstanceStateNetworkAddress{ + Address: fields[2], + Scope: "global", + } + + ip := net.ParseIP(addr.Address) + if ip == nil { + continue + } + + if ip.To4() != nil { + addr.Family = "inet" + + _, subnet, _ := net.ParseCIDR(dbInfo.Config()["ipv4.address"]) + if subnet != nil { + mask, _ := subnet.Mask.Size() + addr.Netmask = fmt.Sprintf("%d", mask) + } + } else { + addr.Family = "inet6" + + _, subnet, _ := net.ParseCIDR(dbInfo.Config()["ipv6.address"]) + if subnet != nil { + mask, _ := subnet.Mask.Size() + addr.Netmask = fmt.Sprintf("%d", mask) + } + } + + addresses = append(addresses, addr) + } + + return addresses, nil +} + // The network structs and functions func networkLoadByName(s *state.State, name string) (*network, error) { id, dbInfo, err := s.Cluster.NetworkGet(name) diff --git a/lxd/vm_qemu.go b/lxd/vm_qemu.go index 00bf6366c0..19781a3d2f 100644 --- a/lxd/vm_qemu.go +++ b/lxd/vm_qemu.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "io/ioutil" + "net" "net/http" "os" "os/exec" @@ -2376,13 +2377,61 @@ func (vm *vmQemu) RenderState() (*api.InstanceState, error) { status, err := vm.agentGetState() if err != nil { logger.Warn("Could not get VM state from agent", log.Ctx{"project": vm.Project(), "instance": vm.Name(), "err": err}) - } else { - status.Pid = int64(pid) - status.Status = statusCode.String() - status.StatusCode = statusCode + status = &api.InstanceState{} + status.Processes = -1 + + networks := map[string]api.InstanceStateNetwork{} + for k, m := range vm.ExpandedDevices() { + // We only care about nics. + if m["type"] != "nic" || m["nictype"] != "bridged" { + continue + } + + // Fill the MAC address. + m, err := vm.fillNetworkDevice(k, m) + if err != nil { + return nil, err + } + + // Parse the lease file. + addresses, err := networkGetLeaseAddresses(vm.state, m["parent"], m["hwaddr"]) + if err != nil { + return nil, err + } + + if len(addresses) == 0 { + continue + } - return status, nil + // Get MTU. + iface, err := net.InterfaceByName(m["parent"]) + if err != nil { + return nil, err + } + + if m["host_name"] == "" { + m["host_name"] = vm.localConfig[fmt.Sprintf("volatile.%s.host_name", k)] + } + + networks[k] = api.InstanceStateNetwork{ + Addresses: addresses, + Counters: api.InstanceStateNetworkCounters(shared.NetworkGetCounters(m["host_name"])), + Hwaddr: m["hwaddr"], + HostName: m["host_name"], + Mtu: iface.MTU, + State: "up", + Type: "broadcast", + } + } + + status.Network = networks } + + status.Pid = int64(pid) + status.Status = statusCode.String() + status.StatusCode = statusCode + + return status, nil } // At least return the Status and StatusCode if we couldn't get any
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel