[botanist] Rename everything
Change-Id: I3fc1d67cbf9c07b48c4bac4ec4a48d568fc0b48f
diff --git a/botanist/common.go b/botanist/common.go
deleted file mode 100644
index 9d39adc..0000000
--- a/botanist/common.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package botanist
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
-)
-
-// DeviceProperties contains static properties of a hardware device.
-type DeviceProperties struct {
- // Nodename is the hostname of the device that we want to boot on.
- Nodename string `json:"nodename"`
-
- // PDU is the configuration for the attached Power Distribution Unit.
- PDU *Config `json:"pdu,omitempty"`
-
- // SSHKeys are the default system keys to be used with the device.
- SSHKeys []string `json:"keys,omitempty"`
-}
-
-// LoadDeviceProperties unmarshalls a slice of DeviceProperties from a given file.
-// For backwards compatibility, it supports unmarshalling a single DeviceProperties object also
-// TODO(IN-1028): Update all botanist configs to use JSON list format
-func LoadDeviceProperties(path string) ([]DeviceProperties, error) {
- data, err := ioutil.ReadFile(path)
- if err != nil {
- return nil, fmt.Errorf("failed to read device properties file %q", path)
- }
-
- var propertiesSlice []DeviceProperties
-
- if err := json.Unmarshal(data, &propertiesSlice); err != nil {
- var properties DeviceProperties
- if err := json.Unmarshal(data, &properties); err != nil {
- return nil, err
- }
- propertiesSlice = append(propertiesSlice, properties)
- }
- return propertiesSlice, nil
-}
diff --git a/botanist/pdu/amt/amt.go b/botanist/power/amt/amt.go
similarity index 100%
rename from botanist/pdu/amt/amt.go
rename to botanist/power/amt/amt.go
diff --git a/botanist/reboot.go b/botanist/power/power.go
similarity index 74%
rename from botanist/reboot.go
rename to botanist/power/power.go
index 6013675..f1c9384 100644
--- a/botanist/reboot.go
+++ b/botanist/power/power.go
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package botanist
+package power
import (
"context"
"time"
- "fuchsia.googlesource.com/tools/botanist/pdu/amt"
- "fuchsia.googlesource.com/tools/botanist/pdu/wol"
+ "fuchsia.googlesource.com/tools/botanist/power/amt"
+ "fuchsia.googlesource.com/tools/botanist/power/wol"
"fuchsia.googlesource.com/tools/sshutil"
"golang.org/x/crypto/ssh"
@@ -29,36 +29,36 @@
sshUser = "fuchsia"
)
-// Config represents a PDU configuration for a particular device.
-type Config struct {
- // Type is the type of PDU to use.
+// Client represents a power management configuration for a particular device.
+type Client struct {
+ // Type is the type of manager to use.
Type string `json:"type"`
- // Host is the network hostname of the PDU e.g. fuchsia-tests-pdu-001.
+ // Host is the network hostname of the manager, e.g. fuchsia-tests-pdu-001.
Host string `json:"host"`
- // HostHwAddr is the ethernet MAC address of the PDU e.g. 10:10:10:10:10:10
+ // HostHwAddr is the ethernet MAC address of the manager, e.g. 10:10:10:10:10:10
HostMACAddr string `json:"host_mac_addr"`
- // Username is the username used to log in to the PDU.
+ // Username is the username used to log in to the manager.
Username string `json:"username"`
- // Password is the password used to log in to the PDU.
+ // Password is the password used to log in to the manager..
Password string `json:"password"`
}
// RebootDevice attempts to reboot the specified device into recovery, and
// additionally uses the given configuration to reboot the device if specified.
-func RebootDevice(cfg *Config, signers []ssh.Signer, nodename string) error {
+func (c Client) RebootDevice(signers []ssh.Signer, nodename string) error {
// Always attempt to soft reboot the device to recovery.
err := rebootRecovery(nodename, signers)
// Hard reboot the device if specified in the config.
- switch cfg.Type {
+ switch c.Type {
case "amt":
- return amt.Reboot(cfg.Host, cfg.Username, cfg.Password)
+ return amt.Reboot(c.Host, c.Username, c.Password)
case "wol":
- return wol.Reboot(botBroadcastAddr, botInterface, cfg.HostMACAddr)
+ return wol.Reboot(botBroadcastAddr, botInterface, c.HostMACAddr)
}
return err
diff --git a/botanist/pdu/wol/wol.go b/botanist/power/wol/wol.go
similarity index 100%
rename from botanist/pdu/wol/wol.go
rename to botanist/power/wol/wol.go
diff --git a/botanist/ssh.go b/botanist/ssh.go
deleted file mode 100644
index a4b04e5..0000000
--- a/botanist/ssh.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Fuchsia Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package botanist
-
-import (
- "io/ioutil"
-
- "golang.org/x/crypto/ssh"
-)
-
-// Returns the SSH signers associated with the key paths in the botanist config file if present.
-func SSHSignersFromDeviceProperties(properties []DeviceProperties) ([]ssh.Signer, error) {
- processedKeys := make(map[string]bool)
- var signers []ssh.Signer
- for _, singleProperties := range properties {
- for _, keyPath := range singleProperties.SSHKeys {
- if !processedKeys[keyPath] {
- processedKeys[keyPath] = true
- p, err := ioutil.ReadFile(keyPath)
- if err != nil {
- return nil, err
- }
- s, err := ssh.ParsePrivateKey(p)
- if err != nil {
- return nil, err
- }
- signers = append(signers, s)
- }
- }
- }
- return signers, nil
-}
diff --git a/botanist/target/device.go b/botanist/target/device.go
new file mode 100644
index 0000000..0ea5b11
--- /dev/null
+++ b/botanist/target/device.go
@@ -0,0 +1,64 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package target
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+
+ "fuchsia.googlesource.com/tools/botanist/power"
+
+ "golang.org/x/crypto/ssh"
+)
+
+// DeviceConfig contains the static properties of a target device.
+type DeviceConfig struct {
+ // Nodename is the hostname of the device that we want to boot on.
+ Nodename string `json:"nodename"`
+
+ // Power is the attached power management configuration.
+ Power *power.Client `json:"power,omitempty"`
+
+ // SSHKeys are the default system keys to be used with the device.
+ SSHKeys []string `json:"keys,omitempty"`
+}
+
+// LoadDeviceConfigs unmarshalls a slice of DeviceConfigs from a given file.
+func LoadDeviceConfigs(path string) ([]DeviceConfig, error) {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read device properties file %q", path)
+ }
+
+ var configs []DeviceConfig
+ if err := json.Unmarshal(data, &configs); err != nil {
+ return nil, fmt.Errorf("failed to unmarshal configs: %v", err)
+ }
+ return configs, nil
+}
+
+// Returns the SSH signers associated with the key paths in the botanist config file if present.
+func SSHSignersFromConfigs(configs []DeviceConfig) ([]ssh.Signer, error) {
+ processedKeys := make(map[string]bool)
+ var signers []ssh.Signer
+ for _, config := range configs {
+ for _, keyPath := range config.SSHKeys {
+ if !processedKeys[keyPath] {
+ processedKeys[keyPath] = true
+ p, err := ioutil.ReadFile(keyPath)
+ if err != nil {
+ return nil, err
+ }
+ s, err := ssh.ParsePrivateKey(p)
+ if err != nil {
+ return nil, err
+ }
+ signers = append(signers, s)
+ }
+ }
+ }
+ return signers, nil
+}
diff --git a/botanist/common_test.go b/botanist/target/device_test.go
similarity index 79%
rename from botanist/common_test.go
rename to botanist/target/device_test.go
index 4b3c9ed..1626a2f 100644
--- a/botanist/common_test.go
+++ b/botanist/target/device_test.go
@@ -1,17 +1,18 @@
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package botanist
+package target
import (
"io/ioutil"
"os"
"testing"
+ "fuchsia.googlesource.com/tools/botanist/power"
"fuchsia.googlesource.com/tools/sshutil"
)
-func TestLoadDevicePropertiesSlice(t *testing.T) {
+func TestLoadConfigs(t *testing.T) {
tests := []struct {
name string
jsonStr string
@@ -19,11 +20,9 @@
expectErr bool
}{
// Valid configs.
- {"ValidListConfig", `[{"nodename":"upper-drank-wick-creek"},{"nodename":"siren-swoop-wick-hasty"}]`, 2, false},
- {"ValidSingleConfig", `{"nodename":"upper-drank-wick-creek"}`, 1, false},
+ {"ValidConfig", `[{"nodename":"upper-drank-wick-creek"},{"nodename":"siren-swoop-wick-hasty"}]`, 2, false},
// Invalid configs.
- {"InvalidListConfig", `{{"nodename":"upper-drank-wick-creek"},{"nodename":"siren-swoop-wick-hasty"}}`, 0, true},
- {"InvalidSingleConfig", `{"upper-drank-wick-creek"}`, 0, true},
+ {"InvalidConfig", `{{"nodename":"upper-drank-wick-creek"},{"nodename":"siren-swoop-wick-hasty"}}`, 0, true},
}
for _, test := range tests {
tmpfile, err := ioutil.TempFile(os.TempDir(), "common_test")
@@ -37,7 +36,7 @@
t.Fatalf("Failed to write to test device properties file: %s", err)
}
- propertiesSlice, err := LoadDeviceProperties(tmpfile.Name())
+ configs, err := LoadDeviceConfigs(tmpfile.Name())
if test.expectErr && err == nil {
t.Errorf("Test%v: Exepected errors; no errors found", test.name)
@@ -47,8 +46,8 @@
t.Errorf("Test%v: Exepected no errors; found error - %v", test.name, err)
}
- if len(propertiesSlice) != test.expectedLen {
- t.Errorf("Test%v: Expected %d nodes; found %d", test.name, test.expectedLen, len(propertiesSlice))
+ if len(configs) != test.expectedLen {
+ t.Errorf("Test%v: Expected %d nodes; found %d", test.name, test.expectedLen, len(configs))
}
if err := tmpfile.Close(); err != nil {
@@ -57,7 +56,7 @@
}
}
-func TestSSHSignersFromDeviceProperties(t *testing.T) {
+func TestSSHSignersFromConfigs(t *testing.T) {
tests := []struct {
name string
device1Keys []string
@@ -118,11 +117,11 @@
for _, keyName := range test.device2Keys {
keyPaths2 = append(keyPaths2, keyNameToPath[keyName])
}
- devices := []DeviceProperties{
- DeviceProperties{"device1", &Config{}, keyPaths1},
- DeviceProperties{"device2", &Config{}, keyPaths2},
+ configs := []DeviceConfig{
+ {"device1", &power.Client{}, keyPaths1},
+ {"device2", &power.Client{}, keyPaths2},
}
- signers, err := SSHSignersFromDeviceProperties(devices)
+ signers, err := SSHSignersFromConfigs(configs)
if test.expectErr && err == nil {
t.Errorf("Test%v: Expected errors; no errors found", test.name)
}
diff --git a/cmd/botanist/run.go b/cmd/botanist/run.go
index 1136b6b..596e9f0 100644
--- a/cmd/botanist/run.go
+++ b/cmd/botanist/run.go
@@ -13,6 +13,7 @@
"time"
"fuchsia.googlesource.com/tools/botanist"
+ "fuchsia.googlesource.com/tools/botanist/target"
"fuchsia.googlesource.com/tools/build"
"fuchsia.googlesource.com/tools/command"
"fuchsia.googlesource.com/tools/logger"
@@ -30,7 +31,7 @@
// RunCommand is a Command implementation for booting a device and running a
// given command locally.
type RunCommand struct {
- // DeviceFile is the path to a file of device properties.
+ // DeviceFile is the path to a file of device config.
deviceFile string
// ImageManifests is a list of paths to image manifests (e.g., images.json)
@@ -79,7 +80,7 @@
}
func (r *RunCommand) SetFlags(f *flag.FlagSet) {
- f.StringVar(&r.deviceFile, "device", "/etc/botanist/config.json", "path to file of device properties")
+ f.StringVar(&r.deviceFile, "device", "/etc/botanist/config.json", "path to file of device config")
f.Var(&r.imageManifests, "images", "paths to image manifests")
f.BoolVar(&r.netboot, "netboot", false, "if set, botanist will not pave; but will netboot instead")
f.StringVar(&r.fastboot, "fastboot", "", "path to the fastboot tool; if set, the device will be flashed into Zedboot. A zircon-r must be supplied via -images")
@@ -208,16 +209,16 @@
return fmt.Errorf("failed to load images: %v", err)
}
- propertiesSlice, err := botanist.LoadDeviceProperties(r.deviceFile)
+ configs, err := target.LoadDeviceConfigs(r.deviceFile)
if err != nil {
- return fmt.Errorf("failed to load device properties file %q", r.deviceFile)
- } else if len(propertiesSlice) != 1 {
- return fmt.Errorf("expected 1 entry in the device properties file; found %d", len(propertiesSlice))
+ return fmt.Errorf("failed to load device config file %q", r.deviceFile)
+ } else if len(configs) != 1 {
+ return fmt.Errorf("expected 1 entry in the device config file; found %d", len(configs))
}
- properties := propertiesSlice[0]
+ config := configs[0]
// Merge config file and command-line keys.
- privKeyPaths := properties.SSHKeys
+ privKeyPaths := config.SSHKeys
if r.sshKey != "" {
privKeyPaths = append(privKeyPaths, r.sshKey)
}
@@ -265,12 +266,12 @@
defer syslog.Close()
}
- if properties.PDU != nil {
+ if config.Power != nil {
defer func() {
- logger.Debugf(ctx, "rebooting the node %q\n", properties.Nodename)
+ logger.Debugf(ctx, "rebooting the node %q\n", config.Nodename)
- if err := botanist.RebootDevice(properties.PDU, signers, properties.Nodename); err != nil {
- logger.Errorf(ctx, "failed to reboot %q: %v\n", properties.Nodename, err)
+ if err := config.Power.RebootDevice(signers, config.Nodename); err != nil {
+ logger.Errorf(ctx, "failed to reboot %q: %v\n", config.Nodename, err)
}
}()
}
@@ -298,7 +299,7 @@
return
}
}
- errs <- r.runCmd(ctx, imgs, properties.Nodename, args, privKeyPaths[0], signers, syslog)
+ errs <- r.runCmd(ctx, imgs, config.Nodename, args, privKeyPaths[0], signers, syslog)
}()
select {
diff --git a/cmd/botanist/zedboot.go b/cmd/botanist/zedboot.go
index 0f481c8..de5470f 100644
--- a/cmd/botanist/zedboot.go
+++ b/cmd/botanist/zedboot.go
@@ -20,6 +20,7 @@
"time"
"fuchsia.googlesource.com/tools/botanist"
+ "fuchsia.googlesource.com/tools/botanist/target"
"fuchsia.googlesource.com/tools/build"
"fuchsia.googlesource.com/tools/command"
"fuchsia.googlesource.com/tools/logger"
@@ -43,8 +44,8 @@
// Netboot tells botanist to netboot (and not to pave).
netboot bool
- // PropertiesFile is the path to a file where deviceProperties have been written.
- propertiesFile string
+ // ConfigFile is the path to a file containing the target config.
+ configFile string
// TestResultsDir is the directory on target to where test results will be written.
testResultsDir string
@@ -92,7 +93,7 @@
f.StringVar(&cmd.outputArchive, "out", "output.tar", "path on host to output tarball of test results")
f.StringVar(&cmd.summaryFilename, "summary-name", runtests.TestSummaryFilename, "name of the file in the test directory")
f.DurationVar(&cmd.filePollInterval, "poll-interval", 1*time.Minute, "time between checking for summary.json on the target")
- f.StringVar(&cmd.propertiesFile, "properties", "/etc/botanist/config.json", "path to file of device properties")
+ f.StringVar(&cmd.configFile, "config", "/etc/botanist/config.json", "path to file of device config")
f.StringVar(&cmd.cmdlineFile, "cmdline-file", "", "path to a file containing additional kernel command-line arguments")
f.StringVar(&cmd.fastboot, "fastboot", "", "path to the fastboot tool; if set, the device will be flashed into Zedboot. A zircon-r must be supplied via -images")
f.StringVar(&cmd.hostCmd, "hacky-host-cmd", "", "host command to run after paving. To be removed on completion of IN-831")
@@ -197,7 +198,7 @@
return cmd.tarHostCmdArtifacts(summaryBuffer.Bytes(), stdoutBuf.Bytes(), tmpDir)
}
-func (cmd *ZedbootCommand) runTests(ctx context.Context, imgs build.Images, nodes []botanist.DeviceProperties, cmdlineArgs []string, signers []ssh.Signer) error {
+func (cmd *ZedbootCommand) runTests(ctx context.Context, imgs build.Images, nodes []target.DeviceConfig, cmdlineArgs []string, signers []ssh.Signer) error {
var err error
// Set up log listener and dump kernel output to stdout.
@@ -359,26 +360,26 @@
}
func (cmd *ZedbootCommand) execute(ctx context.Context, cmdlineArgs []string) error {
- propertiesSlice, err := botanist.LoadDeviceProperties(cmd.propertiesFile)
+ configs, err := target.LoadDeviceConfigs(cmd.configFile)
if err != nil {
- return fmt.Errorf("failed to load device properties file %q", cmd.propertiesFile)
+ return fmt.Errorf("failed to load target config file %q", cmd.configFile)
}
- signers, err := botanist.SSHSignersFromDeviceProperties(propertiesSlice)
+ signers, err := target.SSHSignersFromConfigs(configs)
if err != nil {
return err
}
- for _, properties := range propertiesSlice {
- if properties.PDU != nil {
- defer func(pdu *botanist.Config, nodename string) {
- logger.Debugf(ctx, "rebooting the node %q\n", nodename)
+ for _, config := range configs {
+ if config.Power != nil {
+ defer func(cfg *target.DeviceConfig) {
+ logger.Debugf(ctx, "rebooting the node %q\n", cfg.Nodename)
- if err := botanist.RebootDevice(pdu, signers, nodename); err != nil {
+ if err := cfg.Power.RebootDevice(signers, cfg.Nodename); err != nil {
logger.Errorf(ctx, "failed to reboot the device: %v", err)
}
- }(properties.PDU, properties.Nodename)
+ }(&config)
}
}
@@ -410,7 +411,7 @@
return
}
}
- errs <- cmd.runTests(ctx, imgs, propertiesSlice, cmdlineArgs, signers)
+ errs <- cmd.runTests(ctx, imgs, configs, cmdlineArgs, signers)
}()
select {
@@ -423,8 +424,8 @@
}
func (cmd *ZedbootCommand) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
- propertiesFlag := f.Lookup("properties")
- logger.Debugf(ctx, "properties flag: %v\n", propertiesFlag.Value)
+ configFlag := f.Lookup("config")
+ logger.Debugf(ctx, "config flag: %v\n", configFlag.Value)
// Aggregate command-line arguments.
cmdlineArgs := f.Args()
diff --git a/cmd/health_checker/main.go b/cmd/health_checker/main.go
index 51abf02..5fba855 100644
--- a/cmd/health_checker/main.go
+++ b/cmd/health_checker/main.go
@@ -13,7 +13,7 @@
"os/exec"
"time"
- "fuchsia.googlesource.com/tools/botanist"
+ "fuchsia.googlesource.com/tools/botanist/target"
"fuchsia.googlesource.com/tools/netboot"
)
@@ -75,16 +75,16 @@
return HealthCheckResult{nodename, healthyState, ""}
}
-func reboot(properties botanist.DeviceProperties) error {
- if properties.PDU == nil {
- return fmt.Errorf("Failed to reboot the device: missing PDU info in botanist config file.")
+func reboot(config target.DeviceConfig) error {
+ if config.Power == nil {
+ return fmt.Errorf("Failed to reboot the device: missing power management info in botanist config file.")
}
- signers, err := botanist.SSHSignersFromDeviceProperties([]botanist.DeviceProperties{properties})
+ signers, err := target.SSHSignersFromConfigs([]target.DeviceConfig{config})
if err != nil {
return fmt.Errorf("Failed to reboot the device: %v.", err)
}
- if err = botanist.RebootDevice(properties.PDU, signers, properties.Nodename); err != nil {
+ if err = config.Power.RebootDevice(signers, config.Nodename); err != nil {
return fmt.Errorf("Failed to reboot the device: %v.", err)
}
return nil
@@ -116,20 +116,19 @@
func main() {
flag.Parse()
client := netboot.NewClient(timeout)
- var devices []botanist.DeviceProperties
- devices, err := botanist.LoadDeviceProperties(configFile)
+ configs, err := target.LoadDeviceConfigs(configFile)
if err != nil {
log.Fatal(err)
}
var checkResultSlice []HealthCheckResult
- for _, deviceProperties := range devices {
- nodename := deviceProperties.Nodename
+ for _, config := range configs {
+ nodename := config.Nodename
if nodename == "" {
log.Fatal("Failed to retrieve nodename from config file")
}
checkResult := checkHealth(client, nodename)
if checkResult.State == unhealthyState && rebootIfUnhealthy {
- if rebootErr := reboot(deviceProperties); rebootErr != nil {
+ if rebootErr := reboot(config); rebootErr != nil {
checkResult.ErrorMsg += "; " + rebootErr.Error()
}
}