105 lines
3.4 KiB
Go
105 lines
3.4 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// Phase identifies a resumable unit of Windows provisioning work.
|
|
type Phase string
|
|
|
|
const (
|
|
PhaseOS Phase = "os"
|
|
PhaseHost Phase = "host"
|
|
PhaseCustom Phase = "custom"
|
|
PhaseConfig Phase = "config"
|
|
PhaseWSL Phase = "wsl"
|
|
)
|
|
|
|
var PhaseOrder = []Phase{PhaseOS, PhaseHost, PhaseCustom, PhaseConfig, PhaseWSL}
|
|
|
|
type Options struct {
|
|
Only Phase
|
|
NoAI bool
|
|
NoWSL bool
|
|
Yes bool
|
|
DryRun bool
|
|
LinuxReleaseRepo string
|
|
Nvidia bool
|
|
NvidiaModel string
|
|
NvidiaType string
|
|
Amd bool
|
|
Intel bool
|
|
}
|
|
|
|
func ParseOptions(args []string, stderr io.Writer) (Options, error) {
|
|
var opts Options
|
|
var only string
|
|
fs := flag.NewFlagSet("bootstrap_windows_env", flag.ContinueOnError)
|
|
fs.SetOutput(stderr)
|
|
fs.StringVar(&only, "only", "", "run one phase: os, host, custom, config, or wsl")
|
|
fs.BoolVar(&opts.NoAI, "no-ai", false, "omit native AI CLIs and pass --no-ai to the Fedora guest")
|
|
fs.BoolVar(&opts.NoWSL, "no-wsl", false, "omit Fedora WSL provisioning and guest bootstrap")
|
|
fs.BoolVar(&opts.Yes, "yes", false, "execute the displayed plan without confirmation")
|
|
fs.BoolVar(&opts.DryRun, "dry-run", false, "detect state and display work without making changes")
|
|
fs.StringVar(&opts.LinuxReleaseRepo, "linux-release-repo", "JMR-dev/bootstrap_dev_env", "GitHub repository containing Linux bootstrap releases")
|
|
fs.BoolVar(&opts.Nvidia, "nvidia", false, "fetch and install Nvidia driver")
|
|
fs.StringVar(&opts.NvidiaModel, "model", "", "Nvidia GPU model (e.g. RTX 4090)")
|
|
fs.StringVar(&opts.NvidiaType, "type", "", "Nvidia driver type (Game Ready or Studio)")
|
|
fs.BoolVar(&opts.Amd, "amd", false, "fetch and run AMD auto-detection graphics driver tool")
|
|
fs.BoolVar(&opts.Intel, "intel", false, "fetch and install Intel Driver & Support Assistant")
|
|
if err := fs.Parse(args); err != nil {
|
|
return Options{}, err
|
|
}
|
|
if fs.NArg() != 0 {
|
|
return Options{}, fmt.Errorf("unexpected arguments: %v", fs.Args())
|
|
}
|
|
if only != "" {
|
|
opts.Only = Phase(only)
|
|
switch opts.Only {
|
|
case PhaseOS, PhaseHost, PhaseCustom, PhaseConfig, PhaseWSL:
|
|
default:
|
|
return Options{}, fmt.Errorf("invalid --only value %q: use os, host, custom, config, or wsl", only)
|
|
}
|
|
}
|
|
if opts.NoWSL && opts.Only == PhaseWSL {
|
|
return Options{}, fmt.Errorf("--only wsl cannot be combined with --no-wsl")
|
|
}
|
|
if opts.Nvidia && opts.Amd && opts.Intel && os.Getenv("BOOTSTRAP_INTEGRATION_TEST") != "true" {
|
|
return Options{}, fmt.Errorf("cannot combine --nvidia, --amd, and --intel")
|
|
}
|
|
if opts.Nvidia {
|
|
if opts.NvidiaModel == "" {
|
|
return Options{}, fmt.Errorf("--nvidia requires --model flag")
|
|
}
|
|
if opts.NvidiaType == "" {
|
|
return Options{}, fmt.Errorf("--nvidia requires --type flag")
|
|
}
|
|
if opts.NvidiaType != "Game Ready" && opts.NvidiaType != "Studio" {
|
|
return Options{}, fmt.Errorf("invalid --type value %q: use Game Ready or Studio", opts.NvidiaType)
|
|
}
|
|
} else if opts.NvidiaModel != "" || opts.NvidiaType != "" {
|
|
return Options{}, fmt.Errorf("--model and --type require --nvidia flag")
|
|
}
|
|
return opts, nil
|
|
}
|
|
|
|
func (o Options) Includes(phase Phase) bool {
|
|
if o.NoWSL && phase == PhaseWSL {
|
|
return false
|
|
}
|
|
return o.Only == "" || o.Only == phase
|
|
}
|
|
|
|
func SelectedPhases(opts Options) []Phase {
|
|
phases := make([]Phase, 0, len(PhaseOrder))
|
|
for _, phase := range PhaseOrder {
|
|
if opts.Includes(phase) {
|
|
phases = append(phases, phase)
|
|
}
|
|
}
|
|
return phases
|
|
}
|