Skip to content

Commit 1844b46

Browse files
authored
Create initial checkpoint for nodes withtout startup config too (#39)
* generate checkpoint for nodes without startup config as well as for those with it * lint
1 parent 712ed91 commit 1844b46

File tree

1 file changed

+50
-26
lines changed

1 file changed

+50
-26
lines changed

controllers/startup_config.go

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"path/filepath"
7+
"strings"
78
"time"
89

910
"github.com/go-logr/logr"
@@ -71,32 +72,21 @@ func createStartupConfigVolumesAndMounts(s *srlinuxv1.Srlinux, pod *corev1.Pod,
7172
}
7273

7374
// handleSrlinuxStartupConfig handles the startup config provisioning.
74-
func (r *SrlinuxReconciler) handleSrlinuxStartupConfig(
75+
func (r *SrlinuxReconciler) handleSrlinuxStartupConfig( //nolint:funlen
7576
ctx context.Context,
7677
log logr.Logger,
7778
update *bool,
7879
srlinux *srlinuxv1.Srlinux,
7980
) {
80-
if srlinux.Status.StartupConfig.Phase == "loaded" ||
81-
srlinux.Status.StartupConfig.Phase == "failed" {
82-
log.Info("startup config load already tried, skipping")
81+
if srlinux.Status.StartupConfig.Phase != "" {
82+
log.Info("startup config already processed, skipping")
8383

8484
return
8585
}
8686

87-
// if startup config data is not provided and the state is not "not-provided", set the state to "not-provided"
88-
// so that we only log the message once
89-
if !srlinux.Spec.GetConfig().ConfigDataPresent {
90-
log.Info("no startup config data provided")
91-
92-
srlinux.Status.StartupConfig.Phase = "not-provided"
93-
*update = true
94-
95-
return
96-
}
97-
98-
log.Info("startup config provided, starting config provisioning...")
99-
87+
// we need to wait for podIP to be ready as well as the network to be ready
88+
// we do this before even checking if the startup config is provided
89+
// because we need to create a checkpoing in any case
10090
ip := r.waitPodIPReady(ctx, log, srlinux)
10191

10292
// even though the SR Linux management server is ready, the network might not be ready yet
@@ -108,6 +98,22 @@ func (r *SrlinuxReconciler) handleSrlinuxStartupConfig(
10898
}
10999
defer driver.Close()
110100

101+
// if startup config data is not provided and Phase hasn't been set yet, set the Startup Config state to "not-provided"
102+
// and create a checkpoint
103+
if !srlinux.Spec.GetConfig().ConfigDataPresent && srlinux.Status.StartupConfig.Phase == "" {
104+
log.Info("no startup config data provided")
105+
106+
srlinux.Status.StartupConfig.Phase = "not-provided"
107+
*update = true
108+
109+
err := createInitCheckpoint(ctx, driver, log)
110+
if err != nil {
111+
log.Error(err, "failed to create initial checkpoint")
112+
}
113+
114+
return
115+
}
116+
111117
log.Info("Loading provided startup configuration...", "filename",
112118
srlinux.Spec.GetConfig().ConfigFile, "path", defaultConfigPath)
113119

@@ -123,15 +129,13 @@ func (r *SrlinuxReconciler) handleSrlinuxStartupConfig(
123129

124130
log.Info("Loaded provided startup configuration...")
125131

132+
srlinux.Status.StartupConfig.Phase = "loaded"
133+
*update = true
134+
126135
err = createInitCheckpoint(ctx, driver, log)
127136
if err != nil {
128137
log.Error(err, "failed to create initial checkpoint after loading startup config")
129-
130-
return
131138
}
132-
133-
srlinux.Status.StartupConfig.Phase = "loaded"
134-
*update = true
135139
}
136140

137141
// loadStartupConfig loads the provided startup config into the SR Linux device.
@@ -161,16 +165,36 @@ func loadStartupConfig(
161165
}
162166

163167
// createInitCheckpoint creates a checkpoint named "initial".
164-
// This checkpoint is used to reset the device to the initial state, which is the state after
165-
// applying the startup config.
168+
// This checkpoint is used to reset the device to the initial state, which is the state
169+
// node booted with and (if present) with applied startup config.
166170
func createInitCheckpoint(
167171
_ context.Context,
168172
d *network.Driver,
169173
log logr.Logger,
170174
) error {
175+
log.Info("Creating initial checkpoint...")
176+
177+
// sometimes status of srlinux cr is not updated immediately,
178+
// resulting in several attempts to load configuration and create checkpoint
179+
// so we need to check if the checkpoint already exists and bail out if so
180+
checkCheckpointCmd := "info from state system configuration checkpoint *"
181+
182+
r, err := d.SendCommand(checkCheckpointCmd)
183+
if err != nil {
184+
log.Error(err, "failed to send command")
185+
186+
return err
187+
}
188+
189+
if strings.Contains(r.Result, "initial") {
190+
log.Info("initial checkpoint already exists, skipping")
191+
192+
return nil
193+
}
194+
171195
cmd := "/tools system configuration generate-checkpoint name initial"
172196

173-
r, err := d.SendCommand(cmd)
197+
r, err = d.SendCommand(cmd)
174198
if err != nil {
175199
log.Error(err, "failed to send command")
176200

@@ -226,7 +250,7 @@ func (r *SrlinuxReconciler) waitPodIPReady(
226250
case <-tick.C:
227251
ip := r.getPodIP(ctx, srlinux)
228252
if ip != "" {
229-
log.Info("pod IP assigned, provisioning configuration", "pod-ip", ip)
253+
log.Info("pod IP assigned", "pod-ip", ip)
230254

231255
return ip
232256
}

0 commit comments

Comments
 (0)