@@ -314,18 +314,36 @@ func (d *Driver) Start() error {
314314 log .Debugf ("starting domain XML:\n %s" , domXML )
315315 }
316316
317+ // libvirt/qemu creates a console log file owned by root:root and permissions 0600,
318+ // so we pre-create it (and close it immediately), just to be able to read it later
319+ logPath := consoleLogPath (* d )
320+ f , err := os .Create (logPath )
321+ if err != nil {
322+ log .Debugf ("failed to create console log file %q: %v" , logPath , err )
323+ } else {
324+ f .Close ()
325+ }
326+ // ensure console log file is cleaned up
327+ defer func () {
328+ if _ , err := os .Stat (logPath ); err == nil {
329+ if err := os .Remove (logPath ); err != nil {
330+ log .Debugf ("failed removing console log file %q: %v" , logPath , err )
331+ }
332+ }
333+ }()
334+
317335 if err := dom .Create (); err != nil {
318336 return errors .Wrap (err , "creating domain" )
319337 }
320338
321339 log .Info ("waiting for domain to start..." )
322- if err := d .waitForDomainState (state .Running , 1 * time .Minute ); err != nil {
340+ if err := d .waitForDomainState (state .Running , 30 * time .Second ); err != nil {
323341 return errors .Wrap (err , "waiting for domain to start" )
324342 }
325343 log .Info ("domain is now running" )
326344
327345 log .Info ("waiting for IP..." )
328- if err := d .waitForStaticIP (conn , 2 * time .Minute ); err != nil {
346+ if err := d .waitForStaticIP (conn , 90 * time .Second ); err != nil {
329347 return errors .Wrap (err , "waiting for IP" )
330348 }
331349
@@ -337,6 +355,12 @@ func (d *Driver) Start() error {
337355 return nil
338356}
339357
358+ // consoleLogPath returns the path to the console log file for the given machine name.
359+ func consoleLogPath (d Driver ) string {
360+ // return fmt.Sprintf("%s-console.log", machineName)
361+ return d .ResolveStorePath ("console.log" )
362+ }
363+
340364// waitForDomainState waits maxTime for the domain to reach a target state.
341365func (d * Driver ) waitForDomainState (targetState state.State , maxTime time.Duration ) error {
342366 query := func () error {
@@ -353,11 +377,27 @@ func (d *Driver) waitForDomainState(targetState state.State, maxTime time.Durati
353377 return fmt .Errorf ("last domain state: %q" , currentState .String ())
354378 }
355379 if err := retry .Local (query , maxTime ); err != nil {
380+ dumpConsoleLogs (consoleLogPath (* d ))
356381 return fmt .Errorf ("timed out waiting %v for domain to reach %q state: %w" , maxTime , targetState .String (), err )
357382 }
358383 return nil
359384}
360385
386+ // dumpConsoleLogs prints out the console log.
387+ func dumpConsoleLogs (logPath string ) {
388+ if _ , err := os .Stat (logPath ); err != nil {
389+ log .Debugf ("failed checking console log file %q: %v" , logPath , err )
390+ return
391+ }
392+
393+ data , err := os .ReadFile (logPath )
394+ if err != nil {
395+ log .Debugf ("failed dumping console log file %q: %v" , logPath , err )
396+ return
397+ }
398+ log .Debugf ("console log:\n %s" , data )
399+ }
400+
361401// waitForStaticIP waits for IP address of domain that has been created & starting and then makes that IP static.
362402func (d * Driver ) waitForStaticIP (conn * libvirt.Connect , maxTime time.Duration ) error {
363403 query := func () error {
@@ -376,6 +416,7 @@ func (d *Driver) waitForStaticIP(conn *libvirt.Connect, maxTime time.Duration) e
376416 return nil
377417 }
378418 if err := retry .Local (query , maxTime ); err != nil {
419+ dumpConsoleLogs (consoleLogPath (* d ))
379420 return fmt .Errorf ("domain %s didn't return IP after %v" , d .MachineName , maxTime )
380421 }
381422
0 commit comments