Skip to content

Commit 92cf81c

Browse files
authored
Merge pull request #773 from EmilienM/configDrive
openstack: dynamically mount the config-drive
2 parents c02e517 + 084810a commit 92cf81c

File tree

1 file changed

+92
-23
lines changed

1 file changed

+92
-23
lines changed

pkg/platforms/openstack/openstack.go

Lines changed: 92 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"fmt"
66
"io"
77
"os"
8+
"os/exec"
9+
"path/filepath"
810
"strconv"
911
"strings"
1012

@@ -21,15 +23,18 @@ import (
2123
)
2224

2325
const (
24-
ospHostMetaDataDir = "/host/var/config/openstack/2018-08-27"
25-
ospMetaDataDir = "/var/config/openstack/2018-08-27"
26-
ospMetaDataBaseURL = "http://169.254.169.254/openstack/2018-08-27"
27-
ospNetworkDataJSON = "network_data.json"
28-
ospMetaDataJSON = "meta_data.json"
29-
ospHostNetworkDataFile = ospHostMetaDataDir + "/" + ospNetworkDataJSON
30-
ospHostMetaDataFile = ospHostMetaDataDir + "/" + ospMetaDataJSON
31-
ospNetworkDataURL = ospMetaDataBaseURL + "/" + ospNetworkDataJSON
32-
ospMetaDataURL = ospMetaDataBaseURL + "/" + ospMetaDataJSON
26+
varConfigPath = "/var/config"
27+
ospMetaDataBaseDir = "/openstack/2018-08-27"
28+
ospMetaDataDir = varConfigPath + ospMetaDataBaseDir
29+
ospMetaDataBaseURL = "http://169.254.169.254" + ospMetaDataBaseDir
30+
ospNetworkDataJSON = "network_data.json"
31+
ospMetaDataJSON = "meta_data.json"
32+
ospNetworkDataURL = ospMetaDataBaseURL + "/" + ospNetworkDataJSON
33+
ospMetaDataURL = ospMetaDataBaseURL + "/" + ospMetaDataJSON
34+
// Config drive is defined as an iso9660 or vfat (deprecated) drive
35+
// with the "config-2" label.
36+
//https://docs.openstack.org/nova/latest/user/config-drive.html
37+
configDriveLabel = "config-2"
3338
)
3439

