Skip to content

Commit

Permalink
Configure target IP addresses for LVM backend
Browse files Browse the repository at this point in the history
Configure the cinder-volume service's target_ip_address and
target_secondary_ip_addresses using addresses in the network attachment
status. This is necessary in order for EDPM compute nodes to be able to
make volume attachment requests (via iSCSI or NVMe/TCP) over the storage
network.

Jira: OSP-28445
  • Loading branch information
ASBishop committed Oct 4, 2023
1 parent 07c67fb commit dcc9ab6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 18 deletions.
69 changes: 51 additions & 18 deletions controllers/cindervolume_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,12 @@ func (r *CinderVolumeReconciler) generateServiceConfigs(
labels := labels.GetLabels(instance, labels.GetGroupLabel(cinder.ServiceName), serviceLabels)

// customData hold any customization for the service.
customData := map[string]string{cinder.CustomServiceConfigFileName: instance.Spec.CustomServiceConfig}
customData := map[string]string{}

for key, data := range instance.Spec.DefaultConfigOverwrite {
customData[key] = data
}

customServiceConfig := extendCustomServiceConfig(instance.Spec.CustomServiceConfig)

customData[cinder.CustomServiceConfigFileName] = customServiceConfig

// Fetch the two service config snippets (DefaultsConfigFileName and
// CustomConfigFileName) from the Secret generated by the top level
// cinder controller, and add them to this service specific Secret.
Expand All @@ -580,14 +576,34 @@ func (r *CinderVolumeReconciler) generateServiceConfigs(
}
customData[cinder.CustomServiceConfigSecretsFileName] = customSecrets

usesLVM, customServiceConfig := processCustomServiceConfig(instance.Spec.CustomServiceConfig)
customData[cinder.CustomServiceConfigFileName] = customServiceConfig

templateParameters := make(map[string]interface{})
if usesLVM {
networkAttachmentAddrs := cinder.GetNetworkAttachmentAddrs(
instance.Namespace, instance.Spec.NetworkAttachments, instance.Status.NetworkAttachments)

// Configure target IP addresses using all addresses in the network
// attachments. This relies on the fact that the LVM backend can only
// have one replica.
if len(networkAttachmentAddrs) > 0 {
templateParameters["TargetIpAddress"] = networkAttachmentAddrs[0]
if len(networkAttachmentAddrs) > 1 {
templateParameters["TargetSecondaryIpAddresses"] = strings.Join(networkAttachmentAddrs[1:], ",")
}
}
}

configTemplates := []util.Template{
{
Name: fmt.Sprintf("%s-config-data", instance.Name),
Namespace: instance.Namespace,
Type: util.TemplateTypeConfig,
InstanceType: instance.Kind,
CustomData: customData,
Labels: labels,
Name: fmt.Sprintf("%s-config-data", instance.Name),
Namespace: instance.Namespace,
Type: util.TemplateTypeConfig,
InstanceType: instance.Kind,
CustomData: customData,
ConfigOptions: templateParameters,
Labels: labels,
},
}

Expand Down Expand Up @@ -617,30 +633,33 @@ func (r *CinderVolumeReconciler) createHashOfInputHashes(
return hash, changed, nil
}

// extendCustomServiceConfig - A general purpose hook that may extend the customServiceConfig
// processCustomServiceConfig - A general purpose hook that may extend the customServiceConfig
// string in the CR. Note that this is not equivalent to a transforming or defaulting webhook,
// as the CR is not updated. It only influences the final settings in cinder.conf.
//
// Currently this is limited to defining the list of enabled_backends in case its missing.
func extendCustomServiceConfig(customServiceConfig string) string {
// The function also returns a boolean that indicates whether the LVM driver is being used.
func processCustomServiceConfig(customServiceConfig string) (bool, string) {
svcConfigLines := strings.Split(customServiceConfig, "\n")
hasEnabledBackends := false
usesLVM := false
numDrivers := 0
defaultSectionIdx := -1
sectionName := ""
backendNames := []string{}

for idx, line := range svcConfigLines {
token := strings.SplitN(strings.TrimSpace(line), "=", 2)[0]
for idx, rawLine := range svcConfigLines {
line := strings.TrimSpace(rawLine)
token := strings.SplitN(line, "=", 2)[0]

if token == "" || strings.HasPrefix(token, "#") {
// Skip blank lines and comments
continue
}

if token == "enabled_backends" {
// Note when the CRD already specifies the enabled_backends
// Note when the CR already specifies the enabled_backends
hasEnabledBackends = true
break

} else if token == "[DEFAULT]" {
// Note when the customServiceConfig contains a [DEFAULT] section
Expand All @@ -651,10 +670,24 @@ func extendCustomServiceConfig(customServiceConfig string) string {
sectionName = strings.Trim(token, "[]")

} else if token == "volume_backend_name" {
// The section name is used in the list of enabled_backends
backendNames = append(backendNames, sectionName)

} else if token == "volume_driver" {
numDrivers += 1
if strings.HasSuffix(line, ".LVMVolumeDriver") {
usesLVM = true
}
}
}

// Account for the fact that LVM is the default driver. If the backend's driver
// is implicitly LVM, the number of explicitly configured drivers will be less
// than the number of backends.
if numDrivers < len(backendNames) {
usesLVM = true
}

var extendedConfig string
if hasEnabledBackends || len(backendNames) == 0 {
// Nothing to do, just return the original customServiceConfig
Expand All @@ -675,5 +708,5 @@ func extendCustomServiceConfig(customServiceConfig string) string {
extendedConfig = strings.Join(svcConfigLines, "\n")
}

return extendedConfig
return usesLVM, extendedConfig
}
14 changes: 14 additions & 0 deletions pkg/cinder/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,17 @@ func GetOwningCinderName(instance client.Object) string {

return ""
}

// GetNetworkAttachmentAddrs - Returns a list of IP addresses for all network attachments.
func GetNetworkAttachmentAddrs(namespace string, networkAttachments []string, networkAttachmentStatus map[string][]string) []string {
networkAttachmentAddrs := []string{}

for _, network := range networkAttachments {
network_name := namespace + "/" + network
if network_addrs, ok := networkAttachmentStatus[network_name]; ok {
networkAttachmentAddrs = append(networkAttachmentAddrs, network_addrs...)
}
}

return networkAttachmentAddrs
}
6 changes: 6 additions & 0 deletions templates/cindervolume/config/01-service-defaults.conf
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
[backend_defaults]
{{ if (index . "TargetIpAddress") -}}
target_ip_address = {{ .TargetIpAddress }}
{{ end -}}
{{ if (index . "TargetSecondaryIpAddresses") -}}
target_secondary_ip_addresses = {{ .TargetSecondaryIpAddresses }}
{{ end -}}
use_multipath_for_image_xfer = true

0 comments on commit dcc9ab6

Please sign in to comment.