github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/builder/amazon/chroot/device.go (about)

     1  package chroot
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  )
    10  
    11  // AvailableDevice finds an available device and returns it. Note that
    12  // you should externally hold a flock or something in order to guarantee
    13  // that this device is available across processes.
    14  func AvailableDevice() (string, error) {
    15  	prefix, err := devicePrefix()
    16  	if err != nil {
    17  		return "", err
    18  	}
    19  
    20  	letters := "fghijklmnop"
    21  	for _, letter := range letters {
    22  		for i := 1; i < 16; i++ {
    23  			device := fmt.Sprintf("/dev/%s%c%d", prefix, letter, i)
    24  			if _, err := os.Stat(device); err != nil {
    25  				return device, nil
    26  			}
    27  		}
    28  	}
    29  
    30  	return "", errors.New("available device could not be found")
    31  }
    32  
    33  // devicePrefix returns the prefix ("sd" or "xvd" or so on) of the devices
    34  // on the system.
    35  func devicePrefix() (string, error) {
    36  	available := []string{"sd", "xvd"}
    37  
    38  	f, err := os.Open("/sys/block")
    39  	if err != nil {
    40  		return "", err
    41  	}
    42  	defer f.Close()
    43  
    44  	dirs, err := f.Readdirnames(-1)
    45  	if dirs != nil && len(dirs) > 0 {
    46  		for _, dir := range dirs {
    47  			dirBase := filepath.Base(dir)
    48  			for _, prefix := range available {
    49  				if strings.HasPrefix(dirBase, prefix) {
    50  					return prefix, nil
    51  				}
    52  			}
    53  		}
    54  	}
    55  
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  
    60  	return "", errors.New("device prefix could not be detected")
    61  }