Skip to content

Commit

Permalink
installer: add role to specify the capability of node
Browse files Browse the repository at this point in the history
  Now support `default` or `etcd` role.
  - default means the master node (control-plane, etcd, master)
  - etcd means the etcd node (etcd)

  NOTE: this only supports with join mode because the first node needs to
  be the master node.

Signed-off-by: Vicente Cheng <[email protected]>
  • Loading branch information
Vicente-Cheng authored and bk201 committed Dec 7, 2023
1 parent 28fb14a commit 35f62da
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 5 deletions.
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ type Install struct {
Debug bool `json:"debug,omitempty"`
TTY string `json:"tty,omitempty"`
ForceGPT bool `json:"forceGpt,omitempty"`
Role string `json:"role,omitempty"`

// Following options are not cOS installer flag
ForceMBR bool `json:"forceMbr,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/config/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ const (
ModeUpgrade = "upgrade"
ModeInstall = "install"

RoleDefault = "default"
RoleEtcd = "etcd"

NetworkMethodDHCP = "dhcp"
NetworkMethodStatic = "static"
NetworkMethodNone = "none"
Expand Down
1 change: 1 addition & 0 deletions pkg/console/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
vipPanel = "vipPanel"
vipTextPanel = "vipTextPanel"
ntpServersPanel = "ntpServersPanel"
askRolePanel = "askRolePanel"

hostnameTitle = "Configure hostname for this instance"
networkTitle = "Configure network"
Expand Down
80 changes: 75 additions & 5 deletions pkg/console/install_panels.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ func setPanels(c *Console) error {
addNotePanel,
addFooterPanel,
addAskCreatePanel,
addAskRolePanel,
addDiskPanel,
addHostnamePanel,
addNetworkPanel,
Expand Down Expand Up @@ -423,7 +424,7 @@ func addDiskPanel(c *Console) error {
return false, updateValidatorMessage(err.Error())
}
}
return true, nil;
return true, nil
}
closeThisPage := func() {
c.CloseElements(
Expand All @@ -439,12 +440,15 @@ func addDiskPanel(c *Console) error {
gotoPrevPage := func(g *gocui.Gui, v *gocui.View) error {
closeThisPage()
diskConfirmed = false
if c.config.Install.Mode == config.ModeJoin {
return showNext(c, askRolePanel)
}
return showNext(c, askCreatePanel)
}
gotoNextPage := func(g *gocui.Gui, v *gocui.View) error {
// Don't proceed to the next page if disk size validation fails
if valid, err := validateAllDiskSizes(); !valid || err != nil {
return err;
return err
}

installDisk := c.config.Install.Device
Expand Down Expand Up @@ -492,7 +496,7 @@ func addDiskPanel(c *Console) error {
if len(diskOpts) > 1 {
// Show error if disk size validation fails, but allow proceeding to next field
if _, err := validateAllDiskSizes(); err != nil {
return err;
return err
}
if device == dataDisk {
return showNext(c, persistentSizePanel, dataDiskPanel)
Expand All @@ -505,7 +509,7 @@ func addDiskPanel(c *Console) error {
}
// Show error if disk size validation fails, but allow proceeding to next field
if _, err := validateAllDiskSizes(); err != nil {
return err;
return err
}
return showNext(c, persistentSizePanel)
}
Expand Down Expand Up @@ -540,7 +544,7 @@ func addDiskPanel(c *Console) error {
}
// Show error if disk size validation fails, but allow proceeding to next field
if _, err := validateAllDiskSizes(); err != nil {
return err;
return err
}
return showNext(c, persistentSizePanel)
}
Expand Down Expand Up @@ -721,6 +725,10 @@ func addAskCreatePanel(c *Console) error {
installModeOnly = true
}

if c.config.Install.Mode == config.ModeCreate {
c.config.Install.Role = config.RoleDefault
}

askCreateV.Close()

if selected == config.ModeCreate {
Expand All @@ -732,6 +740,9 @@ func addAskCreatePanel(c *Console) error {

// all packages are already install
// configure hostname and network
if c.config.Install.Mode == config.ModeJoin {
return showRolePage(c)
}
if alreadyInstalled {
return showHostnamePage(c)
}
Expand All @@ -742,6 +753,59 @@ func addAskCreatePanel(c *Console) error {
return nil
}

func showRolePage(c *Console) error {
setLocation := createVerticalLocatorWithName(c)

if err := setLocation(askRolePanel, 3); err != nil {
return err
}

return showNext(c, askRolePanel)
}

func addAskRolePanel(c *Console) error {
askOptionsFunc := func() ([]widgets.Option, error) {
return []widgets.Option{
{
Value: config.RoleDefault,
Text: "Default Role (Master or Worker)",
}, {
Value: config.RoleEtcd,
Text: "Worker (Etcd only)",
},
}, nil
}
askRoleV, err := widgets.NewSelect(c.Gui, askRolePanel, "", askOptionsFunc)
if err != nil {
return err
}
gotoPrevPage := func(g *gocui.Gui, v *gocui.View) error {
c.CloseElements(askRolePanel)
return showNext(c, askCreatePanel)
}
askRoleV.PreShow = func() error {
askRoleV.Value = c.config.Install.Role
return c.setContentByName(titlePanel, "Choose installation role")
}
askRoleV.KeyBindings = map[gocui.Key]func(*gocui.Gui, *gocui.View) error{
gocui.KeyEnter: func(g *gocui.Gui, v *gocui.View) error {
selected, err := askRoleV.GetData()
if err != nil {
return err
}
c.config.Install.Role = selected
askRoleV.Close()
if alreadyInstalled {
return showHostnamePage(c)
}
return showDiskPage(c)
},
gocui.KeyEsc: gotoPrevPage,
}
c.AddElement(askRolePanel, askRoleV)
return nil
}

func addServerURLPanel(c *Console) error {
serverURLV, err := widgets.NewInput(c.Gui, serverURLPanel, "Management address", false)
if err != nil {
Expand Down Expand Up @@ -1041,6 +1105,9 @@ func addHostnamePanel(c *Console) error {
prev := func(g *gocui.Gui, v *gocui.View) error {
c.CloseElements(hostnamePanel, hostnameValidatorPanel)
if alreadyInstalled {
if c.config.Install.Mode == config.ModeJoin {
return showNext(c, askRolePanel)
}
return showNext(c, askCreatePanel)
}
return showDiskPage(c)
Expand Down Expand Up @@ -1732,6 +1799,9 @@ func addConfirmInstallPanel(c *Console) error {
return err
}
options := fmt.Sprintf("install mode: %v\n", c.config.Install.Mode)
if !installModeOnly {
options += fmt.Sprintf("install role: %v\n", c.config.Install.Role)
}
options += fmt.Sprintf("hostname: %v\n", c.config.OS.Hostname)
if userInputData.NTPServers != "" {
options += fmt.Sprintf("ntp servers: %v\n", userInputData.NTPServers)
Expand Down
16 changes: 16 additions & 0 deletions pkg/console/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,14 @@ func doInstall(g *gocui.Gui, hvstConfig *config.HarvesterConfig, webhooks Render
return err
}

// specific the node label for the specific node role
if hvstConfig.Role == config.RoleEtcd {
if hvstConfig.Labels == nil {
hvstConfig.Labels = make(map[string]string)
}
hvstConfig.Labels[util.HarvesterEtcdNodeLabelKey] = "true"
}

env, elementalConfig, err := generateEnvAndConfig(g, hvstConfig)
if err != nil {
return err
Expand Down Expand Up @@ -768,6 +776,14 @@ func configureInstalledNode(g *gocui.Gui, hvstConfig *config.HarvesterConfig, we
ctx := context.TODO()
webhooks.Handle(EventInstallStarted)

// specific the node label for the specific node role
if hvstConfig.Role == config.RoleEtcd {
if hvstConfig.Labels == nil {
hvstConfig.Labels = make(map[string]string)
}
hvstConfig.Labels[util.HarvesterEtcdNodeLabelKey] = "true"
}

// skip rancherd and network config in the cos config
cosConfig, cosConfigFile, hvstConfigFile, err := generateTempConfigFiles(hvstConfig)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions pkg/util/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
)

var (
HarvesterNodeRoleLabelPrefix = "node-role.harvesterhci.io/"
HarvesterEtcdNodeLabelKey = HarvesterNodeRoleLabelPrefix + "etcd"

sizeRegexp = regexp.MustCompile(`^(\d+)(Mi|Gi)$`)
)

Expand Down

0 comments on commit 35f62da

Please sign in to comment.