@@ -105,10 +105,25 @@ reboot
105105 autopkgtestRebootPrepareScript = `#!/bin/bash
106106set -euo pipefail
107107exec /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"
108122`
109123
110124 // 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"
112127)
113128
114129var (
@@ -140,6 +155,13 @@ var (
140155 SilenceUsage : true ,
141156 }
142157
158+ cmdSoftReboot = & cobra.Command {
159+ Use : "soft-reboot-request MARK" ,
160+ Short : "Request a soft reboot" ,
161+ RunE : runSoftReboot ,
162+ SilenceUsage : true ,
163+ }
164+
143165 cmdHttpd = & cobra.Command {
144166 Use : "httpd" ,
145167 Short : "Start an HTTP server to serve the contents of the file system" ,
@@ -260,6 +282,11 @@ func initiateReboot(mark string) error {
260282}
261283
262284func 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+ }
263290 c := exec .Command ("mkfifo" , path )
264291 c .Stderr = os .Stderr
265292 err := c .Run ()
@@ -269,6 +296,20 @@ func mkfifo(path string) error {
269296 return nil
270297}
271298
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+
272313func runExtUnit (cmd * cobra.Command , args []string ) error {
273314 rebootOff , _ := cmd .Flags ().GetBool ("deny-reboots" )
274315 // Write the autopkgtest wrappers
@@ -278,10 +319,18 @@ func runExtUnit(cmd *cobra.Command, args []string) error {
278319 if err := os .WriteFile (autopkgTestRebootPreparePath , []byte (autopkgtestRebootPrepareScript ), 0755 ); err != nil {
279320 return err
280321 }
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+ }
281329
282330 // Create the reboot cmdline -> login FIFO for the reboot mark and
283331 // proxy it into a channel
284332 rebootChan := make (chan string )
333+ softRebootChan := make (chan string )
285334 errChan := make (chan error )
286335
287336 // We want to prevent certain tests (like non-exclusive tests) from rebooting
@@ -303,6 +352,25 @@ func runExtUnit(cmd *cobra.Command, args []string) error {
303352 }
304353 rebootChan <- string (buf )
305354 }()
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+ }()
306374 }
307375
308376 ctx := context .Background ()
@@ -344,6 +412,8 @@ func runExtUnit(cmd *cobra.Command, args []string) error {
344412 return err
345413 case reboot := <- rebootChan :
346414 return initiateReboot (reboot )
415+ case softReboot := <- softRebootChan :
416+ return initiateSoftReboot (softReboot )
347417 case m := <- unitevents :
348418 for n := range m {
349419 if n == unitname {
@@ -397,6 +467,35 @@ func runReboot(cmd *cobra.Command, args []string) error {
397467 return nil
398468}
399469
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+
400499func runHttpd (cmd * cobra.Command , args []string ) error {
401500 port , _ := cmd .Flags ().GetString ("port" )
402501 path , _ := cmd .Flags ().GetString ("path" )
@@ -413,6 +512,8 @@ func main() {
413512 root .AddCommand (cmdRunExtUnit )
414513 cmdReboot .Args = cobra .ExactArgs (1 )
415514 root .AddCommand (cmdReboot )
515+ cmdSoftReboot .Args = cobra .ExactArgs (1 )
516+ root .AddCommand (cmdSoftReboot )
416517 cmdHttpd .Flags ().StringP ("port" , "" , "80" , "port" )
417518 cmdHttpd .Flags ().StringP ("path" , "" , "./" , "path to filesystem contents to serve" )
418519 cmdHttpd .Args = cobra .ExactArgs (0 )
0 commit comments