Example #1
0
// loadConfigurationFile loads the configuration for the process. It will take
// the default coded configuration, merge it with the base configuration file
// within the initrd filesystem, and then check for the OEM configuration to
// merge in as well.
func (r *runner) loadConfigurationFile() error {
	// first, load the config from the local filesystem in the initrd
	diskConfig, err := getConfigurationFromFile(configurationFile)
	if err != nil {
		return err
	}
	if diskConfig != nil {
		r.config.mergeConfig(diskConfig)
	}

	// if an OEM config is specified, attempt to find it
	if r.config.OEMConfig != nil {
		device := util.ResolveDevice(r.config.OEMConfig.Device)
		if device == "" {
			r.log.Warnf("Unable to resolve oem config device %q, skipping", r.config.OEMConfig.Device)
			return nil
		}
		fstype, _ := util.GetFsType(device)

		// FIXME check fstype against currently supported types

		// mount the disk
		diskPath := filepath.Join(mountPath, strings.Replace(device, "/", "_", -1))
		if err := handleMount(device, diskPath, fstype, 0, ""); err != nil {
			r.log.Errorf("failed to mount oem config disk %q: %v", device, err)
			return nil
		}

		// attempt to load the configuration
		configPath := filepath.Join(diskPath, r.config.OEMConfig.ConfigPath)
		r.log.Infof("Loading OEM config: %q", configPath)
		diskConfig, err := getConfigurationFromFile(configPath)
		if err != nil {
			r.log.Errorf("Failed to load oem config: %v", err)
			return nil
		}
		if diskConfig != nil {
			r.config.mergeConfig(diskConfig)
		}
	}

	return nil
}
Example #2
0
// mountDisks handles walking the disk configuration to configure the specified
// disks, mount them, and make them accessible at the right locations.
func (r *runner) mountDisks() error {
	// Walk the disks to validate that usage entries aren't in multiple
	// records. Do this before making any changes to the disks.
	usages := make(map[kurmaPathUsage]bool, 0)
	for _, disk := range r.config.Disks {
		for _, u := range disk.Usage {
			if usages[u] {
				return fmt.Errorf("multiple disk entries cannot specify the same usage [%s]", string(u))
			}
			usages[u] = true
		}
	}

	// do the stuff
	for _, disk := range r.config.Disks {
		device := util.ResolveDevice(disk.Device)
		if device == "" {
			r.log.Warnf("Unable to resolve device %q, skipping", disk.Device)
			continue
		}
		fstype, _ := util.GetFsType(device)

		// FIXME check fstype against currently supported types

		// format it, if needed
		if shouldFormatDisk(disk, fstype) {
			r.log.Infof("Formatting disk %s to %s", device, disk.FsType)
			if err := formatDisk(device, disk.FsType); err != nil {
				r.log.Errorf("failed to format disk %q: %v", device, err)
				continue
			}
			fstype = disk.FsType
		}

		// resize it, but only if ext4 for now
		if strings.HasPrefix(fstype, "ext") && disk.Resize {
			output, err := exec.Command("/bin/resizefs", device).CombinedOutput()
			if err != nil {
				r.log.Warnf("failed to resize disk %q: %v - %q", device, err, string(output))
			}
		}

		// mount it
		diskPath := filepath.Join(mountPath, strings.Replace(device, "/", "_", -1))
		if err := handleMount(device, diskPath, fstype, 0, ""); err != nil {
			r.log.Errorf("failed to mount disk %q: %v", device, err)
			continue
		}

		// setup usages
		for _, usage := range disk.Usage {
			usagePath := filepath.Join(diskPath, string(usage))

			// ensure the directory exists
			if err := os.MkdirAll(usagePath, os.FileMode(0755)); err != nil {
				r.log.Errorf("failed to create mount point: %v", err)
				continue
			}

			// bind mount it to the kurma path
			kurmaUsagePath := filepath.Join(kurmaPath, string(usage))
			if err := bindMount(usagePath, kurmaUsagePath); err != nil {
				r.log.Errorf("failed to bind mount the selected volume: %v", err)
				continue
			}
		}
	}
	return nil
}