blob: 455740737a725ec4d4b0c6acd641cdf875bae319 [file] [log] [blame]
// 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
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
)
const devCtxEnvVar = "DEVICE_CONTEXT"
// DeviceContext contains informationn about a device, which may be set and
// retrieved from the ambient environment.
type DeviceContext struct {
location string
// Nodename is the name of the device.
Nodename string `json:"nodename"`
// SSHKey is the private SSH user corresponding to an authorized key
// registered with the device.
SSHKey string `json:"ssh_key"`
}
// Register stores the the device context value ambiently.
// Unregister must be called to clean this up.
// GetDeviceContext may be called to retrieve the value.
func (devCtx *DeviceContext) Register() error {
if devCtx.location != "" {
return nil
}
fd, err := ioutil.TempFile("", "botanist")
if err != nil {
return err
}
defer fd.Close()
devCtx.location = fd.Name()
if err = json.NewEncoder(fd).Encode(devCtx); err != nil {
devCtx.Unregister()
return err
}
return nil
}
// EnvironEntry returns an environment variable pair string "<name>=<value>"
// that may be attached to the environment of subprocesses.
// This method does not modify the current process' environment.
func (devCtx DeviceContext) EnvironEntry() string {
return fmt.Sprintf("%s=%s", devCtxEnvVar, devCtx.location)
}
// Unregister clears the ambient device context value.
func (devCtx *DeviceContext) Unregister() error {
defer func() { devCtx.location = "" }()
return os.Remove(devCtx.location)
}
// GetDeviceContext returns an ambient DeviceContext value, if one has been registered.
func GetDeviceContext() (*DeviceContext, error) {
location := os.Getenv(devCtxEnvVar)
if location == "" {
return nil, errors.New("no device context found")
}
fd, err := os.Open(location)
if err != nil {
return nil, err
}
var devCtx DeviceContext
if err := json.NewDecoder(fd).Decode(&devCtx); err != nil {
return nil, err
}
devCtx.location = location
return &devCtx, nil
}