f-50: lab: déploiement de two sur les hyperviseurs et provisionnement en un script #50

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-10-04 17:36:15 +02:00
commit 4410f30afa
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
16 changed files with 360 additions and 64 deletions

View file

@ -9,6 +9,7 @@ import (
"go.yaml.in/yaml/v3"
"git.g3e.fr/syonad/two/internal/lab/topology"
"git.g3e.fr/syonad/two/scripts"
)
const (
@ -25,6 +26,11 @@ const (
FRRSuite = "frr-stable"
FRRRepo = "https://deb.frrouting.org/frr"
FRRPackages = "frr frr-pythontools"
ProvisionScript = "/usr/local/sbin/lab-provision"
DeployScript = "/usr/local/sbin/lab-deploy"
TwoScriptsDir = "/opt/two/scripts"
TwoGitServer = "https://git.g3e.fr/"
)
//go:embed frrouting.gpg
@ -91,6 +97,7 @@ func userData(p *topology.Plan, n topology.NodePlan, o Options) ([]byte, error)
DisableRoot: true,
SSHAuthorizedKeys: o.AuthorizedKeys,
}
var steps []string
switch {
case n.Role == topology.RoleSwitch:
cfg.Packages = []string{"nftables"}
@ -99,19 +106,21 @@ func userData(p *topology.Plan, n topology.NodePlan, o Options) ([]byte, error)
{Path: SwitchNFT, Permissions: "0644", Content: switchNFT(p, n.Name)},
{Path: SwitchUnit, Permissions: "0644", Content: unit("Lab switch: bridges, gateways and NAT", SwitchScript)},
}
cfg.Runcmd = [][]string{
{"systemctl", "daemon-reload"},
{"systemctl", "enable", "--now", "lab-switch.service"},
}
steps = append(steps, "systemctl daemon-reload", "systemctl enable --now lab-switch.service")
case n.Loopback.IsValid():
cfg.WriteFiles = []writeFile{
{Path: NodeScript, Permissions: "0755", Content: "#!/bin/sh\nset -eu\n" + loopbackLines(n)},
{Path: NodeUnit, Permissions: "0644", Content: unit("Lab node: loopback", NodeScript)},
}
cfg.Runcmd = [][]string{
{"systemctl", "daemon-reload"},
{"systemctl", "enable", "--now", "lab-node.service"},
}
steps = append(steps, "systemctl daemon-reload", "systemctl enable --now lab-node.service")
}
if n.Role == topology.RoleHypervisor {
cfg.WriteFiles = append(cfg.WriteFiles,
writeFile{Path: TwoScriptsDir + "/deploy.sh", Permissions: "0755", Encoding: "b64", Content: base64.StdEncoding.EncodeToString(scripts.Deploy)},
writeFile{Path: TwoScriptsDir + "/bootstrap_kvm.sh", Permissions: "0755", Encoding: "b64", Content: base64.StdEncoding.EncodeToString(scripts.BootstrapKVM)},
writeFile{Path: DeployScript, Permissions: "0755", Content: deployScript(p, n)},
)
steps = append(steps, DeployScript)
}
if n.FRR != "" {
cfg.WriteFiles = append(cfg.WriteFiles,
@ -119,7 +128,13 @@ func userData(p *topology.Plan, n topology.NodePlan, o Options) ([]byte, error)
writeFile{Path: FRRConfig, Permissions: "0640", Content: o.FRR[n.Name]},
writeFile{Path: FRRScript, Permissions: "0755", Content: frrScript(n)},
)
cfg.Runcmd = append(cfg.Runcmd, []string{FRRScript})
steps = append(steps, FRRScript)
}
if len(steps) > 0 {
cfg.WriteFiles = append(cfg.WriteFiles,
writeFile{Path: ProvisionScript, Permissions: "0755", Content: "#!/bin/sh\nset -eu\n" + strings.Join(steps, "\n") + "\n"},
)
cfg.Runcmd = [][]string{{ProvisionScript}}
}
body, err := yaml.Marshal(cfg)
if err != nil {
@ -128,6 +143,18 @@ func userData(p *topology.Plan, n topology.NodePlan, o Options) ([]byte, error)
return append([]byte("#cloud-config\n"), body...), nil
}
func retry(command string) string {
return "n=0\nuntil " + command + "; do\n n=$((n + 1))\n [ \"$n\" -lt 30 ] || exit 1\n sleep 10\ndone\n"
}
func deployScript(p *topology.Plan, n topology.NodePlan) string {
uplink := nodeCables(p, n.Name)[0].NodeInterface
return "#!/bin/sh\nset -eu\n" +
retry("curl -fsS -o /dev/null "+TwoGitServer) +
"cd " + TwoScriptsDir + "\n" +
fmt.Sprintf("bash ./deploy.sh --noup_script -i -u %s -t %s\n", uplink, n.Release)
}
func frrDaemons(n topology.NodePlan) []string {
if n.Role == topology.RoleHypervisor {
return []string{"bgpd"}
@ -139,7 +166,7 @@ func frrScript(n topology.NodePlan) string {
var b strings.Builder
b.WriteString("#!/bin/sh\nset -eu\nexport DEBIAN_FRONTEND=noninteractive\n. /etc/os-release\n")
fmt.Fprintf(&b, "echo \"deb [signed-by=%s] %s ${VERSION_CODENAME} %s\" > /etc/apt/sources.list.d/frr.list\n", FRRKey, FRRRepo, FRRSuite)
b.WriteString("n=0\nuntil apt-get update -qq --error-on=any; do\n n=$((n + 1))\n [ \"$n\" -lt 30 ] || exit 1\n sleep 10\ndone\n")
b.WriteString(retry("apt-get update -qq --error-on=any"))
fmt.Fprintf(&b, "apt-get install -y -qq --no-install-recommends %s\n", FRRPackages)
for _, d := range frrDaemons(n) {
fmt.Fprintf(&b, "sed -i 's/^%s=no/%s=yes/' /etc/frr/daemons\n", d, d)