Skip to content

Commit

Permalink
Merge pull request #206 from jakefhyde/40901-hostname-truncation
Browse files Browse the repository at this point in the history
Add hostname override flag to create
  • Loading branch information
jakefhyde authored Apr 20, 2023
2 parents fc90414 + bd7ac59 commit 1ab6e01
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 15 deletions.
28 changes: 19 additions & 9 deletions commands/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ var (
Usage: "Use a custom provisioning script instead of installing docker",
Value: "",
},
cli.StringFlag{
Name: "hostname-override",
Usage: "Specify hostname to use during cloud-init instead of default generated hostname",
Value: "",
},
}
)

Expand Down Expand Up @@ -231,14 +236,15 @@ func cmdCreateInner(c CommandLine, api libmachine.API) error {
osFlag := drivers.DriverOSFlag(h.Driver)

customInstallScript := c.String("custom-install-script")
h.HostOptions.HostnameOverride = c.String("hostname-override")
if customInstallScript != "" {
h.HostOptions.CustomInstallScript = customInstallScript
h.HostOptions.AuthOptions = nil
h.HostOptions.EngineOptions = nil
h.HostOptions.SwarmOptions = nil

if userdataFlag != "" {
err = updateUserdataFile(driverOpts, name, userdataFlag, osFlag, customInstallScript)
err = updateUserdataFile(driverOpts, name, h.HostOptions.HostnameOverride, userdataFlag, osFlag, customInstallScript)
if err != nil {
return fmt.Errorf("[cmdCreateInner] could not alter cloud-init file: %v", err)
}
Expand Down Expand Up @@ -498,7 +504,7 @@ func gzipEncode(data []byte) (string, error) {
// updateUserdataFile If the user has provided a userdata file, then we add the customInstallScript to their userdata file.
// This assumes that the user-provided userdata file start with a shebang or `#cloud-config`
// If the user has not provided any userdata file, then we set the customInstallScript as the userdata file.
func updateUserdataFile(driverOpts *rpcdriver.RPCFlags, machineName, userdataFlag, osFlag, customInstallScript string) error {
func updateUserdataFile(driverOpts *rpcdriver.RPCFlags, machineName, hostname, userdataFlag, osFlag, customInstallScript string) error {
var userdataContent []byte
var err error
userdataFile := driverOpts.String(userdataFlag)
Expand All @@ -508,13 +514,13 @@ func updateUserdataFile(driverOpts *rpcdriver.RPCFlags, machineName, userdataFla
// Always convert to cloud config if user data is not provided
userdataContent = []byte("#cloud-config")
} else {
userdataContent, err = ioutil.ReadFile(userdataFile)
userdataContent, err = os.ReadFile(userdataFile)
if err != nil {
return err
}
}

customScriptContent, err := ioutil.ReadFile(customInstallScript)
customScriptContent, err := os.ReadFile(customInstallScript)
if err != nil {
return err
}
Expand All @@ -527,7 +533,7 @@ func updateUserdataFile(driverOpts *rpcdriver.RPCFlags, machineName, userdataFla
}
defer modifiedUserdataFile.Close()

if err := replaceUserdataFile(machineName, machineOS, userdataContent, customScriptContent, modifiedUserdataFile); err != nil {
if err := replaceUserdataFile(machineName, machineOS, hostname, userdataContent, customScriptContent, modifiedUserdataFile); err != nil {
return err
}

Expand All @@ -540,7 +546,7 @@ func updateUserdataFile(driverOpts *rpcdriver.RPCFlags, machineName, userdataFla
// and passes the script path to commonCloudConfig
// RK - sets the hostname based on OS as cloud-init (linux) and cloudbase-init (windows) diverge
// on how hostnames are set in cloud-config (userdata)
func writeCloudConfig(machineName, encodedData, machineOS string, cf map[interface{}]interface{}, newUserDataFile *os.File) error {
func writeCloudConfig(machineName, encodedData, machineOS, hostname string, cf map[interface{}]interface{}, newUserDataFile *os.File) error {
command := "sh"
path := "/usr/local/custom_script/install.sh"
key := "hostname"
Expand All @@ -555,7 +561,11 @@ func writeCloudConfig(machineName, encodedData, machineOS string, cf map[interfa
key = "set_hostname"
}
if _, ok := cf[key]; !ok {
cf[key] = machineName
if hostname != "" {
cf[key] = hostname
} else {
cf[key] = machineName
}
log.Debugf("[writeCloudConfig] wrote %s field for %s machine %s", key, machineOS, machineName)
}
return commonCloudConfig(encodedData, command, path, cf, newUserDataFile)
Expand Down Expand Up @@ -598,7 +608,7 @@ func commonCloudConfig(encodedData, command, path string, cf map[interface{}]int
// temp file for this content.
// If the user-provided userdata file starts with a shebang, then we can add it to the customScriptContent and add data to the `runcmd` directive.
// fi the user-provided userdata file is in cloud-config format, then we add the customScriptContent to the `runcmd` directive.
func replaceUserdataFile(machineName, machineOS string, userdataContent, customScriptContent []byte, newUserDataFile *os.File) error {
func replaceUserdataFile(machineName, machineOS, hostname string, userdataContent, customScriptContent []byte, newUserDataFile *os.File) error {
var err error
var encodedData string
cf := make(map[interface{}]interface{})
Expand Down Expand Up @@ -632,7 +642,7 @@ func replaceUserdataFile(machineName, machineOS string, userdataContent, customS
return fmt.Errorf("existing userdata file does not begin with '#!' or '#cloud-config'")
}

return writeCloudConfig(machineName, encodedData, machineOS, cf, newUserDataFile)
return writeCloudConfig(machineName, encodedData, machineOS, hostname, cf, newUserDataFile)
}

// appendValueToListInCloudConfig appends a value to a list or creates one if it does not exist at the given key within the cloud config
Expand Down
3 changes: 2 additions & 1 deletion libmachine/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Options struct {
Memory int
Disk int
CustomInstallScript string
HostnameOverride string
MachineOS string
EngineOptions *engine.Options
SwarmOptions *swarm.Options
Expand Down Expand Up @@ -303,7 +304,7 @@ func (h *Host) Provision() error {

if h.HostOptions.CustomInstallScript != "" {
log.Infof("Machine %s was provisioned with a custom install script, using this script for provisioning", h.Name)
return provision.WithCustomScript(provisioner, h.HostOptions.CustomInstallScript)
return provision.WithCustomScript(provisioner, h.HostOptions.CustomInstallScript, h.HostOptions.HostnameOverride)
}

return provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions)
Expand Down
2 changes: 1 addition & 1 deletion libmachine/libmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (api *Client) performCreate(h *host.Host) error {
log.Infof("Provisioning with %s...", provisioner.String())
if h.HostOptions.CustomInstallScript != "" {
log.Infof("Provisioning with custom install script via SSH, not installing Docker...")
return provision.WithCustomScript(provisioner, h.HostOptions.CustomInstallScript)
return provision.WithCustomScript(provisioner, h.HostOptions.CustomInstallScript, h.HostOptions.HostnameOverride)
} else {
if err := provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil {
return err
Expand Down
12 changes: 8 additions & 4 deletions libmachine/provision/custom_script.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ package provision

import (
"fmt"
"io/ioutil"
"os"

"github.com/rancher/machine/libmachine/provision/pkgaction"
)

func WithCustomScript(provisioner Provisioner, customScriptPath string) error {
func WithCustomScript(provisioner Provisioner, customScriptPath, hostname string) error {
if provisioner == nil {
return nil
}

if err := provisioner.SetHostname(provisioner.GetDriver().GetMachineName()); err != nil {
if hostname == "" {
hostname = provisioner.GetDriver().GetMachineName()
}

if err := provisioner.SetHostname(hostname); err != nil {
return err
}

Expand All @@ -22,7 +26,7 @@ func WithCustomScript(provisioner Provisioner, customScriptPath string) error {
}
}

customScriptContents, err := ioutil.ReadFile(customScriptPath)
customScriptContents, err := os.ReadFile(customScriptPath)
if err != nil {
return fmt.Errorf("unable to read file %s: %v", customScriptPath, err)
}
Expand Down

0 comments on commit 1ab6e01

Please sign in to comment.