Skip to content

Commit

Permalink
feat: rework the way Sidero Agent boots and configures networking
Browse files Browse the repository at this point in the history
1. Update `PKGS` to the latest version which has kernel with modules.
2. Pull in `udevd`, kernel modules into the Sidero Agent initramfs.
3. Stop doing kernel network configuration (`ip=dhcp`).
4. Run `udevd` in `initramfs` to auto-load kernel modules based on
   hardware information.
5. Pass MAC address of the NIC used to PXE boot from iPXE down to Sidero
   Agent.
6. In the Sidero Agent, run DHCP configuration on the link passed by
   MAC.

Slightly refactored Sidero Agent code by pulling apart `main.go` into
smaller pieces.

Signed-off-by: Andrey Smirnov <[email protected]>
  • Loading branch information
smira committed Apr 6, 2023
1 parent b6235eb commit b305f2c
Show file tree
Hide file tree
Showing 14 changed files with 1,055 additions and 592 deletions.
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ FROM ghcr.io/siderolabs/liblzma:${PKGS} AS pkg-liblzma
FROM ghcr.io/siderolabs/ipxe:${PKGS} AS pkg-ipxe
FROM --platform=amd64 ghcr.io/siderolabs/ipxe:${PKGS} AS pkg-ipxe-amd64
FROM --platform=arm64 ghcr.io/siderolabs/ipxe:${PKGS} AS pkg-ipxe-arm64
FROM --platform=amd64 ghcr.io/siderolabs/eudev:${PKGS} AS pkg-eudev-amd64
FROM --platform=arm64 ghcr.io/siderolabs/eudev:${PKGS} AS pkg-eudev-arm64
FROM --platform=amd64 ghcr.io/siderolabs/util-linux:${PKGS} AS pkg-util-linux-amd64
FROM --platform=arm64 ghcr.io/siderolabs/util-linux:${PKGS} AS pkg-util-linux-arm64
FROM --platform=amd64 ghcr.io/siderolabs/kmod:${PKGS} AS pkg-kmod-amd64
FROM --platform=arm64 ghcr.io/siderolabs/kmod:${PKGS} AS pkg-kmod-arm64

# The base target provides the base for running various tasks against the source
# code
Expand Down Expand Up @@ -178,21 +184,29 @@ WORKDIR /initramfs
COPY --from=pkg-ca-certificates / .
COPY --from=pkg-musl-amd64 / .
COPY --from=pkg-openssl-amd64 / .
COPY --from=pkg-util-linux-amd64 / .
COPY --from=pkg-kmod-amd64 / .
COPY --from=pkg-eudev-amd64 / .
COPY --from=pkg-ipmitool-amd64 / .
COPY --from=agent-build-amd64 /agent ./init
COPY --from=pkg-linux-firmware-amd64 /lib/firmware/bnx2 ./lib/firmware/bnx2
COPY --from=pkg-linux-firmware-amd64 /lib/firmware/bnx2x ./lib/firmware/bnx2x
COPY --from=pkg-kernel-amd64 /lib/modules ./lib/modules
RUN set -o pipefail && find . 2>/dev/null | cpio -H newc -o | xz -v -C crc32 -0 -e -T 0 -z >/initramfs.xz

FROM base AS initramfs-archive-arm64
WORKDIR /initramfs
COPY --from=pkg-ca-certificates / .
COPY --from=pkg-musl-arm64 / .
COPY --from=pkg-openssl-arm64 / .
COPY --from=pkg-util-linux-arm64 / .
COPY --from=pkg-kmod-arm64 / .
COPY --from=pkg-eudev-arm64 / .
COPY --from=pkg-ipmitool-arm64 / .
COPY --from=agent-build-arm64 /agent ./init
COPY --from=pkg-linux-firmware-arm64 /lib/firmware/bnx2 ./lib/firmware/bnx2
COPY --from=pkg-linux-firmware-arm64 /lib/firmware/bnx2x ./lib/firmware/bnx2x
COPY --from=pkg-kernel-arm64 /lib/modules ./lib/modules
RUN set -o pipefail && find . 2>/dev/null | cpio -H newc -o | xz -v -C crc32 -0 -e -T 0 -z >/initramfs.xz

