in step_create_instances.go [54:122]
func logSerialOutput(ctx context.Context, s *Step, ii InstanceInterface, ib *InstanceBase, port int64, interval time.Duration) {
w := s.w
w.stepWait.Add(1)
defer w.stepWait.Done()
logsObj := path.Join(w.logsPath, fmt.Sprintf("%s-serial-port%d.log", ii.getName(), port))
w.LogStepInfo(s.name, "CreateInstances", "Streaming instance %q serial port %d output to https://storage.cloud.google.com/%s/%s", ii.getName(), port, w.bucket, logsObj)
var start int64
var buf bytes.Buffer
var gcsErr bool
var readFromSerial bool
var numErr int
tick := time.Tick(interval)
Loop:
for {
select {
case <-tick:
resp, err := w.ComputeClient.GetSerialPortOutput(path.Base(ib.Project), path.Base(ii.getZone()), ii.getName(), port, start)
if err != nil {
numErr++
status, sErr := w.ComputeClient.InstanceStatus(path.Base(ib.Project), path.Base(ii.getZone()), ii.getName())
switch status {
case "TERMINATED", "STOPPED", "STOPPING":
// Instance is stopped or stopping.
if sErr == nil {
break Loop
}
}
if numErr > 10 {
// Only emit an error log if we were able to read *some* data from the
// instance, since there's a race condition where an instance can shut
// down fast enough that the call to InstanceStatus will return a 404.
if !readFromSerial {
w.LogStepInfo(s.name, "CreateInstances",
"Instance %q: error getting serial port: %v", ii.getName(), err)
}
break Loop
}
continue
}
readFromSerial = true
numErr = 0
start = resp.Next
buf.WriteString(resp.Contents)
w.Logger.AppendSerialPortLogs(w, ii.getName(), resp.Contents)
wc := w.StorageClient.Bucket(w.bucket).Object(logsObj).NewWriter(ctx)
wc.ContentType = "text/plain"
if _, err := wc.Write(buf.Bytes()); err != nil && !gcsErr {
gcsErr = true
w.LogStepInfo(s.name, "CreateInstances", "Instance %q: error writing log to GCS: %v", ii.getName(), err)
continue
} else if err != nil { // dont try to close the writer
continue
}
if err := wc.Close(); err != nil && !gcsErr {
gcsErr = true
w.LogStepInfo(s.name, "CreateInstances", "Instance %q: error saving log to GCS: %v", ii.getName(), err)
continue
}
if w.isCanceled {
break Loop
}
}
}
w.Logger.WriteSerialPortLogsToCloudLogging(w, ii.getName())
}