@@ -105,10 +105,25 @@ reboot
105
105
autopkgtestRebootPrepareScript = `#!/bin/bash
106
106
set -euo pipefail
107
107
exec /usr/local/bin/kolet reboot-request "$1"
108
+ `
109
+
110
+ // Soft-reboot support
111
+ autopkgTestSoftRebootPath = "/tmp/autopkgtest-soft-reboot"
112
+ autopkgtestSoftRebootScript = `#!/bin/bash
113
+ set -xeuo pipefail
114
+ /usr/local/bin/kolet soft-reboot-request "$1"
115
+ systemctl soft-reboot
116
+ `
117
+ autopkgTestSoftRebootPreparePath = "/tmp/autopkgtest-soft-reboot-prepare"
118
+
119
+ autopkgtestSoftRebootPrepareScript = `#!/bin/bash
120
+ set -euo pipefail
121
+ exec /usr/local/bin/kolet soft-reboot-request "$1"
108
122
`
109
123
110
124
// File used to communicate between the script and the kolet runner internally
111
- rebootRequestFifo = "/run/kolet-reboot"
125
+ rebootRequestFifo = "/run/kolet-reboot"
126
+ softRebootRequestFifo = "/run/kolet-soft-reboot"
112
127
)
113
128
114
129
var (
@@ -140,6 +155,13 @@ var (
140
155
SilenceUsage : true ,
141
156
}
142
157
158
+ cmdSoftReboot = & cobra.Command {
159
+ Use : "soft-reboot-request MARK" ,
160
+ Short : "Request a soft reboot" ,
161
+ RunE : runSoftReboot ,
162
+ SilenceUsage : true ,
163
+ }
164
+
143
165
cmdHttpd = & cobra.Command {
144
166
Use : "httpd" ,
145
167
Short : "Start an HTTP server to serve the contents of the file system" ,
@@ -260,6 +282,11 @@ func initiateReboot(mark string) error {
260
282
}
261
283
262
284
func mkfifo (path string ) error {
285
+ // Create a FIFO in an idempotent fashion
286
+ // as /run survives soft-reboots.
287
+ if _ , err := os .Stat (path ); err == nil {
288
+ return nil
289
+ }
263
290
c := exec .Command ("mkfifo" , path )
264
291
c .Stderr = os .Stderr
265
292
err := c .Run ()
@@ -269,6 +296,20 @@ func mkfifo(path string) error {
269
296
return nil
270
297
}
271
298
299
+ func initiateSoftReboot (mark string ) error {
300
+ systemdjournal .Print (systemdjournal .PriInfo , "Processing soft-reboot request" )
301
+ res := kola.KoletResult {
302
+ SoftReboot : string (mark ),
303
+ }
304
+ buf , err := json .Marshal (& res )
305
+ if err != nil {
306
+ return errors .Wrapf (err , "serializing KoletResult" )
307
+ }
308
+ fmt .Println (string (buf ))
309
+ systemdjournal .Print (systemdjournal .PriInfo , "Acknowledged soft-reboot request with mark: %s" , buf )
310
+ return nil
311
+ }
312
+
272
313
func runExtUnit (cmd * cobra.Command , args []string ) error {
273
314
rebootOff , _ := cmd .Flags ().GetBool ("deny-reboots" )
274
315
// Write the autopkgtest wrappers
@@ -278,10 +319,18 @@ func runExtUnit(cmd *cobra.Command, args []string) error {
278
319
if err := os .WriteFile (autopkgTestRebootPreparePath , []byte (autopkgtestRebootPrepareScript ), 0755 ); err != nil {
279
320
return err
280
321
}
322
+ // Write the soft-reboot autopkgtest wrappers
323
+ if err := os .WriteFile (autopkgTestSoftRebootPath , []byte (autopkgtestSoftRebootScript ), 0755 ); err != nil {
324
+ return err
325
+ }
326
+ if err := os .WriteFile (autopkgTestSoftRebootPreparePath , []byte (autopkgtestSoftRebootPrepareScript ), 0755 ); err != nil {
327
+ return err
328
+ }
281
329
282
330
// Create the reboot cmdline -> login FIFO for the reboot mark and
283
331
// proxy it into a channel
284
332
rebootChan := make (chan string )
333
+ softRebootChan := make (chan string )
285
334
errChan := make (chan error )
286
335
287
336
// We want to prevent certain tests (like non-exclusive tests) from rebooting
@@ -303,6 +352,25 @@ func runExtUnit(cmd *cobra.Command, args []string) error {
303
352
}
304
353
rebootChan <- string (buf )
305
354
}()
355
+
356
+ // Create soft-reboot FIFO and channel
357
+ err = mkfifo (softRebootRequestFifo )
358
+ if err != nil {
359
+ return err
360
+ }
361
+ go func () {
362
+ softRebootReader , err := os .Open (softRebootRequestFifo )
363
+ if err != nil {
364
+ errChan <- err
365
+ return
366
+ }
367
+ defer softRebootReader .Close ()
368
+ buf , err := io .ReadAll (softRebootReader )
369
+ if err != nil {
370
+ errChan <- err
371
+ }
372
+ softRebootChan <- string (buf )
373
+ }()
306
374
}
307
375
308
376
ctx := context .Background ()
@@ -344,6 +412,8 @@ func runExtUnit(cmd *cobra.Command, args []string) error {
344
412
return err
345
413
case reboot := <- rebootChan :
346
414
return initiateReboot (reboot )
415
+ case softReboot := <- softRebootChan :
416
+ return initiateSoftReboot (softReboot )
347
417
case m := <- unitevents :
348
418
for n := range m {
349
419
if n == unitname {
@@ -397,6 +467,35 @@ func runReboot(cmd *cobra.Command, args []string) error {
397
467
return nil
398
468
}
399
469
470
+ // runSoftReboot handles soft-reboot requests similar to runReboot but for systemctl soft-reboot
471
+ func runSoftReboot (cmd * cobra.Command , args []string ) error {
472
+ if _ , err := os .Stat (softRebootRequestFifo ); os .IsNotExist (err ) {
473
+ return errors .New ("Soft-reboots are not supported for this test, softRebootRequestFifo does not exist." )
474
+ }
475
+
476
+ mark := args [0 ]
477
+ systemdjournal .Print (systemdjournal .PriInfo , "Requesting soft-reboot with mark: %s" , mark )
478
+ err := mkfifo (kola .KoletRebootAckFifo )
479
+ if err != nil {
480
+ return err
481
+ }
482
+ err = os .WriteFile (softRebootRequestFifo , []byte (mark ), 0644 )
483
+ if err != nil {
484
+ return err
485
+ }
486
+ f , err := os .Open (kola .KoletRebootAckFifo )
487
+ if err != nil {
488
+ return err
489
+ }
490
+ buf := make ([]byte , 1 )
491
+ _ , err = f .Read (buf )
492
+ if err != nil {
493
+ return err
494
+ }
495
+ systemdjournal .Print (systemdjournal .PriInfo , "Soft-reboot request acknowledged" )
496
+ return nil
497
+ }
498
+
400
499
func runHttpd (cmd * cobra.Command , args []string ) error {
401
500
port , _ := cmd .Flags ().GetString ("port" )
402
501
path , _ := cmd .Flags ().GetString ("path" )
@@ -413,6 +512,8 @@ func main() {
413
512
root .AddCommand (cmdRunExtUnit )
414
513
cmdReboot .Args = cobra .ExactArgs (1 )
415
514
root .AddCommand (cmdReboot )
515
+ cmdSoftReboot .Args = cobra .ExactArgs (1 )
516
+ root .AddCommand (cmdSoftReboot )
416
517
cmdHttpd .Flags ().StringP ("port" , "" , "80" , "port" )
417
518
cmdHttpd .Flags ().StringP ("path" , "" , "./" , "path to filesystem contents to serve" )
418
519
cmdHttpd .Args = cobra .ExactArgs (0 )
0 commit comments