Skip to content

Commit

Permalink
Add ability to set hostname via DHCP during install
Browse files Browse the repository at this point in the history
This is an alternative to harvester#717

Here we switch the order of the "Configure hostname" and "Configure
network" installer pages, so that "Configure network" comes first.
This allows us to set DHCLIENT_SET_HOSTNAME="yes" when applying the
management NIC config.  If DHCP is used, and the DHCP server is
configured to specify a hostname, the live environment will then
automatically have its hostname set to whatever it got from the DHCP
server.  Then, on the hostname page, we can default the hostname to
that value, which the user is still free to change should they wish.

If DHCP isn't used, or if the DHCP server doesn't specify a hostname,
there's no change to the existing behaviour - the hostname field will
initially be blank, and the user will be required to fill it out.

Related issue: harvester/harvester#1444

Signed-off-by: Tim Serong <[email protected]>
  • Loading branch information
tserong committed May 8, 2024
1 parent c8ffa53 commit 43ae32f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 26 deletions.
64 changes: 39 additions & 25 deletions pkg/console/install_panels.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ func addDiskPanel(c *Console) error {
if installModeOnly {
return showNext(c, passwordConfirmPanel, passwordPanel)
}
return showHostnamePage(c)
return showNetworkPage(c)
}

diskConfirm := func(_ *gocui.Gui, _ *gocui.View) error {
Expand Down Expand Up @@ -840,7 +840,7 @@ func addAskCreatePanel(c *Console) error {
return showRolePage(c)
}
if alreadyInstalled {
return showHostnamePage(c)
return showNetworkPage(c)
}
return showDiskPage(c)
},
Expand Down Expand Up @@ -898,7 +898,7 @@ func addAskRolePanel(c *Console) error {
c.config.Install.Role = selected
askRoleV.Close()
if alreadyInstalled {
return showHostnamePage(c)
return showNetworkPage(c)
}
return showDiskPage(c)
},
Expand Down Expand Up @@ -1182,6 +1182,13 @@ func showHostnamePage(c *Console) error {
return showNext(c, hostnamePanel)
}

func setupNetwork(c *Console) ([]byte, error) {
return applyNetworks(
mgmtNetwork,
c.config.Hostname,
)
}

func addHostnamePanel(c *Console) error {
hostnameV, err := widgets.NewInput(c.Gui, hostnamePanel, hostNameLabel, false)
if err != nil {
Expand All @@ -1199,20 +1206,22 @@ func addHostnamePanel(c *Console) error {
return c.setContentByName(hostnameValidatorPanel, message)
}

getNextPagePanel := func() []string {
return []string{dnsServersPanel}
}

next := func() error {
output, err := setupNetwork(c)
if err != nil {
return fmt.Errorf("Configure network failed: %s %s", string(output), err)
}
c.CloseElements(hostnamePanel, hostnameValidatorPanel)
return showNetworkPage(c)
return showNext(c, getNextPagePanel()...)
}

prev := func(_ *gocui.Gui, _ *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)
return showNetworkPage(c)
}

validate := func() (string, error) {
Expand All @@ -1234,6 +1243,16 @@ func addHostnamePanel(c *Console) error {

hostnameV.PreShow = func() error {
c.Gui.Cursor = true
if c.config.Hostname == "" {
// On the first run through the interactive installer, the hostname is
// not yet set in the harvester config, but we might have been given a
// new hostname via DHCP...
currentHostname, err := os.Hostname()
if currentHostname != "rancher" && err == nil {
// ...if so, let's take that as the default.
c.config.Hostname = currentHostname
}
}
hostnameV.Value = c.config.Hostname
return c.setContentByName(titlePanel, hostnameTitle)
}
Expand Down Expand Up @@ -1360,15 +1379,8 @@ func addNetworkPanel(c *Console) error {
)
}

setupNetwork := func() ([]byte, error) {
return applyNetworks(
mgmtNetwork,
c.config.Hostname,
)
}

preGotoNextPage := func() (string, error) {
output, err := setupNetwork()
output, err := setupNetwork(c)
if err != nil {
return fmt.Sprintf("Configure network failed: %s %s", string(output), err), nil
}
Expand All @@ -1391,10 +1403,6 @@ func addNetworkPanel(c *Console) error {
return "", nil
}

getNextPagePanel := func() []string {
return []string{dnsServersPanel}
}

gotoNextPage := func(fromPanel string) error {
if err := networkValidatorV.Show(); err != nil {
return err
Expand All @@ -1421,7 +1429,7 @@ func addNetworkPanel(c *Console) error {
spinner.Stop(false, "")
g.Update(func(_ *gocui.Gui) error {
closeThisPage()
return showNext(c, getNextPagePanel()...)
return showHostnamePage(c)
})
}
}(c.Gui)
Expand All @@ -1430,7 +1438,13 @@ func addNetworkPanel(c *Console) error {

gotoPrevPage := func(_ *gocui.Gui, _ *gocui.View) error {
closeThisPage()
return showHostnamePage(c)
if alreadyInstalled {
if c.config.Install.Mode == config.ModeJoin {
return showNext(c, askRolePanel)
}
return showNext(c, askCreatePanel)
}
return showDiskPage(c)
}
// askInterfaceV
askInterfaceV.PreShow = func() error {
Expand Down
33 changes: 32 additions & 1 deletion pkg/console/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,37 @@ func applyNetworks(network config.Network, hostname string) ([]byte, error) {
return nil, err
}

// If called without a hostname set, we enable setting hostname via the
// DHCP server, in case the DHCP server is configured to give us a
// hostname we can use by default.
//
// If we move the network interface page of the installer so it's before
// the hostname page, this function will activate once the management
// NIC is configured, and if the DHCP server is configured correctly,
// the system hostname will be set to the one provided by the server.
// Later, on the hostname page, we can default the hostname field to
// the current system hostname.
//
// Note that this change means we need to apply the network config
// *again* after the hostname page, so that the hostname will be
// written to /etc/hostname.
//
// I really need to refactor this function a bit so we can just apply
// the network config first, then apply only the hostname change once we
// leave the hostname screen, rather than reapplying all the network
// interface config twice, but this works as-is for a proof of concept.
dhclientSetHostname := "no"
if hostname == "" {
dhclientSetHostname = "yes"
}
output, err := exec.Command("sed", "-i",
fmt.Sprintf(`s/^DHCLIENT_SET_HOSTNAME=.*/DHCLIENT_SET_HOSTNAME="%s"/`, dhclientSetHostname),
"/etc/sysconfig/network/dhcp").CombinedOutput()
if err != nil {
logrus.Error(err, string(output))
return nil, err
}

conf := &yipSchema.YipConfig{
Name: "Network Configuration",
Stages: map[string][]yipSchema.Stage{
Expand All @@ -33,7 +64,7 @@ func applyNetworks(network config.Network, hostname string) ([]byte, error) {
},
},
}
_, err := config.UpdateManagementInterfaceConfig(&conf.Stages["live"][1], network, true)
_, err = config.UpdateManagementInterfaceConfig(&conf.Stages["live"][1], network, true)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 43ae32f

Please sign in to comment.