From 89dcc07e216eb1f5a2d026e82b503e1c380c3f9f Mon Sep 17 00:00:00 2001 From: Alex Lovell-Troy Date: Fri, 22 Nov 2024 16:26:50 -0500 Subject: [PATCH 1/2] feat(tftp): implement TFTP server functionality and update dependencies --- .goreleaser.yml | 2 +- coresmd/main.go | 4 ++++ coresmd/tftp.go | 31 +++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 coresmd/tftp.go diff --git a/.goreleaser.yml b/.goreleaser.yml index 8e92342..2fd2ec6 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -10,7 +10,7 @@ before: builds: - id: coredhcp main: ./coredhcp/ - goos: + goos: # CoreDHCP only supports linux - linux goarch: - amd64 diff --git a/coresmd/main.go b/coresmd/main.go index b67ac32..4431e72 100644 --- a/coresmd/main.go +++ b/coresmd/main.go @@ -98,6 +98,10 @@ func setup4(args ...string) (handler.Handler4, error) { cache.RefreshLoop() + // Start tftpserver + log.Info("starting TFTP server on port 69 with directory /tftpboot") + go startTFTPServer("/tftpboot") + log.Infof("coresmd plugin initialized with base URL %s and validity duration %s", smdClient.BaseURL, cache.Duration.String()) return Handler4, nil diff --git a/coresmd/tftp.go b/coresmd/tftp.go new file mode 100644 index 0000000..dd0157a --- /dev/null +++ b/coresmd/tftp.go @@ -0,0 +1,31 @@ +package coresmd + +import ( + "io" + "os" + "path/filepath" + + "github.com/pin/tftp" +) + +func startTFTPServer(directory string) { + s := tftp.NewServer(readHandler(directory), nil) + err := s.ListenAndServe(":69") // default TFTP port + if err != nil { + log.Fatalf("failed to start TFTP server: %v", err) + } +} + +func readHandler(directory string) func(string, io.ReaderFrom) error { + return func(filename string, rf io.ReaderFrom) error { + filePath := filepath.Join(directory, filename) + file, err := os.Open(filePath) + if err != nil { + return err + } + defer file.Close() + + _, err = rf.ReadFrom(file) + return err + } +} diff --git a/go.mod b/go.mod index 5c5d00a..c801279 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( github.com/nxadm/tail v1.4.11 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pin/tftp v2.1.0+incompatible github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/go.sum b/go.sum index 0d8a7d6..7d2bee7 100644 --- a/go.sum +++ b/go.sum @@ -56,6 +56,8 @@ github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pin/tftp v2.1.0+incompatible h1:Yng4J7jv6lOc6IF4XoB5mnd3P7ZrF60XQq+my3FAMus= +github.com/pin/tftp v2.1.0+incompatible/go.mod h1:xVpZOMCXTy+A5QMjEVN0Glwa1sUvaJhFXbr/aAxuxGY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= From d3d3ba958a8730cdad1e5eb25cb060c93eaf787d Mon Sep 17 00:00:00 2001 From: Alex Lovell-Troy Date: Fri, 22 Nov 2024 17:22:43 -0500 Subject: [PATCH 2/2] Add ipxe binaries to the container --- Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Dockerfile b/Dockerfile index b5ce49e..d1b10e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,14 @@ RUN set -ex \ && rm -rf /var/cache/apk/* \ && rm -rf /tmp/* +# Download the latest ipxe binaries from https://github.com/OpenCHAMI/ipxe-binaries/releases and unpack them in the /tftpboot directory. +RUN set -ex \ + && mkdir -p /tftpboot \ + && latest_release_url=$(curl -s https://api.github.com/repos/OpenCHAMI/ipxe-binaries/releases/latest | jq -r '.assets[] | select(.name == "ipxe.tar.gz") | .browser_download_url') \ + && curl -L $latest_release_url -o /tmp/ipxe.tar.gz \ + && tar -xzvf /tmp/ipxe.tar.gz -C /tftpboot \ + && rm /tmp/ipxe.tar.gz + COPY coredhcp /coredhcp