Skip to content

Commit

Permalink
lxc/copy.go: implement profile extension
Browse files Browse the repository at this point in the history
Signed-off-by: hamistao <pedro.ribeiro@canonical.com>
  • Loading branch information
hamistao committed Mar 12, 2024
1 parent 4e8c581 commit b708308
Showing 1 changed file with 68 additions and 12 deletions.
80 changes: 68 additions & 12 deletions lxc/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,49 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR
entry.Profiles = []string{}
}

// If there are device overrides that are expected to be applied to profile devices then load the profiles
// that would be applied server-side.
profileDevices := make(map[string]map[string]string)

if len(deviceMap) > 0 {
// If the list of profiles is empty then LXD would apply the default profile on the server side.
serverSideProfiles := entry.Profiles
if len(serverSideProfiles) == 0 {
serverSideProfiles = []string{"default"}
}

// Get the effective expanded devices by overlaying each profile's devices in order.
for _, profileName := range serverSideProfiles {
profile, _, err := dest.GetProfile(profileName)
if err != nil {
return fmt.Errorf(i18n.G("Failed loading profile %q for device override: %w"), profileName, err)
}

for deviceName, device := range profile.Devices {
profileDevices[deviceName] = device
}
}
}

// Allow setting additional config keys
for key, value := range configMap {
entry.Config[key] = value
}

// Allow setting device overrides
for k, m := range deviceMap {
if entry.Devices[k] == nil {
entry.Devices[k] = m
continue
for deviceName := range deviceMap {
// Check device exists in expanded profile devices.
profileDeviceConfig, found := profileDevices[deviceName]
if !found {
return fmt.Errorf(i18n.G("Cannot override config for device %q: Device not found in profile devices"), deviceName)
}

for key, value := range m {
entry.Devices[k][key] = value
for k, v := range deviceMap[deviceName] {
profileDeviceConfig[k] = v
}

// Add device to entry devices.
entry.Devices[deviceName] = profileDeviceConfig
}

// Allow overriding the ephemeral status
Expand Down Expand Up @@ -272,21 +300,49 @@ func (c *cmdCopy) copyInstance(conf *config.Config, sourceResource string, destR
entry.Profiles = []string{}
}

// If there are device overrides that are expected to be applied to profile devices then load the profiles
// that would be applied server-side.
profileDevices := make(map[string]map[string]string)

if len(deviceMap) > 0 {
// If the list of profiles is empty then LXD would apply the default profile on the server side.
serverSideProfiles := entry.Profiles
if len(serverSideProfiles) == 0 {
serverSideProfiles = []string{"default"}
}

// Get the effective expanded devices by overlaying each profile's devices in order.
for _, profileName := range serverSideProfiles {
profile, _, err := dest.GetProfile(profileName)
if err != nil {
return fmt.Errorf(i18n.G("Failed loading profile %q for device override: %w"), profileName, err)
}

for deviceName, device := range profile.Devices {
profileDevices[deviceName] = device
}
}
}

// Allow setting additional config keys
for key, value := range configMap {
entry.Config[key] = value
}

// Allow setting device overrides
for k, m := range deviceMap {
if entry.Devices[k] == nil {
entry.Devices[k] = m
continue
for deviceName := range deviceMap {
// Check device exists in expanded profile devices.
profileDeviceConfig, found := profileDevices[deviceName]
if !found {
return fmt.Errorf(i18n.G("Cannot override config for device %q: Device not found in profile devices"), deviceName)
}

for key, value := range m {
entry.Devices[k][key] = value
for k, v := range deviceMap[deviceName] {
profileDeviceConfig[k] = v
}

// Add device to entry devices.
entry.Devices[deviceName] = profileDeviceConfig
}

// Allow overriding the ephemeral status
Expand Down

0 comments on commit b708308

Please sign in to comment.