diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 85e01a9..6aace2f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,20 +31,25 @@ jobs: - name: Check out code into the Go module directory uses: actions/checkout@v4 - - name: Set up Go 1.23 + - name: Set up Go 1.24 uses: actions/setup-go@v5 with: - go-version: "1.23" + go-version: "1.24" cache: false - - name: make ipxe + - name: fake ipxe binary run: | - make ipxe + mkdir -p ipxe/ipxe/bin + touch ipxe/ipxe/bin/ipxe.bin - name: Lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v7 with: - args: -p bugs -p unused --timeout=3m + args: --timeout=3m + + - name: remove fake ipxe binary + run: | + rm -rf ipxe/ipxe - name: Make tag run: | diff --git a/Dockerfile b/Dockerfile index f8fb913..43e9684 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # be aware that bookworm has a newer gcc which can not compile the older ipxe -FROM golang:1.23-bullseye as builder +FROM golang:1.24-bullseye AS builder WORKDIR /work COPY . . RUN apt update \ @@ -7,7 +7,6 @@ RUN apt update \ liblzma-dev \ && make ipxe pixie -FROM alpine:3.20 -RUN apk -U add ca-certificates +FROM gcr.io/distroless/static-debian12 COPY --from=builder /work/build/pixie /pixie ENTRYPOINT ["/pixie"] diff --git a/dhcp4/conn.go b/dhcp4/conn.go index 661400a..35bd4fd 100644 --- a/dhcp4/conn.go +++ b/dhcp4/conn.go @@ -229,7 +229,7 @@ func newPortableConn(port int) (conn, error) { } l := ipv4.NewPacketConn(c) if err = l.SetControlMessage(ipv4.FlagInterface, true); err != nil { - l.Close() + _ = l.Close() return nil, err } return &portableConn{l}, nil diff --git a/dhcp4/conn_linux.go b/dhcp4/conn_linux.go index 63fc0c5..7475b38 100644 --- a/dhcp4/conn_linux.go +++ b/dhcp4/conn_linux.go @@ -68,15 +68,15 @@ func newLinuxConn(port int) (conn, error) { } r, err := ipv4.NewRawConn(c) if err != nil { - c.Close() + _ = c.Close() return nil, err } if err = r.SetControlMessage(ipv4.FlagInterface, true); err != nil { - c.Close() + _ = c.Close() return nil, fmt.Errorf("setting packet filter: %w", err) } if err = r.SetBPF(filter); err != nil { - c.Close() + _ = c.Close() return nil, fmt.Errorf("setting packet filter: %w", err) } diff --git a/dhcp4/conn_test.go b/dhcp4/conn_test.go index ed98e00..268c4c1 100644 --- a/dhcp4/conn_test.go +++ b/dhcp4/conn_test.go @@ -127,7 +127,7 @@ func TestPortableConn(t *testing.T) { } port := l.LocalAddr().(*net.UDPAddr).Port addr := l.LocalAddr().String() - l.Close() + _ = l.Close() c, err := newPortableConn(port) if err != nil { diff --git a/dhcp4/packet.go b/dhcp4/packet.go index 27aecf8..47e75ab 100644 --- a/dhcp4/packet.go +++ b/dhcp4/packet.go @@ -332,7 +332,7 @@ func Unmarshal(bs []byte) (*Packet, error) { return nil, fmt.Errorf("BOOTP message type (%d) doesn't match DHCP message type (%s", bs[0], ret.Type) } default: - return nil, fmt.Errorf("Unknown DHCP message type %d", ret.Type) + return nil, fmt.Errorf("unknown DHCP message type %d", ret.Type) } return ret, nil diff --git a/dhcp6/conn.go b/dhcp6/conn.go index 5796e9d..5901e53 100644 --- a/dhcp6/conn.go +++ b/dhcp6/conn.go @@ -30,12 +30,12 @@ func NewConn(addr, port string) (*Conn, error) { } pc := ipv6.NewPacketConn(c) if err := pc.JoinGroup(ifi, &net.UDPAddr{IP: group}); err != nil { - pc.Close() + _ = pc.Close() return nil, err } if err := pc.SetControlMessage(ipv6.FlagSrc|ipv6.FlagDst, true); err != nil { - pc.Close() + _ = pc.Close() return nil, err } @@ -57,12 +57,12 @@ func (c *Conn) Close() error { func InterfaceByAddress(ifAddr string) (*net.Interface, error) { allIfis, err := net.Interfaces() if err != nil { - return nil, fmt.Errorf("Error getting network interface information: %w", err) + return nil, fmt.Errorf("error getting network interface information: %w", err) } for _, ifi := range allIfis { addrs, err := ifi.Addrs() if err != nil { - return nil, fmt.Errorf("Error getting network interface address information: %w", err) + return nil, fmt.Errorf("error getting network interface address information: %w", err) } for _, addr := range addrs { if addrToIP(addr).String() == ifAddr { @@ -70,7 +70,7 @@ func InterfaceByAddress(ifAddr string) (*net.Interface, error) { } } } - return nil, fmt.Errorf("Couldn't find an interface with address %s", ifAddr) + return nil, fmt.Errorf("couldn't find an interface with address %s", ifAddr) } func addrToIP(a net.Addr) net.IP { @@ -116,7 +116,7 @@ func (c *Conn) SendDHCP(dst net.IP, p []byte) error { } _, err := c.conn.WriteTo(p, nil, dstAddr) if err != nil { - return fmt.Errorf("Error sending a reply to %s: %w", dst.String(), err) + return fmt.Errorf("error sending a reply to %s: %w", dst.String(), err) } return nil } diff --git a/dhcp6/options.go b/dhcp6/options.go index f0261d9..50c36b3 100644 --- a/dhcp6/options.go +++ b/dhcp6/options.go @@ -210,10 +210,10 @@ func (o Options) Marshal() ([]byte, error) { for _, o := range multipleOptions { serialized, err := o.Marshal() if err != nil { - return nil, fmt.Errorf("Error serializing option value: %w", err) + return nil, fmt.Errorf("error serializing option value: %w", err) } if err := binary.Write(buffer, binary.BigEndian, serialized); err != nil { - return nil, fmt.Errorf("Error serializing option value: %w", err) + return nil, fmt.Errorf("error serializing option value: %w", err) } } } @@ -226,15 +226,15 @@ func (o *Option) Marshal() ([]byte, error) { err := binary.Write(buffer, binary.BigEndian, o.ID) if err != nil { - return nil, fmt.Errorf("Error serializing option id: %w", err) + return nil, fmt.Errorf("error serializing option id: %w", err) } err = binary.Write(buffer, binary.BigEndian, o.Length) if err != nil { - return nil, fmt.Errorf("Error serializing option length: %w", err) + return nil, fmt.Errorf("error serializing option length: %w", err) } err = binary.Write(buffer, binary.BigEndian, o.Value) if err != nil { - return nil, fmt.Errorf("Error serializing option value: %w", err) + return nil, fmt.Errorf("error serializing option value: %w", err) } return buffer.Bytes(), nil } diff --git a/dhcp6/packet.go b/dhcp6/packet.go index 05994d3..c0ccc00 100644 --- a/dhcp6/packet.go +++ b/dhcp6/packet.go @@ -50,7 +50,7 @@ func (p *Packet) Marshal() ([]byte, error) { return nil, fmt.Errorf("packet has malformed options section: %w", err) } - ret := make([]byte, len(marshalledOptions)+4, len(marshalledOptions)+4) + ret := make([]byte, len(marshalledOptions)+4) ret[0] = byte(p.Type) copy(ret[1:], p.TransactionID[:]) copy(ret[4:], marshalledOptions) @@ -71,7 +71,7 @@ func (p *Packet) ShouldDiscard(serverDuid []byte) error { case MsgRelease: return nil // FIX ME! default: - return fmt.Errorf("Unknown packet") + return fmt.Errorf("unknown packet") } } @@ -100,7 +100,7 @@ func shouldDiscardRequest(p *Packet, serverDuid []byte) error { if !options.HasServerID() { return fmt.Errorf("'Request' packet has no server id option") } - if bytes.Compare(options.ServerID(), serverDuid) != 0 { + if !bytes.Equal(options.ServerID(), serverDuid) { return fmt.Errorf("'Request' packet's server id option (%d) is different from ours (%d)", options.ServerID(), serverDuid) } return nil @@ -114,7 +114,7 @@ func shouldDiscardInformationRequest(p *Packet, serverDuid []byte) error { if options.HasIaNa() || options.HasIaTa() { return fmt.Errorf("'Information-request' packet has an IA option present") } - if options.HasServerID() && (bytes.Compare(options.ServerID(), serverDuid) != 0) { + if options.HasServerID() && (!bytes.Equal(options.ServerID(), serverDuid)) { return fmt.Errorf("'Information-request' packet's server id option (%d) is different from ours (%d)", options.ServerID(), serverDuid) } return nil diff --git a/dhcp6/packet_builder.go b/dhcp6/packet_builder.go index 241a1a4..d066775 100644 --- a/dhcp6/packet_builder.go +++ b/dhcp6/packet_builder.go @@ -65,7 +65,7 @@ func (b *PacketBuilder) makeMsgAdvertise(transactionID [3]byte, serverDUID, clie MakeIaAddrOption(association.IPAddress, b.PreferredLifetime, b.ValidLifetime))) } retOptions.Add(MakeOption(OptServerID, serverDUID)) - if 0x10 == clientArchType { // HTTPClient + if clientArchType == 0x10 { // HTTPClient retOptions.Add(MakeOption(OptVendorClass, []byte{0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient } retOptions.Add(MakeOption(OptBootfileURL, bootFileURL)) @@ -92,7 +92,7 @@ func (b *PacketBuilder) makeMsgReply(transactionID [3]byte, serverDUID, clientID MakeStatusOption(2, err.Error()))) } retOptions.Add(MakeOption(OptServerID, serverDUID)) - if 0x10 == clientArchType { // HTTPClient + if clientArchType == 0x10 { // HTTPClient retOptions.Add(MakeOption(OptVendorClass, []byte{0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient } retOptions.Add(MakeOption(OptBootfileURL, bootFileURL)) @@ -108,7 +108,7 @@ func (b *PacketBuilder) makeMsgInformationRequestReply(transactionID [3]byte, se retOptions := make(Options) retOptions.Add(MakeOption(OptClientID, clientID)) retOptions.Add(MakeOption(OptServerID, serverDUID)) - if 0x10 == clientArchType { // HTTPClient + if clientArchType == 0x10 { // HTTPClient retOptions.Add(MakeOption(OptVendorClass, []byte{0, 0, 0, 0, 0, 10, 72, 84, 84, 80, 67, 108, 105, 101, 110, 116})) // HTTPClient } retOptions.Add(MakeOption(OptBootfileURL, bootFileURL)) @@ -124,7 +124,7 @@ func (b *PacketBuilder) makeMsgReleaseReply(transactionID [3]byte, serverDUID, c retOptions.Add(MakeOption(OptClientID, clientID)) retOptions.Add(MakeOption(OptServerID, serverDUID)) - v := make([]byte, 19, 19) + v := make([]byte, 19) copy(v[2:], []byte("Release received.")) retOptions.Add(MakeOption(OptStatusCode, v)) diff --git a/dhcp6/pool/random_address_pool.go b/dhcp6/pool/random_address_pool.go index 4bde3e4..45374cc 100644 --- a/dhcp6/pool/random_address_pool.go +++ b/dhcp6/pool/random_address_pool.go @@ -90,7 +90,7 @@ func (p *RandomAddressPool) ReserveAddresses(clientID []byte, interfaceIDs [][]b continue } if uint64(len(p.usedIps)) == p.poolSize { - return ret, fmt.Errorf("No more free ip addresses are currently available in the pool") + return ret, fmt.Errorf("no more free ip addresses are currently available in the pool") } for { @@ -134,10 +134,7 @@ func (p *RandomAddressPool) ReleaseAddresses(clientID []byte, interfaceIDs [][]b // expireIdentityAssociations releases IP addresses in identity associations that reached the end of valid lifetime // back into the address pool. Note it should be called from under the RandomAddressPool.lock. func (p *RandomAddressPool) expireIdentityAssociations() { - for { - if p.identityAssociationExpirations.Size() < 1 { - break - } + for p.identityAssociationExpirations.Size() >= 1 { expiration := p.identityAssociationExpirations.Peek().(*associationExpiration) if p.timeNow().Before(expiration.expiresAt) { break diff --git a/go.mod b/go.mod index c6e2831..d5efa66 100644 --- a/go.mod +++ b/go.mod @@ -1,44 +1,43 @@ module github.com/metal-stack/pixie -go 1.23.0 +go 1.24 require ( - github.com/metal-stack/metal-api v0.39.3-0.20241112084334-e7ae92577d45 + github.com/metal-stack/metal-api v0.41.2 github.com/metal-stack/v v1.0.3 github.com/pin/tftp/v3 v3.1.0 - github.com/prometheus/client_golang v1.20.5 - github.com/spf13/cobra v1.8.1 - github.com/spf13/viper v1.20.0-alpha.6 - github.com/stretchr/testify v1.9.0 - golang.org/x/crypto v0.29.0 - golang.org/x/net v0.31.0 - google.golang.org/grpc v1.68.0 + github.com/prometheus/client_golang v1.22.0 + github.com/spf13/cobra v1.9.1 + github.com/spf13/viper v1.20.1 + github.com/stretchr/testify v1.10.0 + golang.org/x/crypto v0.38.0 + golang.org/x/net v0.40.0 + google.golang.org/grpc v1.72.2 ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-viper/mapstructure/v2 v2.2.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/klauspost/compress v1.17.11 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.60.1 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/sagikazarmark/locafero v0.6.0 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.64.0 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/sagikazarmark/locafero v0.9.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.7.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/afero v1.14.0 // indirect + github.com/spf13/cast v1.8.0 // indirect + github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect - google.golang.org/protobuf v1.35.1 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/text v0.25.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 997ee3f..aef3470 100644 --- a/go.sum +++ b/go.sum @@ -2,90 +2,124 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/metal-stack/metal-api v0.39.3-0.20241112084334-e7ae92577d45 h1:tw8Qt0Vg2JvZayZjY69sdc7SmxMeufY1D0r0um692qo= -github.com/metal-stack/metal-api v0.39.3-0.20241112084334-e7ae92577d45/go.mod h1:VIBQva4qsl9WAl78Djr6oFKO21TLT3/MKNlC4US72sc= +github.com/metal-stack/metal-api v0.41.2 h1:Vt7X2TkSM747+4+lbTeu6Xgsy85d28al7/nC3hzDj/Q= +github.com/metal-stack/metal-api v0.41.2/go.mod h1:rWW1yimU4+CFhUXlzSrxfqanXYXuI3pprPhpbkhlgH4= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= github.com/metal-stack/v v1.0.3/go.mod h1:YTahEu7/ishwpYKnp/VaW/7nf8+PInogkfGwLcGPdXg= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pin/tftp/v3 v3.1.0 h1:rQaxd4pGwcAJnpId8zC+O2NX3B2/NscjDZQaqEjuE7c= github.com/pin/tftp/v3 v3.1.0/go.mod h1:xwQaN4viYL019tM4i8iecm++5cGxSqen6AJEOEyEI0w= 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= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.60.1 h1:FUas6GcOw66yB/73KC+BOZoFJmbo/1pojoILArPAaSc= -github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= -github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= -github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= +github.com/prometheus/common v0.64.0 h1:pdZeA+g617P7oGv1CzdTzyeShxAGrTBsolKNOLQPGO4= +github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= +github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= +github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= -github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/locafero v0.8.0 h1:mXaMVw7IqxNBxfv3LdWt9MDmcWDQ1fagDH918lOdVaQ= +github.com/sagikazarmark/locafero v0.8.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= +github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k= +github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= -github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.20.0-alpha.6 h1:f65Cr/+2qk4GfHC0xqT/isoupQppwN5+VLRztUGTDbY= -github.com/spf13/viper v1.20.0-alpha.6/go.mod h1:CGBZzv0c9fOUASm6rfus4wdeIjR/04NOLq1P4KRhX3k= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= +github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= +github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= +github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk= +github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4= +github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= -google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/ipxe/ipxe.go b/ipxe/ipxe.go index 24264b2..44a8cce 100644 --- a/ipxe/ipxe.go +++ b/ipxe/ipxe.go @@ -2,7 +2,6 @@ package ipxe import ( "embed" - _ "embed" "path" ) diff --git a/pixiecore/boot_configuration.go b/pixiecore/boot_configuration.go index 081f822..1c2ec1c 100644 --- a/pixiecore/boot_configuration.go +++ b/pixiecore/boot_configuration.go @@ -98,10 +98,12 @@ func (bc *APIBootConfiguration) GetBootURL(id []byte, clientArchType uint16) ([] return nil, err } if resp.StatusCode != http.StatusOK { - resp.Body.Close() + _ = resp.Body.Close() return nil, fmt.Errorf("%s: %s", reqURL, http.StatusText(resp.StatusCode)) } - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() buf := new(bytes.Buffer) _, err = buf.ReadFrom(resp.Body) diff --git a/pixiecore/booters.go b/pixiecore/booters.go index fa98179..9064b63 100644 --- a/pixiecore/booters.go +++ b/pixiecore/booters.go @@ -147,7 +147,7 @@ func (b *apibooter) getAPIResponse(m Machine) (io.ReadCloser, error) { return nil, err } if resp.StatusCode != http.StatusOK { - resp.Body.Close() + _ = resp.Body.Close() return nil, fmt.Errorf("%s: %s", reqURL, http.StatusText(resp.StatusCode)) } @@ -157,7 +157,9 @@ func (b *apibooter) getAPIResponse(m Machine) (io.ReadCloser, error) { func (b *apibooter) BootSpec(m Machine) (*Spec, error) { body, err := b.getAPIResponse(m) if body != nil { - defer body.Close() + defer func() { + _ = body.Close() + }() } if err != nil { return nil, err @@ -267,7 +269,7 @@ func (b *apibooter) ReadBootFile(id ID) (io.ReadCloser, int64, error) { } fi, err := f.Stat() if err != nil { - f.Close() + _ = f.Close() return nil, -1, err } ret, sz = f, fi.Size() @@ -302,7 +304,9 @@ func (b *apibooter) WriteBootFile(id ID, body io.Reader) error { if resp.StatusCode != 200 { return fmt.Errorf("POST %q failed: %s", u, resp.Status) } - defer resp.Body.Close() + defer func() { + _ = resp.Body.Close() + }() return nil } diff --git a/pixiecore/booters_test.go b/pixiecore/booters_test.go index 4dc2d41..01319f6 100644 --- a/pixiecore/booters_test.go +++ b/pixiecore/booters_test.go @@ -36,7 +36,9 @@ func mustRead(f io.ReadCloser, sz int64, err error) string { if err != nil { panic(err) } - defer f.Close() + defer func() { + _ = f.Close() + }() bs, err := io.ReadAll(f) if err != nil { panic(err) diff --git a/pixiecore/http.go b/pixiecore/http.go index f801d94..f809fc2 100644 --- a/pixiecore/http.go +++ b/pixiecore/http.go @@ -133,7 +133,9 @@ func (s *Server) handleFile(w http.ResponseWriter, r *http.Request) { http.Error(w, "couldn't get file", http.StatusInternalServerError) return } - defer f.Close() + defer func() { + _ = f.Close() + }() if sz >= 0 { w.Header().Set("Content-Length", strconv.FormatInt(sz, 10)) } else { @@ -167,7 +169,7 @@ func (s *Server) handleBooting(w http.ResponseWriter, r *http.Request) { // Return a no-op boot script, to satisfy iPXE. It won't get used, // the boot script deletes this image immediately after // downloading. - fmt.Fprintf(w, "# Booting") + _, _ = fmt.Fprintf(w, "# Booting") macStr := r.URL.Query().Get("mac") if macStr == "" { diff --git a/pixiecore/pixicorev6.go b/pixiecore/pixicorev6.go index ccfc629..628308f 100644 --- a/pixiecore/pixicorev6.go +++ b/pixiecore/pixicorev6.go @@ -57,7 +57,7 @@ func (s *ServerV6) Serve() error { // Wait for either a fatal error, or Shutdown(). err = <-s.errs - dhcp.Close() + _ = dhcp.Close() s.Log.Info("stopped...") return err diff --git a/pixiecore/pixiecore.go b/pixiecore/pixiecore.go index 03cf717..460d903 100644 --- a/pixiecore/pixiecore.go +++ b/pixiecore/pixiecore.go @@ -235,20 +235,20 @@ func (s *Server) Serve() error { } pxe, err := net.ListenPacket("udp4", fmt.Sprintf("%s:%d", s.Address, s.PXEPort)) if err != nil { - dhcp.Close() + _ = dhcp.Close() return err } http, err := net.Listen("tcp", fmt.Sprintf("%s:%d", s.Address, s.HTTPPort)) if err != nil { - dhcp.Close() - pxe.Close() + _ = dhcp.Close() + _ = pxe.Close() return err } metrics, err := net.Listen("tcp", fmt.Sprintf("%s:%d", s.MetricsAddress, s.MetricsPort)) if err != nil { - dhcp.Close() - pxe.Close() - http.Close() + _ = dhcp.Close() + _ = pxe.Close() + _ = http.Close() return err } @@ -272,10 +272,10 @@ func (s *Server) Serve() error { // Wait for either a fatal error, or Shutdown(). err = <-s.errs - dhcp.Close() - pxe.Close() - http.Close() - metrics.Close() + _ = dhcp.Close() + _ = pxe.Close() + _ = http.Close() + _ = metrics.Close() return err }