Skip to content

Commit

Permalink
feat: add human-friendly entry point
Browse files Browse the repository at this point in the history
* Added /start as entry point, for humans and iPXE

The '/poll/1/${netX/mac:hexhyp}' is fairly iPXE internal, not something
that invites curious people to look better at shoelaces. Neither it is
looking nice in DHCP server configuration.

This change adds a HTTP handler for '/start'. And '/start' points
to '/poll/1/${netX/mac:hexhyp}'. The benefit of it is that human visible
documentation can replace the "voodoo" '/poll/1/${netX/mac:hexhyp}'
with "friendly" '/start'.

Because it is an addition are the existing HTTP handlers not effected,
neither the installed deployments effected.

Signed-off-by: Geert Stappers <[email protected]>
  • Loading branch information
stappersg authored Jan 4, 2023
1 parent 0463152 commit 1c79728
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 5 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ with your TFTP and Shoelaces server addresses.
# dhcp.conf
next-server <your-tftp-server>;
if exists user-class and option user-class = "iPXE" {
filename "http://<shoelaces-server>/poll/1/${netX/mac:hexhyp}";
filename "http://<shoelaces-server>/start";
} else {
filename "undionly.kpxe";
}
Expand All @@ -153,7 +153,7 @@ putting it in `dnsmasq.d/ipxe.conf`:
```txt
dhcp-match=set:ipxe,175 # iPXE sends a 175 option.
dhcp-boot=tag:!ipxe,undionly.kpxe
dhcp-boot=http://<shoelaces-server>/poll/1/${netX/mac:hexhyp}
dhcp-boot=http://<shoelaces-server>/start
```

The **${netX/mac:hexhyp}** strings represents the MAC address of the booting
Expand Down
4 changes: 2 additions & 2 deletions docs/shoelaces.8.scd
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ debug=true
# dhcp.conf
next-server <your-tftp-server>;
if exists user-class and option user-class = "iPXE" {
filename "http://<shoelaces-server>/poll/1/${netX/mac:hexhyp}";
filename "http://<shoelaces-server>/start";
} else {
filename "undionly.kpxe";
}
Expand All @@ -100,7 +100,7 @@ the following snippet:
```
dhcp-match=set:ipxe,175 # iPXE sends a 175 option.
dhcp-boot=tag:!ipxe,undionly.kpxe
dhcp-boot=http://<shoelaces-server>/poll/1/${netX/mac:hexhyp}
dhcp-boot=http://<shoelaces-server>/start
```

A TFTP server such as *tftpd*(8) must be configured to serve the iPXE executable,
Expand Down
10 changes: 10 additions & 0 deletions internal/handlers/polling.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ import (
"github.com/thousandeyes/shoelaces/internal/utils"
)

// StartPollingHandler is called by iPXE boot agents. It returns the poll script.
func StartPollingHandler(w http.ResponseWriter, r *http.Request) {
env := envFromRequest(r)

script := polling.GenStartScript(env.Logger, env.BaseURL)

w.Write([]byte(script))
}


// PollHandler is called by iPXE boot agents. It returns the boot script
// specified on the configuration or, if the host is unknown, it makes it
// retry for a while until the user specifies alternative IPXE boot script.
Expand Down
30 changes: 30 additions & 0 deletions internal/polling/polling.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ import (
type ManualAction int

const (
startScript = "#!ipxe\n" +
"echo Shoelaces starts polling\n" +
"chain --autofree --replace \\\n" +
" http://{{.baseURL}}/poll/1/${netX/mac:hexhyp}\n" +
"#\n" +
"#\n" +
"# Do\n" +
"# curl http://{{.baseURL}}/poll/1/06-66-de-ad-be-ef\n" +
"# to get an idea about what iPXE will receive.\n"

maxRetry = 10

retryScript = "#!ipxe\n" +
Expand Down Expand Up @@ -226,6 +236,26 @@ func setHostName(params map[string]interface{}, mac string) {
}
}

func GenStartScript(logger log.Logger, baseURL string) string {
variablesMap := map[string]interface{}{}
parsedTemplate := &bytes.Buffer{}

tmpl, err := template.New("retry").Parse(startScript)
if err != nil {
logger.Info("component", "polling", "msg", "Error parsing start template")
panic(err)
}

variablesMap["baseURL"] = baseURL
err = tmpl.Execute(parsedTemplate, variablesMap)
if err != nil {
logger.Info("component", "polling", "msg", "Error executing start template")
panic(err)
}

return parsedTemplate.String()
}

func genBootScript(logger log.Logger, templateRenderer *templates.ShoelacesTemplates, baseURL string, script *mappings.Script) string {
script.Params["baseURL"] = utils.BaseURLforEnvName(baseURL, script.Environment)
text, err := templateRenderer.RenderTemplate(logger, script.Name, script.Params, script.Environment)
Expand Down
3 changes: 3 additions & 0 deletions internal/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ func ShoelacesRouter(env *environment.Environment) http.Handler {
r.PathPrefix("/configs/").Handler(http.StripPrefix("/configs/",
handlers.TemplateServer()))

// Starting point for iPXE boot agents, usualy defined by DHCP server.
// Gets the iPXE boot agents into the polling loop.
r.HandleFunc("/start", handlers.StartPollingHandler).Methods("GET")
// Called by iPXE boot agents, returns boot script specified on the configuration
// or if the host is unknown makes it retry for a while until the user specifies
// alternative ipxe boot script
Expand Down
2 changes: 1 addition & 1 deletion web/templates/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ <h3 class="text-center">Waiting for MACs...</h3>
<div class="center-block col-md-6">
<div class="card">
<div class="card-body">
<p class="text-center">Shoelaces is waiting for a server to boot. Using iPXE, your server should reach the following endpoint: <br /> <b class="text-primary-custom">http://{{ .BaseURL }}/poll/1/&#60;MAC&#62;</b> </p>
<p class="text-center">Shoelaces is waiting for a server to boot. Using iPXE, your server should reach the following endpoint: <br /> <b class="text-primary-custom">http://{{ .BaseURL }}/start</b> </p>
<p class="text-center">You can automate this process by setting up a DHCP server.</p>
</div>
</div>
Expand Down

0 comments on commit 1c79728

Please sign in to comment.