Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions cli/commands/write/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ func init() {
subcommands.Register(&writeCmd{name: "write"}, "")
subcommands.Register(&writeCmd{name: "update", distro: "windows", track: "stable", update: true}, "")
subcommands.Register(&writeCmd{name: "windows", distro: "windows", track: "stable"}, "")
subcommands.Register(&writeCmd{name: "windowsdev", distro: "windowsdev", track: "stable"}, "")
subcommands.Register(&writeCmd{name: "windowsffu", distro: "windowsffu", track: "stable", ffu: true}, "")
}

Expand Down Expand Up @@ -245,7 +244,7 @@ func (c *writeCmd) SetFlags(f *flag.FlagSet) {
f.BoolVar(&c.update, "update", c.update, "attempts to perform a device refresh only for non-admin users")
f.StringVar(&c.distro, "distro", c.distro, "the os distribution to be provisioned, typically 'windows' or 'linux'")
f.StringVar(&c.track, "track", c.track, "track (variant) of the installer to provision")
f.StringVar(&c.confTrack, "conf_track", c.track, "track (variant) of the configuration file to provision, only valid with FFU based distros")
f.StringVar(&c.confTrack, "conf_track", "", "track (variant) of the configuration file to provision")
f.StringVar(&c.seedServer, "seed_server", "", "override the default server to use for obtaining seeds, only used for debugging")
f.BoolVar(&c.info, "info", false, "display console messages with debugging information included")
f.IntVar(&c.v, "v", 1, "controls the level of info log verbosity")
Expand Down Expand Up @@ -314,12 +313,6 @@ func (c *writeCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
return subcommands.ExitFailure
}

// FFU images are the only ones that use confTrack. Default confTrack = track for reusability.
if !c.ffu && c.confTrack != "" {
deck.InfofA("Ignoring confTrack flag %q, as this is only used for windowsffu", c.confTrack).With(deck.V(1)).Go()
c.confTrack = ""
}

// We now know we have a valid list of devices to provision, and we can
// begin provisioning.
if err := execute(c, f); err != nil {
Expand Down
44 changes: 40 additions & 4 deletions cli/commands/write/write_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package write
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
Expand Down Expand Up @@ -135,10 +136,45 @@ func TestExecute(t *testing.T) {
want: subcommands.ExitFailure,
},
{
desc: "--conf_track passed on non ffu distro",
cmd: &writeCmd{},
args: []string{"--track=stable", "--conf_track=stable", "1"},
execute: func(c *writeCmd, f *flag.FlagSet) error { return nil },
desc: "--conf_track passed on non ffu distro",
cmd: &writeCmd{},
args: []string{"--track=stable", "--conf_track=stable", "1"},
execute: func(c *writeCmd, f *flag.FlagSet) error {
if c.confTrack != "stable" {
return fmt.Errorf("c.confTrack got %q, want 'stable'", c.confTrack)
}
return nil
},
logDir: filepath.Dir(filepath.Join(os.TempDir(), binaryName)),
verbose: false,
want: subcommands.ExitSuccess,
},
{
// An empty conf_track is passed through unchanged; config.New
// defaults it to the image track.
desc: "--conf_track is passed through empty when unspecified",
cmd: &writeCmd{},
args: []string{"--track=testing", "1"},
execute: func(c *writeCmd, f *flag.FlagSet) error {
if c.confTrack != "" {
return fmt.Errorf("c.confTrack got %q, want empty", c.confTrack)
}
return nil
},
logDir: filepath.Dir(filepath.Join(os.TempDir(), binaryName)),
verbose: false,
want: subcommands.ExitSuccess,
},
{
desc: "--conf_track explicitly specified on non ffu distro",
cmd: &writeCmd{},
args: []string{"--track=stable", "--conf_track=unstable", "1"},
execute: func(c *writeCmd, f *flag.FlagSet) error {
if c.confTrack != "unstable" {
return fmt.Errorf("c.confTrack got %q, want 'unstable'", c.confTrack)
}
return nil
},
logDir: filepath.Dir(filepath.Join(os.TempDir(), binaryName)),
verbose: false,
want: subcommands.ExitSuccess,
Expand Down
57 changes: 45 additions & 12 deletions cli/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,19 @@ const (
type distribution struct {
os OperatingSystem
confFile string // The final name of the config file.
confServer string // The FFU configs are obtained here.
confServer string // Runtime boot configs are obtained here.
imageServer string // The base image is obtained here.
label string // If set, is used to set partition labels.
name string // Friendly name: e.g. Corp Windows.
seedDest string // The relative path where the seed should be written.
seedFile string // This file is hashed when obtainng a seed.
seedServer string // If set, a seed is obtained from here.
images map[string]string
configs map[string]string // Contains config file names.
// ffu reports whether the distribution supports FFU restoration. FFU
// mode is rejected for distributions where this is false, because writing
// the FFU config would send a normal install into FFU restoration.
ffu bool
images map[string]string
configs map[string]string // Contains config file names.
}

// Configuration represents the state of all flags and selections provided
Expand Down Expand Up @@ -103,20 +107,29 @@ func New(cleanup, warning, eject, ffu, update bool, devices []string, os, track,
}
if len(devices) > 0 {
if err := conf.addDeviceList(devices); err != nil {
return nil, fmt.Errorf("addDeviceList(%q) returned %v", devices, err)
return nil, fmt.Errorf("addDeviceList(%q) returned %w", devices, err)
}
}
// Sanity check the chosen distribution and add it to the config.
if err := conf.addDistro(os); err != nil {
return nil, fmt.Errorf("addDistro(%q) returned %v", os, err)
return nil, fmt.Errorf("addDistro(%q) returned %w", os, err)
}
// FFU mode writes a config that triggers FFU restoration at boot, so it is
// only allowed for distributions that support it.
if ffu && !conf.distro.ffu {
return nil, fmt.Errorf("%w: distribution %q does not support FFU", errInput, os)
}
var err error
// Sanity check the image and configuration tracks and add them to the config.
if conf.track, err = validateTrack(track, conf.distro.images); err != nil {
return nil, err
}
if ffu {
if conf.confTrack, err = validateTrack(confTrack, conf.distro.configs); err != nil {
if conf.NeedsConfig() {
ct := confTrack
if ct == "" {
ct = conf.track
}
if conf.confTrack, err = validateTrack(ct, conf.distro.configs); err != nil {
return nil, err
}
}
Expand Down Expand Up @@ -236,8 +249,9 @@ func (c *Configuration) Track() string {
return c.track
}

// ConfTrack returns the selected confTrack for FFU. This generally maps
// to one of default, unstable, testing, or stable.
// ConfTrack returns the selected track of the runtime boot config, or blank
// when no config is needed. This generally maps to one of default, unstable,
// testing, or stable.
func (c *Configuration) ConfTrack() string {
return c.confTrack
}
Expand Down Expand Up @@ -274,19 +288,38 @@ func (c *Configuration) FFU() bool {
return c.ffu
}

// HasConfig returns whether or not configuration files are defined for this distribution.
func (c *Configuration) HasConfig() bool {
return c.distro != nil && c.distro.confServer != "" && len(c.distro.configs) > 0
}

// NeedsConfig reports whether a runtime boot config must be fetched and written.
func (c *Configuration) NeedsConfig() bool {
return c.HasConfig() || c.FFU()
}

// ConfFile returns the final name of the configuration file.
func (c *Configuration) ConfFile() string {
return c.distro.confFile
}

// FFUConfFile returns the name of the config file.
// FFUConfFile returns the name of the runtime config file for the selected
// config track, or "" when the distribution defines none. Despite its name it
// serves both FFU and non-FFU distributions.
// TODO(b/544866964): Rename once ConfFile is retired to avoid the collision.
func (c *Configuration) FFUConfFile() string {
// Return the filename only.
if c.distro == nil || c.distro.configs[c.confTrack] == "" {
return ""
}
return filepath.Base(c.distro.configs[c.confTrack])
}

// FFUConfPath returns the path to the config.
// FFUConfPath returns the download URL of the runtime config file for the
// selected config track, or "" when the distribution defines none.
func (c *Configuration) FFUConfPath() string {
if c.distro == nil || c.distro.confServer == "" || c.distro.configs[c.confTrack] == "" {
return ""
}
return fmt.Sprintf(`%s/%s`, c.distro.confServer, c.distro.configs[c.confTrack])
}

Expand Down
Loading
Loading