From 848daefffe9998a27055dd5ebffd17837f896d0612287458714f2ebb1991aad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=9F=E9=85=8C=20=E9=B5=AC=E5=85=84?= Date: Fri, 27 Mar 2026 20:25:54 +0800 Subject: [PATCH] clitools: Added ConfigureDNS --- clitools/makefile | 4 +- clitools/pkg/bootstrap/registry.go | 10 ++- clitools/pkg/cmd/internal/internal.go | 12 ++- clitools/pkg/node/network.go | 116 ++++++++++++++++++++++---- makefile | 14 +++- 5 files changed, 132 insertions(+), 24 deletions(-) diff --git a/clitools/makefile b/clitools/makefile index fac06f2..7ab571c 100644 --- a/clitools/makefile +++ b/clitools/makefile @@ -4,11 +4,11 @@ BIN_DIR := bin build: mkdir -p $(BIN_DIR) - go build -o $(BIN_DIR)/ctl-$(VERSION) ./cmd/ctl + GOOS=linux GOARCH=arm64 go build -o $(BIN_DIR)/ctl-linux-aarch64-$(VERSION) ./cmd/ctl/ +# go build -o $(BIN_DIR)/ctl-$(VERSION) ./cmd/ctl run: go run ./cmd/ctl clean: rm -rf $(BIN_DIR) - diff --git a/clitools/pkg/bootstrap/registry.go b/clitools/pkg/bootstrap/registry.go index 372a73f..20ffccd 100644 --- a/clitools/pkg/bootstrap/registry.go +++ b/clitools/pkg/bootstrap/registry.go @@ -12,9 +12,11 @@ type Registry struct { func NewRegistry(ctx *node.NodeContext) *Registry { netCfg := node.NetworkConfig{ - MgmtIface: ctx.Config.Spec.Network.ManagementIface, - MgmtAddress: ctx.Config.Spec.Network.ManagementCIDR, - MgmtGateway: ctx.Config.Spec.Network.ManagementGW, + MgmtIface: ctx.Config.Spec.Network.ManagementIface, + MgmtAddress: ctx.Config.Spec.Network.ManagementCIDR, + MgmtGateway: ctx.Config.Spec.Network.ManagementGW, + DNSNameservers: ctx.Config.Spec.Network.DNSNameservers, + DNSSearchDomains: ctx.Config.Spec.Network.DNSSearchDomains, } return &Registry{ @@ -34,7 +36,7 @@ func NewRegistry(ctx *node.NodeContext) *Registry { "allow_single_node_scheduling": node.AllowSingleNodeScheduling, "ensure_ip_forward": node.EnsureIPForward, "configure_mgmt_interface": node.ConfigureMgmtInterface(netCfg), - "configure_dns": node.ConfigureDNS, + "configure_dns": node.ConfigureDNS(netCfg), "set_hostname_if_needed": node.SetHostnameIfNeeded, "print_summary": node.PrintSummary, "reconcile_control_plane": node.ReconcileControlPlane, diff --git a/clitools/pkg/cmd/internal/internal.go b/clitools/pkg/cmd/internal/internal.go index 24f3684..953db45 100644 --- a/clitools/pkg/cmd/internal/internal.go +++ b/clitools/pkg/cmd/internal/internal.go @@ -1,9 +1,9 @@ package internal import ( + "github.com/spf13/cobra" "undecided.project/monok8s/pkg/bootstrap" "undecided.project/monok8s/pkg/config" - "github.com/spf13/cobra" ) func NewCmdInternal() *cobra.Command { @@ -18,11 +18,19 @@ func NewCmdInternal() *cobra.Command { if err != nil { return err } + cfg, err := (config.Loader{}).Load(path) if err != nil { return err } - return bootstrap.NewRunner(cfg).RunNamedStep(cmd.Context(), args[0]) + + err = bootstrap.NewRunner(cfg).RunNamedStep(cmd.Context(), args[0]) + if err != nil { + return err + } + + cmd.Println("OK") + return nil }, }) cmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "path to MonoKSConfig yaml") diff --git a/clitools/pkg/node/network.go b/clitools/pkg/node/network.go index 28609b3..4f40943 100644 --- a/clitools/pkg/node/network.go +++ b/clitools/pkg/node/network.go @@ -4,16 +4,19 @@ import ( "context" "fmt" "net" + "os" "strings" - system "undecided.project/monok8s/pkg/system" "k8s.io/klog/v2" + system "undecided.project/monok8s/pkg/system" ) type NetworkConfig struct { - MgmtIface string - MgmtAddress string - MgmtGateway string + MgmtIface string + MgmtAddress string + MgmtGateway string + DNSNameservers []string + DNSSearchDomains []string } func ConfigureMgmtInterface(cfg NetworkConfig) Step { @@ -24,18 +27,31 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step { if strings.TrimSpace(cfg.MgmtAddress) == "" { return fmt.Errorf("mgmt address is required") } - ip, ipNet, err := net.ParseCIDR(cfg.MgmtAddress) + + ip, ipNet, err := net.ParseCIDR(strings.TrimSpace(cfg.MgmtAddress)) if err != nil { return fmt.Errorf("invalid mgmt address %q: %w", cfg.MgmtAddress, err) } - wantIP := ip.String() - if gw := strings.TrimSpace(cfg.MgmtGateway); gw != "" && net.ParseIP(gw) == nil { - return fmt.Errorf("invalid mgmt gateway %q", gw) + + ip4 := ip.To4() + if ip4 == nil { + return fmt.Errorf("mgmt address must be IPv4: %q", cfg.MgmtAddress) + } + + wantIP := ip4.String() + wantCIDR := fmt.Sprintf("%s/%d", wantIP, maskSize(ipNet.Mask)) + + if gw := strings.TrimSpace(cfg.MgmtGateway); gw != "" { + gwIP := net.ParseIP(gw) + if gwIP == nil || gwIP.To4() == nil { + return fmt.Errorf("invalid mgmt gateway %q", gw) + } } if _, err := nctx.System.Run(ctx, "ip", "link", "show", "dev", cfg.MgmtIface); err != nil { return fmt.Errorf("interface not found: %s: %w", cfg.MgmtIface, err) } + if _, err := nctx.System.Run(ctx, "ip", "link", "set", "dev", cfg.MgmtIface, "up"); err != nil { return fmt.Errorf("failed to bring up interface %s: %w", cfg.MgmtIface, err) } @@ -44,11 +60,12 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step { if err != nil { return fmt.Errorf("failed checking existing address on %s: %w", cfg.MgmtIface, err) } + if hasAddr { - klog.Infof("address already present on %s: %s", cfg.MgmtIface, cfg.MgmtAddress) + klog.Infof("address already present on %s: %s", cfg.MgmtIface, wantCIDR) } else { - if _, err := nctx.System.Run(ctx, "ip", "addr", "add", ipNet.String(), "dev", cfg.MgmtIface); err != nil { - return fmt.Errorf("failed assigning %s to %s: %w", ipNet.String(), cfg.MgmtIface, err) + if _, err := nctx.System.Run(ctx, "ip", "addr", "add", wantCIDR, "dev", cfg.MgmtIface); err != nil { + return fmt.Errorf("failed assigning %s to %s: %w", wantCIDR, cfg.MgmtIface, err) } } @@ -57,17 +74,88 @@ func ConfigureMgmtInterface(cfg NetworkConfig) Step { return fmt.Errorf("failed setting default route via %s dev %s: %w", gw, cfg.MgmtIface, err) } } + return nil } } +func maskSize(m net.IPMask) int { + ones, _ := m.Size() + return ones +} + func EnsureIPForward(ctx context.Context, n *NodeContext) error { return system.EnsureSysctl(ctx, n.System, "net.ipv4.ip_forward", "1") } -func ConfigureDNS(context.Context, *NodeContext) error { - klog.Info("configure_dns: TODO implement resolv.conf rendering") - return nil +func ConfigureDNS(cfg NetworkConfig) Step { + return func(context.Context, *NodeContext) error { + + if len(cfg.DNSNameservers) == 0 { + return nil + } + + var nameservers []string + for _, ns := range cfg.DNSNameservers { + ns = strings.TrimSpace(ns) + if ns == "" { + continue + } + if ip := net.ParseIP(ns); ip == nil { + return fmt.Errorf("invalid DNS nameserver %q", ns) + } + nameservers = append(nameservers, ns) + } + if len(nameservers) == 0 { + return fmt.Errorf("DNSNameservers is set but no valid nameservers were parsed") + } + + var searchDomains []string + for _, d := range cfg.DNSSearchDomains { + d = strings.TrimSpace(d) + if d == "" { + continue + } + searchDomains = append(searchDomains, d) + } + + var b strings.Builder + if len(searchDomains) > 0 { + b.WriteString("search ") + b.WriteString(strings.Join(searchDomains, " ")) + b.WriteByte('\n') + } + for _, ns := range nameservers { + b.WriteString("nameserver ") + b.WriteString(ns) + b.WriteByte('\n') + } + b.WriteString("options timeout:2 attempts:3\n") + + const ( + resolvDir = "/etc" + tmpPath = "/etc/resolv.conf.monok8s.tmp" + resolvPath = "/etc/resolv.conf" + ) + + if err := os.MkdirAll(resolvDir, 0o755); err != nil { + klog.Warningf("failed to create %s for DNS config: %v; leaving %s unchanged", resolvDir, err, resolvPath) + return nil + } + + if err := os.WriteFile(tmpPath, []byte(b.String()), 0o644); err != nil { + klog.Warningf("failed to write temporary DNS config %s: %v; leaving %s unchanged", tmpPath, err, resolvPath) + return nil + } + + if err := os.Rename(tmpPath, resolvPath); err != nil { + _ = os.Remove(tmpPath) + klog.Warningf("failed to install DNS config at %s: %v; leaving existing DNS config unchanged", resolvPath, err) + return nil + } + + return nil + } } func interfaceHasIPv4(ctx context.Context, nctx *NodeContext, iface, wantIP string) (bool, error) { diff --git a/makefile b/makefile index 1928b19..ed0568c 100644 --- a/makefile +++ b/makefile @@ -91,6 +91,12 @@ RELEASE_DEPS := \ build.env \ makefile +CLITOOLS := \ + clitools/pkg \ + clitools/cmd \ + clitools/go.mod \ + clitools/go.sum + # ---- Directory creation ------------------------------------------------------ $(PACKAGES_DIR): @@ -258,13 +264,17 @@ initramfs: $(INITRAMFS) itb: $(BOARD_ITB) build-base: $(BUILD_BASE_STAMP) +clitools: $(CLITOOLS) + $(MAKE) -C clitools + clean: rm -f \ $(BUILD_BASE_STAMP) \ $(KERNEL_IMAGE) \ $(INITRAMFS) \ $(BOARD_ITB) \ - $(RELEASE_IMAGE) + $(RELEASE_IMAGE) \ + $(CLITOOLS) distclean: clean rm -rf $(OUT_DIR) @@ -272,5 +282,5 @@ distclean: clean pkgclean: rm -rf $(PACKAGES_DIR) -.PHONY: release kernel initramfs itb build-base clean distclean pkgclean \ +.PHONY: release kernel initramfs itb build-base clitools clean distclean pkgclean \ cluster-config cluster-defconfig cluster-print