mirror of
https://github.com/siderolabs/talos.git
synced 2025-09-11 00:41:13 +02:00
This adds support for downloading the machine config over TFTP. This will allow users to avoid having to setup an HTTP server, and use whatever they are using for PXE. Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
67 lines
1.3 KiB
Go
67 lines
1.3 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package download
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
|
|
"github.com/pin/tftp"
|
|
)
|
|
|
|
// NewTFTPTransport returns an http.RoundTripper capable of handling the TFTP
|
|
// protocol.
|
|
func NewTFTPTransport() http.RoundTripper {
|
|
return &tftpRoundTripper{}
|
|
}
|
|
|
|
var _ http.RoundTripper = &tftpRoundTripper{}
|
|
|
|
type tftpRoundTripper struct{}
|
|
|
|
func (t *tftpRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
addr := req.URL.Host
|
|
|
|
if req.URL.Port() == "" {
|
|
addr += ":69"
|
|
}
|
|
|
|
c, err := tftp.NewClient(addr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
w, err := c.Receive(req.URL.Path, "octet")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
buf := &bytes.Buffer{}
|
|
|
|
written, err := w.WriteTo(buf)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if expected, ok := w.(tftp.IncomingTransfer).Size(); ok {
|
|
if written != expected {
|
|
return nil, fmt.Errorf("expected %d bytes, got %d", expected, written)
|
|
}
|
|
}
|
|
|
|
return &http.Response{
|
|
Status: "200 OK",
|
|
StatusCode: 200,
|
|
Proto: "TFTP/1.0",
|
|
ProtoMajor: 1,
|
|
ProtoMinor: 0,
|
|
Body: ioutil.NopCloser(buf),
|
|
ContentLength: -1,
|
|
Request: req,
|
|
}, nil
|
|
}
|