mirror of
https://github.com/rancher/os.git
synced 2025-08-29 11:34:42 +00:00
Add ipxe support
This commit is contained in:
parent
b4cc0014b2
commit
0e46d19194
@ -4,7 +4,7 @@ RUN zypper ref
|
||||
ARG DAPPER_HOST_ARCH
|
||||
ENV ARCH $DAPPER_HOST_ARCH
|
||||
|
||||
RUN zypper in -y bash git gcc docker vim less file curl wget ca-certificates make mkisofs go1.16
|
||||
RUN zypper in -y bash git gcc docker vim less file curl wget ca-certificates make mkisofs go1.16 qemu-tools
|
||||
RUN go get golang.org/x/tools/cmd/goimports
|
||||
RUN if [ "${ARCH}" == "amd64" ]; then \
|
||||
curl -sL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s v1.40.1; \
|
||||
|
4
Makefile
4
Makefile
@ -68,6 +68,10 @@ ami:
|
||||
run:
|
||||
./scripts/run
|
||||
|
||||
.PHONY: run
|
||||
pxe:
|
||||
./scripts/run pxe
|
||||
|
||||
all-amis: \
|
||||
ami-us-west-1 \
|
||||
ami-us-west-2
|
||||
|
@ -2,18 +2,36 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
"github.com/rancher/os/pkg/config"
|
||||
"github.com/rancher/os/pkg/install"
|
||||
"github.com/sirupsen/logrus"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
output = flag.Bool("automatic", false, "Check for and run automatic installation")
|
||||
printConfig = flag.Bool("print-config", false, "Print effective configuration and exit")
|
||||
configFile = flag.String("config-file", "", "Config file to use, local file or http/tftp URL")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if err := install.Run(*output); err != nil {
|
||||
if *printConfig {
|
||||
cfg, err := config.ReadConfig(*configFile)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
data, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
os.Stdout.Write(data)
|
||||
return
|
||||
}
|
||||
|
||||
if err := install.Run(*output, *configFile); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1 @@
|
||||
/usr/lib/systemd/system/ros-installer.service
|
17
framework/files/usr/lib/systemd/system/ros-installer.service
Normal file
17
framework/files/usr/lib/systemd/system/ros-installer.service
Normal file
@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=RancherOS Automatic Installation
|
||||
Documentation=https://github.com/rancher/os
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
Before=getty-pre.target serial-getty@ttyS0.service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
EnvironmentFile=-/etc/default/%N
|
||||
EnvironmentFile=-/etc/sysconfig/%N
|
||||
TimeoutStartSec=0
|
||||
StandardOutput=journal+console
|
||||
ExecStart=/usr/sbin/ros-installer -automatic
|
3
go.mod
3
go.mod
@ -4,12 +4,13 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/mattn/go-isatty v0.0.10
|
||||
github.com/pin/tftp v2.1.0+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rancher/wrangler v0.8.3
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tredoe/osutil v1.0.5
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||
gopkg.in/pin/tftp.v2 v2.1.0
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
|
4
go.sum
4
go.sum
@ -244,6 +244,8 @@ github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/pin/tftp v2.1.0+incompatible h1:Yng4J7jv6lOc6IF4XoB5mnd3P7ZrF60XQq+my3FAMus=
|
||||
github.com/pin/tftp v2.1.0+incompatible/go.mod h1:xVpZOMCXTy+A5QMjEVN0Glwa1sUvaJhFXbr/aAxuxGY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -473,6 +475,8 @@ gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/pin/tftp.v2 v2.1.0 h1:QbLeBeg/UoYf1dkjJS5nLj/x9t8gFQRG06fq5PEOWDw=
|
||||
gopkg.in/pin/tftp.v2 v2.1.0/go.mod h1:OptUw+bblWIH7jYabWNBP0CAH4/sBtD2N0oBeXcRG98=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
|
@ -1,6 +1,6 @@
|
||||
package config
|
||||
|
||||
type Rancher struct {
|
||||
type RancherOS struct {
|
||||
Install Install `json:"install,omitempty"`
|
||||
}
|
||||
|
||||
@ -15,31 +15,22 @@ type Install struct {
|
||||
NoFormat bool `json:"noFormat,omitempty"`
|
||||
Debug bool `json:"debug,omitempty"`
|
||||
TTY string `json:"tty,omitempty"`
|
||||
ServerURL string `json:"serverUrl,omitempty"`
|
||||
Token string `json:"token,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty"`
|
||||
Rancher Rancher `json:"rancher,omitempty"`
|
||||
RancherOS RancherOS `json:"rancheros,omitempty"`
|
||||
}
|
||||
|
||||
type YipConfig struct {
|
||||
Stages map[string][]Stage `json:"stages,omitempty"`
|
||||
Rancherd Rancherd `json:"rancherd,omitempty"`
|
||||
}
|
||||
|
||||
type Stage struct {
|
||||
Users map[string]User `json:"users,omitempty"`
|
||||
}
|
||||
|
||||
type Rancherd struct {
|
||||
Server string `json:"server,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
Token string `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
PasswordHash string `json:"passwd,omitempty"`
|
||||
|
@ -3,6 +3,7 @@ package config
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
@ -10,18 +11,20 @@ import (
|
||||
values "github.com/rancher/wrangler/pkg/data"
|
||||
"github.com/rancher/wrangler/pkg/data/convert"
|
||||
schemas2 "github.com/rancher/wrangler/pkg/schemas"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
schemas = schemas2.EmptySchemas().Init(func(s *schemas2.Schemas) *schemas2.Schemas {
|
||||
s.DefaultMapper = func() schemas2.Mapper {
|
||||
return schemas2.Mappers{
|
||||
defaultMappers = schemas2.Mappers{
|
||||
NewToMap(),
|
||||
NewToSlice(),
|
||||
NewToBool(),
|
||||
&FuzzyNames{},
|
||||
}
|
||||
}
|
||||
schemas = schemas2.EmptySchemas().Init(func(s *schemas2.Schemas) *schemas2.Schemas {
|
||||
s.AddMapper("config", defaultMappers)
|
||||
s.AddMapper("rancherOS", defaultMappers)
|
||||
s.AddMapper("install", defaultMappers)
|
||||
return s
|
||||
}).MustImport(Config{})
|
||||
schema = schemas.Schema("config")
|
||||
@ -40,7 +43,7 @@ func mapToEnv(prefix string, data map[string]interface{}) []string {
|
||||
var result []string
|
||||
for k, v := range data {
|
||||
keyName := strings.ToUpper(prefix + convert.ToYAMLKey(k))
|
||||
keyName = strings.ReplaceAll(keyName, "RANCHER_", "COS_")
|
||||
keyName = strings.ReplaceAll(keyName, "RANCHEROS_", "COS_")
|
||||
if data, ok := v.(map[string]interface{}); ok {
|
||||
subResult := mapToEnv(keyName+"_", data)
|
||||
result = append(result, subResult...)
|
||||
@ -51,14 +54,86 @@ func mapToEnv(prefix string, data map[string]interface{}) []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func ReadConfig() (Config, error) {
|
||||
result := Config{}
|
||||
|
||||
data, err := readCmdline()
|
||||
if err != nil {
|
||||
return result, err
|
||||
func readFile(path string) (result map[string]interface{}, _ error) {
|
||||
result = map[string]interface{}{}
|
||||
defer func() {
|
||||
if v, ok := result["install"]; ok {
|
||||
values.PutValue(result, v, "rancheros", "install")
|
||||
}
|
||||
if err := schema.Mapper.ToInternal(data); err != nil {
|
||||
}()
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(path, "http://"):
|
||||
fallthrough
|
||||
case strings.HasPrefix(path, "https://"):
|
||||
resp, err := http.Get(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
buffer, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read %s: %w", path, err)
|
||||
}
|
||||
|
||||
return result, yaml.Unmarshal(buffer, &result)
|
||||
case strings.HasPrefix(path, "tftp://"):
|
||||
return tftpGet(path)
|
||||
}
|
||||
|
||||
f, err := ioutil.ReadFile(path)
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := map[string]interface{}{}
|
||||
if err := yaml.Unmarshal(f, &data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
type reader func() (map[string]interface{}, error)
|
||||
|
||||
func merge(readers ...reader) (map[string]interface{}, error) {
|
||||
d := map[string]interface{}{}
|
||||
for _, r := range readers {
|
||||
newData, err := r()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := schema.Mapper.ToInternal(newData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d = values.MergeMapsConcatSlice(d, newData)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
func readConfigMap(cfg string) (map[string]interface{}, error) {
|
||||
var (
|
||||
err error
|
||||
data map[string]interface{}
|
||||
)
|
||||
return merge(func() (map[string]interface{}, error) {
|
||||
data, err = merge(readCmdline,
|
||||
func() (map[string]interface{}, error) {
|
||||
return readFile(cfg)
|
||||
},
|
||||
)
|
||||
return data, err
|
||||
}, func() (map[string]interface{}, error) {
|
||||
return readFile(convert.ToString(values.GetValueN(data, "rancheros", "install", "configUrl")))
|
||||
})
|
||||
}
|
||||
|
||||
func ReadConfig(cfg string) (result Config, err error) {
|
||||
data, err := readConfigMap(cfg)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
@ -72,7 +147,11 @@ func readCmdline() (map[string]interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
bytes, err := ioutil.ReadFile("/proc/cmdline")
|
||||
procCmdLine := os.Getenv("PROC_CMDLINE")
|
||||
if procCmdLine == "" {
|
||||
procCmdLine = "/proc/cmdline"
|
||||
}
|
||||
bytes, err := ioutil.ReadFile(procCmdLine)
|
||||
if os.IsNotExist(err) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
|
@ -30,7 +30,9 @@ func (f *FuzzyNames) addName(name, toName string) {
|
||||
}
|
||||
|
||||
func (f *FuzzyNames) ModifySchema(schema *schemas2.Schema, schemas *schemas2.Schemas) error {
|
||||
if f.names == nil {
|
||||
f.names = map[string]string{}
|
||||
}
|
||||
|
||||
for name := range schema.ResourceFields {
|
||||
if strings.HasSuffix(name, "s") && len(name) > 1 {
|
||||
|
41
pkg/config/tftpget.go
Normal file
41
pkg/config/tftpget.go
Normal file
@ -0,0 +1,41 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
|
||||
"gopkg.in/pin/tftp.v2"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func tftpGet(tftpURL string) (map[string]interface{}, error) {
|
||||
u, err := url.Parse(tftpURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
host, _, err := net.SplitHostPort(u.Host)
|
||||
if err != nil {
|
||||
host = u.Host + ":69"
|
||||
}
|
||||
|
||||
fmt.Printf("Downloading config from host %s, file %s\n", host, u.Path)
|
||||
client, err := tftp.NewClient(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
writerTo, err := client.Receive(u.Path, "octet")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
if _, err := writerTo.WriteTo(buf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := map[string]interface{}{}
|
||||
return result, yaml.Unmarshal(buf.Bytes(), &result)
|
||||
}
|
@ -6,10 +6,10 @@ import (
|
||||
)
|
||||
|
||||
func PrintInstall(cfg Config) ([]byte, error) {
|
||||
if cfg.Rancher.Install.Password != "" {
|
||||
cfg.Rancher.Install.Password = "******"
|
||||
if cfg.RancherOS.Install.Password != "" {
|
||||
cfg.RancherOS.Install.Password = "******"
|
||||
}
|
||||
data, err := convert.EncodeToMap(cfg.Rancher.Install)
|
||||
data, err := convert.EncodeToMap(cfg.RancherOS.Install)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -10,10 +10,6 @@ import (
|
||||
)
|
||||
|
||||
func Ask(cfg *config.Config) error {
|
||||
if cfg.Rancher.Install.Silent {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := AskInstallDevice(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -22,7 +18,7 @@ func Ask(cfg *config.Config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.Rancher.Install.ConfigURL == "" {
|
||||
if cfg.RancherOS.Install.ConfigURL == "" {
|
||||
if err := AskGithub(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -30,17 +26,13 @@ func Ask(cfg *config.Config) error {
|
||||
if err := AskPassword(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := AskServerAgent(cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func AskInstallDevice(cfg *config.Config) error {
|
||||
if cfg.Rancher.Install.Device != "" {
|
||||
if cfg.RancherOS.Install.Device != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -54,69 +46,22 @@ func AskInstallDevice(cfg *config.Config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Rancher.Install.Device = "/dev/" + fields[i]
|
||||
cfg.RancherOS.Install.Device = "/dev/" + fields[i]
|
||||
return nil
|
||||
}
|
||||
|
||||
func AskToken(cfg *config.Config, server bool) error {
|
||||
var (
|
||||
token string
|
||||
err error
|
||||
)
|
||||
|
||||
if cfg.Rancher.Install.Token != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
msg := "Token or cluster secret"
|
||||
if server {
|
||||
msg += " (optional)"
|
||||
}
|
||||
if server {
|
||||
token, err = questions.PromptOptional(msg+": ", "")
|
||||
} else {
|
||||
token, err = questions.Prompt(msg+": ", "")
|
||||
}
|
||||
cfg.Rancher.Install.Token = token
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func isServer(cfg *config.Config) (bool, error) {
|
||||
opts := []string{"server", "agent"}
|
||||
func isServer(cfg *config.Config) (bool, bool, error) {
|
||||
opts := []string{"server", "agent", "none"}
|
||||
i, err := questions.PromptFormattedOptions("Run as server or agent?", 0, opts...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, false, err
|
||||
}
|
||||
|
||||
return i == 0, nil
|
||||
}
|
||||
|
||||
func AskServerAgent(cfg *config.Config) error {
|
||||
if cfg.Rancher.Install.ServerURL != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
server, err := isServer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if server {
|
||||
return AskToken(cfg, true)
|
||||
}
|
||||
|
||||
url, err := questions.Prompt("URL of server: ", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Rancher.Install.ServerURL = url
|
||||
|
||||
return AskToken(cfg, false)
|
||||
return i == 0, i == 1, nil
|
||||
}
|
||||
|
||||
func AskPassword(cfg *config.Config) error {
|
||||
if cfg.Rancher.Install.Silent || cfg.Rancher.Install.Password != "" {
|
||||
if cfg.RancherOS.Install.Silent || cfg.RancherOS.Install.Password != "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -140,12 +85,12 @@ func AskPassword(cfg *config.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
cfg.Rancher.Install.Password = pass
|
||||
cfg.RancherOS.Install.Password = pass
|
||||
return nil
|
||||
}
|
||||
|
||||
func AskGithub(cfg *config.Config) error {
|
||||
if len(cfg.SSHAuthorizedKeys) > 0 || cfg.Rancher.Install.Password != "" {
|
||||
if len(cfg.SSHAuthorizedKeys) > 0 || cfg.RancherOS.Install.Password != "" || cfg.RancherOS.Install.Silent {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -167,7 +112,7 @@ func AskGithub(cfg *config.Config) error {
|
||||
}
|
||||
|
||||
func AskConfigURL(cfg *config.Config) error {
|
||||
if cfg.Rancher.Install.ConfigURL != "" {
|
||||
if cfg.RancherOS.Install.ConfigURL != "" || cfg.RancherOS.Install.Silent {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -185,6 +130,6 @@ func AskConfigURL(cfg *config.Config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Rancher.Install.ConfigURL = str
|
||||
cfg.RancherOS.Install.ConfigURL = str
|
||||
return nil
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -10,16 +11,16 @@ import (
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func Run(automatic bool) error {
|
||||
cfg, err := config.ReadConfig()
|
||||
func Run(automatic bool, configFile string) error {
|
||||
cfg, err := config.ReadConfig(configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if automatic && !cfg.Rancher.Install.Automatic {
|
||||
if automatic && !cfg.RancherOS.Install.Automatic {
|
||||
return nil
|
||||
} else if automatic {
|
||||
cfg.Rancher.Install.Silent = true
|
||||
cfg.RancherOS.Install.Silent = true
|
||||
}
|
||||
|
||||
err = Ask(&cfg)
|
||||
@ -44,7 +45,7 @@ func runInstall(cfg config.Config, output string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !cfg.Rancher.Install.Silent {
|
||||
if !cfg.RancherOS.Install.Silent {
|
||||
val, err := questions.PromptBool("\nConfiguration\n"+"-------------\n\n"+
|
||||
string(installBytes)+
|
||||
"\nYour disk will be formatted and installed with the above configuration.\nContinue?", false)
|
||||
@ -53,30 +54,20 @@ func runInstall(cfg config.Config, output string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.Rancher.Install.ConfigURL == "" {
|
||||
yip := config.YipConfig{
|
||||
Rancherd: config.Rancherd{
|
||||
Server: cfg.Rancher.Install.ServerURL,
|
||||
Token: cfg.Rancher.Install.Token,
|
||||
},
|
||||
}
|
||||
if cfg.Rancher.Install.ServerURL == "" {
|
||||
yip.Rancherd.Role = "cluster-init"
|
||||
} else {
|
||||
yip.Rancherd.Role = "agent"
|
||||
}
|
||||
if cfg.Rancher.Install.Password != "" || len(cfg.SSHAuthorizedKeys) > 0 {
|
||||
if cfg.RancherOS.Install.ConfigURL == "" && !cfg.RancherOS.Install.Silent {
|
||||
yip := config.YipConfig{}
|
||||
if cfg.RancherOS.Install.Password != "" || len(cfg.SSHAuthorizedKeys) > 0 {
|
||||
yip.Stages = map[string][]config.Stage{
|
||||
"network": {{
|
||||
Users: map[string]config.User{
|
||||
"root": {
|
||||
Name: "root",
|
||||
PasswordHash: cfg.Rancher.Install.Password,
|
||||
PasswordHash: cfg.RancherOS.Install.Password,
|
||||
SSHAuthorizedKeys: cfg.SSHAuthorizedKeys,
|
||||
},
|
||||
}},
|
||||
}}
|
||||
cfg.Rancher.Install.Password = ""
|
||||
cfg.RancherOS.Install.Password = ""
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(yip)
|
||||
@ -87,7 +78,7 @@ func runInstall(cfg config.Config, output string) error {
|
||||
if err := ioutil.WriteFile(output+".yip", data, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Rancher.Install.ConfigURL = output + ".yip"
|
||||
cfg.RancherOS.Install.ConfigURL = output + ".yip"
|
||||
}
|
||||
|
||||
ev, err := config.ToEnv(cfg)
|
||||
@ -95,6 +86,8 @@ func runInstall(cfg config.Config, output string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
printEnv(cfg)
|
||||
|
||||
cmd := exec.Command("cos-installer")
|
||||
cmd.Env = append(os.Environ(), ev...)
|
||||
cmd.Stdout = os.Stdout
|
||||
@ -102,3 +95,19 @@ func runInstall(cfg config.Config, output string) error {
|
||||
cmd.Stderr = os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func printEnv(cfg config.Config) {
|
||||
if cfg.RancherOS.Install.Password != "" {
|
||||
cfg.RancherOS.Install.Password = "<removed>"
|
||||
}
|
||||
|
||||
ev2, err := config.ToEnv(cfg)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Install environment:")
|
||||
for _, ev := range ev2 {
|
||||
fmt.Println(ev)
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,30 @@ isoinfo -x /rootfs.squashfs -R -i build/output.iso > build/output.squashfs
|
||||
isoinfo -x /boot/kernel.xz -R -i build/output.iso > build/output-kernel
|
||||
isoinfo -x /boot/rootfs.xz -R -i build/output.iso > build/output-initrd
|
||||
|
||||
|
||||
RELEASE_URL=${RELEASE_URL:-https://github.com/rancher/os/releases/download}
|
||||
INSTALL_CFG=${RELEASE_URL}/${VERSION}/example-cloud-init
|
||||
PXE_ASSET_VERSION="\${version}-\${arch}"
|
||||
if [ "${TAG}" = "dev" ]; then
|
||||
RELEASE_URL=tftp://10.0.2.2
|
||||
INSTALL_CFG=
|
||||
VERSION=${TAG}
|
||||
PXE_ASSET_VERSION=${TAG}
|
||||
fi
|
||||
|
||||
cat > build/output.ipxe << EOF
|
||||
#!ipxe
|
||||
set arch ${ARCH}
|
||||
set version ${VERSION}
|
||||
set url ${RELEASE_URL}/\${version}
|
||||
set kernel rancheros-${PXE_ASSET_VERSION}-kernel
|
||||
set initrd rancheros-${PXE_ASSET_VERSION}-initrd
|
||||
set rootfs rancheros-${PXE_ASSET_VERSION}.squashfs
|
||||
kernel \${url}/\${kernel} initrd=\${initrd} ip=dhcp rd.cos.disable root=live:\${url}/\${rootfs} rancheros.install.automatic=true rancheros.install.config_url=\${config} console=tty1 console=ttyS0
|
||||
initrd \${url}/\${initrd}
|
||||
boot
|
||||
EOF
|
||||
|
||||
mkdir -p dist/artifacts
|
||||
for i in build/output*; do
|
||||
mv -f $i dist/artifacts/rancheros-${TAG}${i##build/output}
|
||||
|
27
scripts/run
27
scripts/run
@ -11,10 +11,34 @@ fi
|
||||
touch meta-data
|
||||
touch user-data
|
||||
rm -f seed.iso
|
||||
genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
|
||||
mkisofs -output seed.iso -volid cidata -joliet -rock user-data meta-data
|
||||
BOOT=
|
||||
|
||||
if [ "$1" = "pxe" ]; then
|
||||
shift 1
|
||||
if [ ! -e ipxe.cfg ]; then
|
||||
if [ ! -e ../dist/artifacts/rancheros-dev.ipxe ]; then
|
||||
make -C .. package
|
||||
fi
|
||||
if [ -e ../dist/artifacts/rancheros-dev.ipxe ]; then
|
||||
cp ../dist/artifacts/rancheros-dev.ipxe ipxe.cfg
|
||||
fi
|
||||
fi
|
||||
BOOT="-boot cn"
|
||||
|
||||
if [ ! -e dev ]; then
|
||||
ln -s ../dist/artifacts dev
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ "$1" == "" ] && [ ! -e output.iso ]; then
|
||||
make -C .. build iso
|
||||
fi
|
||||
|
||||
#-bios /usr/share/qemu/OVMF.fd \
|
||||
qemu-system-x86_64 \
|
||||
$BOOT \
|
||||
-enable-kvm \
|
||||
-m ${MEMORY:=4096} \
|
||||
-machine accel=${ACCEL:="kvm"} \
|
||||
@ -23,6 +47,7 @@ qemu-system-x86_64 \
|
||||
-serial mon:stdio \
|
||||
-rtc base=utc,clock=rt \
|
||||
-chardev socket,path=qga.sock,server,nowait,id=qga0 \
|
||||
-nic user,tftp=./,bootfile=/ipxe.cfg \
|
||||
-device virtio-serial \
|
||||
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0 \
|
||||
-drive if=virtio,media=disk,file=disk.img \
|
||||
|
Loading…
Reference in New Issue
Block a user