mirror of
https://github.com/docker/docs.git
synced 2026-04-12 06:19:22 +07:00
If the lines don't split cleanly (occasionally STDERR gets mixed in, for instance, due to our current SSH output setup), we should simply log.Warn in the output instead of bailing completely. Signed-off-by: Nathan LeClaire <nathan.leclaire@gmail.com>
89 lines
2.2 KiB
Go
89 lines
2.2 KiB
Go
package provision
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"github.com/docker/machine/log"
|
|
)
|
|
|
|
// The /etc/os-release file contains operating system identification data
|
|
// See http://www.freedesktop.org/software/systemd/man/os-release.html for more details
|
|
|
|
// Values in this struct must always be string
|
|
// or the reflection will not work properly.
|
|
type OsRelease struct {
|
|
AnsiColor string `osr:"ANSI_COLOR"`
|
|
Name string `osr:"NAME"`
|
|
Version string `osr:"VERSION"`
|
|
Id string `osr:"ID"`
|
|
IdLike string `osr:"ID_LIKE"`
|
|
PrettyName string `osr:"PRETTY_NAME"`
|
|
VersionId string `osr:"VERSION_ID"`
|
|
HomeUrl string `osr:"HOME_URL"`
|
|
SupportUrl string `osr:"SUPPORT_URL"`
|
|
BugReportUrl string `osr:"BUG_REPORT_URL"`
|
|
}
|
|
|
|
func stripQuotes(val string) string {
|
|
if len(val) > 0 && val[0] == '"' {
|
|
return val[1 : len(val)-1]
|
|
}
|
|
return val
|
|
}
|
|
|
|
func (osr *OsRelease) setIfPossible(key, val string) error {
|
|
v := reflect.ValueOf(osr).Elem()
|
|
for i := 0; i < v.NumField(); i++ {
|
|
fieldValue := v.Field(i)
|
|
fieldType := v.Type().Field(i)
|
|
originalName := fieldType.Tag.Get("osr")
|
|
if key == originalName && fieldValue.Kind() == reflect.String {
|
|
fieldValue.SetString(val)
|
|
return nil
|
|
}
|
|
}
|
|
return fmt.Errorf("Couldn't set key %s, no corresponding struct field found", key)
|
|
}
|
|
|
|
func parseLine(osrLine string) (string, string, error) {
|
|
if osrLine == "" {
|
|
return "", "", nil
|
|
}
|
|
|
|
vals := strings.Split(osrLine, "=")
|
|
if len(vals) != 2 {
|
|
return "", "", fmt.Errorf("Expected %s to split by '=' char into two strings, instead got %d strings", osrLine, len(vals))
|
|
}
|
|
key := vals[0]
|
|
val := stripQuotes(vals[1])
|
|
return key, val, nil
|
|
}
|
|
|
|
func (osr *OsRelease) ParseOsRelease(osReleaseContents []byte) error {
|
|
r := bytes.NewReader(osReleaseContents)
|
|
scanner := bufio.NewScanner(r)
|
|
for scanner.Scan() {
|
|
key, val, err := parseLine(scanner.Text())
|
|
if err != nil {
|
|
log.Warn("Warning: got an invalid line error parsing /etc/os-release: %s", err)
|
|
continue
|
|
}
|
|
if err := osr.setIfPossible(key, val); err != nil {
|
|
log.Debug(err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func NewOsRelease(contents []byte) (*OsRelease, error) {
|
|
osr := &OsRelease{}
|
|
if err := osr.ParseOsRelease(contents); err != nil {
|
|
return nil, err
|
|
}
|
|
return osr, nil
|
|
}
|