@@ -39,6 +39,17 @@ const (
3939 ldPreloadEnvVar = "LD_PRELOAD"
4040)
4141
42+ type reconfigurer struct {
43+ * reconfigureMIGOptions
44+ commandRunner
45+ }
46+
47+ // A commandWithOutput runs a command and ensures that STDERR and STDOUT are
48+ // set.
49+ type commandWithOutput struct {}
50+
51+ var _ commandRunner = (* commandWithOutput )(nil )
52+
4253// New creates a MIG Reconfigurer with the supplied options.
4354func New (opts ... Option ) (Reconfigurer , error ) {
4455 o := & reconfigureMIGOptions {}
@@ -51,26 +62,31 @@ func New(opts ...Option) (Reconfigurer, error) {
5162 return nil , err
5263 }
5364
54- return o , nil
65+ r := & reconfigurer {
66+ reconfigureMIGOptions : o ,
67+ commandRunner : & commandWithOutput {},
68+ }
69+
70+ return r , nil
5571}
5672
5773// Reconfigure configures MIG (Multi-Instance GPU) settings on a Kubernetes
5874// node. It validates the requested configuration, checks the current state,
5975// applies MIG mode changes, manages host GPU client services, and handles
6076// reboots when necessary. The function ensures that MIG configurations are
6177// applied safely with proper service lifecycle management.
62- func (opts * reconfigureMIGOptions ) Reconfigure () error {
78+ func (opts * reconfigurer ) Reconfigure () error {
6379 log .Info ("Asserting that the requested configuration is present in the configuration file" )
6480 if err := opts .assertValidMIGConfig (); err != nil {
6581 return fmt .Errorf ("error validating the selected MIG configuration: %w" , err )
6682 }
6783
68- log .Infof ("Getting current value of the '%s' node label" , opts .configStateLabel )
69- state , err := opts .getNodeLabelValue (opts .configStateLabel )
84+ log .Infof ("Getting current value of the '%s' node label" , opts .ConfigStateLabel )
85+ state , err := opts .getNodeLabelValue (opts .ConfigStateLabel )
7086 if err != nil {
71- return fmt .Errorf ("unable to get the value of the %q label: %w" , opts .configStateLabel , err )
87+ return fmt .Errorf ("unable to get the value of the %q label: %w" , opts .ConfigStateLabel , err )
7288 }
73- log .Infof ("Current value of '%s=%s'" , opts .configStateLabel , state )
89+ log .Infof ("Current value of '%s=%s'" , opts .ConfigStateLabel , state )
7490
7591 log .Info ("Checking if the selected MIG config is currently applied or not" )
7692 if err := opts .assertMIGConfig (); err == nil {
@@ -116,11 +132,11 @@ func (opts *reconfigureMIGOptions) Reconfigure() error {
116132 log .Info ("If the -r option was passed, the node will be automatically rebooted if this is not successful" )
117133 if err := opts .applyMIGModeOnly (); err != nil || opts .assertMIGModeOnly () != nil {
118134 if opts .WithReboot {
119- log .Infof ("Changing the '%s' node label to '%s'" , opts .configStateLabel , configStateRebooting )
120- if err := opts .setNodeLabelValue (opts .configStateLabel , configStateRebooting ); err != nil {
121- log .Errorf ("Unable to set the value of '%s' to '%s'" , opts .configStateLabel , configStateRebooting )
135+ log .Infof ("Changing the '%s' node label to '%s'" , opts .ConfigStateLabel , configStateRebooting )
136+ if err := opts .setNodeLabelValue (opts .ConfigStateLabel , configStateRebooting ); err != nil {
137+ log .Errorf ("Unable to set the value of '%s' to '%s'" , opts .ConfigStateLabel , configStateRebooting )
122138 log .Error ("Exiting so as not to reboot multiple times unexpectedly" )
123- return fmt .Errorf ("unable to set the value of %q to %q: %w" , opts .configStateLabel , configStateRebooting , err )
139+ return fmt .Errorf ("unable to set the value of %q to %q: %w" , opts .ConfigStateLabel , configStateRebooting , err )
124140 }
125141 return rebootHost (opts .HostRootMount )
126142 }
@@ -141,7 +157,7 @@ func (opts *reconfigureMIGOptions) Reconfigure() error {
141157 return nil
142158}
143159
144- func (opts * reconfigureMIGOptions ) assertValidMIGConfig () error {
160+ func (opts * reconfigurer ) assertValidMIGConfig () error {
145161 args := []string {
146162 "--debug" ,
147163 "assert" ,
@@ -152,7 +168,7 @@ func (opts *reconfigureMIGOptions) assertValidMIGConfig() error {
152168 return opts .runMigParted (args ... )
153169}
154170
155- func (opts * reconfigureMIGOptions ) assertMIGConfig () error {
171+ func (opts * reconfigurer ) assertMIGConfig () error {
156172 args := []string {
157173 "--debug" ,
158174 "assert" ,
@@ -162,7 +178,7 @@ func (opts *reconfigureMIGOptions) assertMIGConfig() error {
162178 return opts .runMigParted (args ... )
163179}
164180
165- func (opts * reconfigureMIGOptions ) assertMIGModeOnly () error {
181+ func (opts * reconfigurer ) assertMIGModeOnly () error {
166182 args := []string {
167183 "--debug" ,
168184 "assert" ,
@@ -173,7 +189,7 @@ func (opts *reconfigureMIGOptions) assertMIGModeOnly() error {
173189 return opts .runMigParted (args ... )
174190}
175191
176- func (opts * reconfigureMIGOptions ) applyMIGModeOnly () error {
192+ func (opts * reconfigurer ) applyMIGModeOnly () error {
177193 args := []string {
178194 "--debug" ,
179195 "apply" ,
@@ -184,7 +200,7 @@ func (opts *reconfigureMIGOptions) applyMIGModeOnly() error {
184200 return opts .runMigParted (args ... )
185201}
186202
187- func (opts * reconfigureMIGOptions ) applyMIGConfig () error {
203+ func (opts * reconfigurer ) applyMIGConfig () error {
188204 args := []string {
189205 "--debug" ,
190206 "apply" ,
@@ -194,7 +210,7 @@ func (opts *reconfigureMIGOptions) applyMIGConfig() error {
194210 return opts .runMigParted (args ... )
195211}
196212
197- func (opts * reconfigureMIGOptions ) hostPersistConfig () error {
213+ func (opts * reconfigurer ) hostPersistConfig () error {
198214 config := fmt .Sprintf (`[Service]
199215Environment="MIG_PARTED_SELECTED_CONFIG=%s"
200216` , opts .SelectedMIGConfig )
@@ -206,7 +222,7 @@ Environment="MIG_PARTED_SELECTED_CONFIG=%s"
206222 }
207223
208224 cmd := exec .Command ("chroot" , opts .HostRootMount , "systemctl" , "daemon-reload" ) // #nosec G204 -- HostRootMount is validated via dirpath validator.
209- return runCommandWithOutput (cmd )
225+ return opts . Run (cmd )
210226}
211227
212228func (opts * reconfigureMIGOptions ) hostStopSystemdServices () error {
@@ -234,7 +250,7 @@ func (opts *reconfigureMIGOptions) hostStartSystemdServices() error {
234250 log .Infof ("Starting %s" , service )
235251 cmd := exec .Command ("chroot" , opts .HostRootMount , "systemctl" , "start" , service ) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
236252 if err := cmd .Run (); err != nil {
237- serviceError := fmt .Errorf ("error starting %q: %w" , err )
253+ serviceError := fmt .Errorf ("error starting %q: %w" , service , err )
238254 log .Errorf ("%v; skipping, but continuing..." , serviceError )
239255
240256 errs = errors .Join (errs , serviceError )
@@ -332,15 +348,15 @@ func shouldRestartService(opts *reconfigureMIGOptions, service string) bool {
332348 return true
333349}
334350
335- func runCommandWithOutput (cmd * exec.Cmd ) error {
351+ func ( c * commandWithOutput ) Run (cmd * exec.Cmd ) error {
336352 cmd .Stdout = os .Stdout
337353 cmd .Stderr = os .Stderr
338354 return cmd .Run ()
339355}
340356
341- func (opts * reconfigureMIGOptions ) runMigParted (args ... string ) error {
357+ func (opts * reconfigurer ) runMigParted (args ... string ) error {
342358 cmd := opts .migPartedCmd (args ... )
343- return runCommandWithOutput (cmd )
359+ return opts . Run (cmd )
344360}
345361
346362func (opts * reconfigureMIGOptions ) migPartedCmd (args ... string ) * exec.Cmd {
0 commit comments