3540
var (
@@ -109,9 +114,10 @@ func New(hostManager host.HostManagerInterface) OpenstackInterface {
109114
}
110115

111116
// GetOpenstackData gets the metadata and network_data
112-
func getOpenstackData(useHostPath bool) (metaData *OSPMetaData, networkData *OSPNetworkData, err error) {
113-
metaData, networkData, err = getOpenstackDataFromConfigDrive(useHostPath)
117+
func getOpenstackData(mountConfigDrive bool) (metaData *OSPMetaData, networkData *OSPNetworkData, err error) {
118+
metaData, networkData, err = getOpenstackDataFromConfigDrive(mountConfigDrive)
114119
if err != nil {
120+
log.Log.Error(err, "GetOpenStackData(): non-fatal error getting OpenStack data from config drive")
115121
metaData, networkData, err = getOpenstackDataFromMetadataService()
116122
if err != nil {
117123
return metaData, networkData, fmt.Errorf("GetOpenStackData(): error getting OpenStack data: %w", err)
@@ -153,46 +159,109 @@ func getOpenstackData(useHostPath bool) (metaData *OSPMetaData, networkData *OSP
153159
return metaData, networkData, err
154160
}
155161

162+
// getConfigDriveDevice returns the config drive device which was found
163+
func getConfigDriveDevice() (string, error) {
164+
dev := "/dev/disk/by-label/" + configDriveLabel
165+
if _, err := os.Stat(dev); os.IsNotExist(err) {
166+
out, err := exec.Command(
167+
"blkid", "-l",
168+
"-t", "LABEL="+configDriveLabel,
169+
"-o", "device",
170+
).CombinedOutput()
171+
if err != nil {
172+
return "", fmt.Errorf("unable to run blkid: %v", err)
173+
}
174+
dev = strings.TrimSpace(string(out))
175+
}
176+
log.Log.Info("found config drive device", "device", dev)
177+
return dev, nil
178+
}
179+
180+
// mountConfigDriveDevice mounts the config drive and return the path
181+
func mountConfigDriveDevice(device string) (string, error) {
182+
if device == "" {
183+
return "", fmt.Errorf("device is empty")
184+
}
185+
tmpDir, err := os.MkdirTemp("", "sriov-configdrive")
186+
if err != nil {
187+
return "", fmt.Errorf("error creating temp directory: %w", err)
188+
}
189+
cmd := exec.Command("mount", "-o", "ro", "-t", "auto", device, tmpDir)
190+
if err := cmd.Run(); err != nil {
191+
return "", fmt.Errorf("error mounting config drive: %w", err)
192+
}
193+
log.Log.V(2).Info("mounted config drive device", "device", device, "path", tmpDir)
194+
return tmpDir, nil
195+
}
196+
197+
// ummountConfigDriveDevice ummounts the config drive device
198+
func ummountConfigDriveDevice(path string) error {
199+
if path == "" {
200+
return fmt.Errorf("path is empty")
201+
}
202+
cmd := exec.Command("umount", path)
203+
if err := cmd.Run(); err != nil {
204+
return fmt.Errorf("error umounting config drive: %w", err)
205+
}
206+
log.Log.V(2).Info("umounted config drive", "path", path)
207+
return nil
208+
}
209+
156210
// getOpenstackDataFromConfigDrive reads the meta_data and network_data files
157-
func getOpenstackDataFromConfigDrive(useHostPath bool) (metaData *OSPMetaData, networkData *OSPNetworkData, err error) {
211+
func getOpenstackDataFromConfigDrive(mountConfigDrive bool) (metaData *OSPMetaData, networkData *OSPNetworkData, err error) {
158212
metaData = &OSPMetaData{}
159213
networkData = &OSPNetworkData{}
214+
var configDrivePath string
160215
log.Log.Info("reading OpenStack meta_data from config-drive")
161216
var metadataf *os.File
162217
ospMetaDataFilePath := ospMetaDataFile
163-
if useHostPath {
164-
ospMetaDataFilePath = ospHostMetaDataFile
218+
if mountConfigDrive {
219+
configDriveDevice, err := getConfigDriveDevice()
220+
if err != nil {
221+
return metaData, networkData, fmt.Errorf("error finding config drive device: %w", err)
222+
}
223+
configDrivePath, err = mountConfigDriveDevice(configDriveDevice)
224+
if err != nil {
225+
return metaData, networkData, fmt.Errorf("error mounting config drive device: %w", err)
226+
}
227+
defer func() {
228+
if e := ummountConfigDriveDevice(configDrivePath); err == nil && e != nil {
229+
err = fmt.Errorf("error umounting config drive device: %w", e)
230+
}
231+
if e := os.Remove(configDrivePath); err == nil && e != nil {
232+
err = fmt.Errorf("error removing temp directory %s: %w", configDrivePath, e)
233+
}
234+
}()
235+
ospMetaDataFilePath = filepath.Join(configDrivePath, ospMetaDataBaseDir, ospMetaDataJSON)
236+
ospNetworkDataFile = filepath.Join(configDrivePath, ospMetaDataBaseDir, ospNetworkDataJSON)
165237
}
166238
metadataf, err = os.Open(ospMetaDataFilePath)
167239
if err != nil {
168-
return metaData, networkData, fmt.Errorf("error opening file %s: %w", ospHostMetaDataFile, err)
240+
return metaData, networkData, fmt.Errorf("error opening file %s: %w", ospMetaDataFilePath, err)
169241
}
170242
defer func() {
171243
if e := metadataf.Close(); err == nil && e != nil {
172-
err = fmt.Errorf("error closing file %s: %w", ospHostMetaDataFile, e)
244+
err = fmt.Errorf("error closing file %s: %w", ospMetaDataFilePath, e)
173245
}
174246
}()
175247
if err = json.NewDecoder(metadataf).Decode(&metaData); err != nil {
176-
return metaData, networkData, fmt.Errorf("error unmarshalling metadata from file %s: %w", ospHostMetaDataFile, err)
248+
return metaData, networkData, fmt.Errorf("error unmarshalling metadata from file %s: %w", ospMetaDataFilePath, err)
177249
}
178250

179251
log.Log.Info("reading OpenStack network_data from config-drive")
180252
var networkDataf *os.File
181253
ospNetworkDataFilePath := ospNetworkDataFile
182-
if useHostPath {
183-
ospNetworkDataFilePath = ospHostNetworkDataFile
184-
}
185254
networkDataf, err = os.Open(ospNetworkDataFilePath)
186255
if err != nil {
187-
return metaData, networkData, fmt.Errorf("error opening file %s: %w", ospHostNetworkDataFile, err)
256+
return metaData, networkData, fmt.Errorf("error opening file %s: %w", ospNetworkDataFilePath, err)
188257
}
189258
defer func() {
190259
if e := networkDataf.Close(); err == nil && e != nil {
191-
err = fmt.Errorf("error closing file %s: %w", ospHostNetworkDataFile, e)
260+
err = fmt.Errorf("error closing file %s: %w", ospNetworkDataFilePath, e)
192261
}
193262
}()
194263
if err = json.NewDecoder(networkDataf).Decode(&networkData); err != nil {
195-
return metaData, networkData, fmt.Errorf("error unmarshalling metadata from file %s: %w", ospHostNetworkDataFile, err)
264+
return metaData, networkData, fmt.Errorf("error unmarshalling metadata from file %s: %w", ospNetworkDataFilePath, err)
196265
}
197266
return metaData, networkData, err
198267
}

0 commit comments

Comments
 (0)