FROM scratch AS sidero-controller-manager-image
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ TALOS_RELEASE ?= v1.4.0-beta.0
DEFAULT_K8S_VERSION ?= v1.26.0

TOOLS ?= ghcr.io/siderolabs/tools:v1.4.0
PKGS ?= v1.3.0-16-gd1b0e28
PKGS ?= v1.5.0-alpha.0-3-g174f8fc

SFYRA_CLUSTERCTL_CONFIG ?= $(HOME)/.cluster-api/clusterctl.sfyra.yaml

Expand Down
62 changes: 62 additions & 0 deletions app/sidero-controller-manager/cmd/agent/addresses.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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 main

import (
"context"
"net"
"time"

"github.com/siderolabs/go-retry/retry"
"github.com/siderolabs/go-smbios/smbios"

"github.com/siderolabs/sidero/app/sidero-controller-manager/internal/api"
)

func reconcileIPs(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS, ips []net.IP) error {
addresses := make([]*api.Address, len(ips))
for i := range addresses {
addresses[i] = &api.Address{
Type: "InternalIP",
Address: ips[i].String(),
}
}

return retry.Constant(5*time.Minute, retry.WithUnits(30*time.Second)).Retry(func() error {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

_, err := client.ReconcileServerAddresses(ctx, &api.ReconcileServerAddressesRequest{
Uuid: s.SystemInformation.UUID,
Address: addresses,
})
if err != nil {
return retry.ExpectedError(err)
}

return nil
})
}

// IPAddrs finds and returns a list of non-loopback IP addresses of the
// current machine.
func IPAddrs() (ips []net.IP, err error) {
ips = []net.IP{}

addrs, err := net.InterfaceAddrs()
if err != nil {
return
}

for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok {
if ipnet.IP.IsGlobalUnicast() && !ipnet.IP.IsLinkLocalUnicast() {
ips = append(ips, ipnet.IP)
}
}
}

return ips, nil
}
85 changes: 85 additions & 0 deletions app/sidero-controller-manager/cmd/agent/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// 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 main

import (
"context"
"log"
"net"
"os"
"time"

"github.com/siderolabs/go-blockdevice/blockdevice/util/disk"
"github.com/siderolabs/go-retry/retry"
"github.com/siderolabs/go-smbios/smbios"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

"github.com/siderolabs/sidero/app/sidero-controller-manager/internal/api"
)

func create(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) (*api.CreateServerResponse, error) {
disks, err := disk.List()
if err != nil {
log.Printf("encountered error fetching disks: %q", err)
}

interfaces, err := net.Interfaces()
if err != nil {
log.Printf("encountered error fetching network interfaces: %q", err)
}

req := &api.CreateServerRequest{
Hardware: MapHardwareInformation(s, disks, interfaces),
Hostname: "",
}

hostname, err := os.Hostname()
if err != nil {
log.Printf("encountered error fetching hostname: %q", err)
} else {
req.Hostname = hostname
}

var resp *api.CreateServerResponse

err = retry.Constant(5*time.Minute, retry.WithUnits(30*time.Second), retry.WithErrorLogging(true)).Retry(func() error {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

resp, err = client.CreateServer(ctx, req)
if err != nil {
return retry.ExpectedError(err)
}

return nil
})

return resp, err
}

func wipe(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) error {
return retry.Constant(5*time.Minute, retry.WithUnits(30*time.Second), retry.WithErrorLogging(true)).Retry(func() error {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

_, err := client.MarkServerAsWiped(ctx, &api.MarkServerAsWipedRequest{Uuid: s.SystemInformation.UUID})
if err != nil {
return retry.ExpectedError(err)
}

return nil
})
}

func connect(ctx context.Context, endpoint string) (*grpc.ClientConn, error) {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

return grpc.DialContext(ctx,
endpoint,
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
}
Loading

0 comments on commit b305f2c

Please sign in to comment.