in testworkflow.go [596:721]
func finalizeWorkflows(ctx context.Context, tests []*TestWorkflow, zone, gcsPrefix, localPath string) error {
log.Printf("Storing artifacts and logs in %s", gcsPrefix)
for _, twf := range tests {
if twf.wf == nil {
return fmt.Errorf("found nil workflow in finalize")
}
twf.wf.StorageClient = client
// $GCS_PATH/2021-04-20T11:44:08-07:00/image_validation/debian-10
twf.GCSPath = fmt.Sprintf("%s/%s/%s", gcsPrefix, twf.Name, twf.Image.Name)
twf.wf.GCSPath = twf.GCSPath
twf.wf.Zone = zone
// Process quota steps and associated creation steps.
for quotaStepName, createStepName := range map[string]string{
waitForVMQuotaStepName: createVMsStepName,
waitForDisksQuotaStepName: createDisksStepName,
} {
quotaStep, ok := twf.wf.Steps[quotaStepName]
if !ok {
continue
}
for _, q := range quotaStep.WaitForAvailableQuotas.Quotas {
// Populate empty regions with best guess from the zone
if q.Region == "" {
lastIndex := strings.LastIndex(twf.wf.Zone, "-")
q.Region = twf.wf.Zone[:lastIndex]
}
}
createStep, ok := twf.wf.Steps[createStepName]
if !ok {
continue
}
// Fix dependencies. Create steps should depend on the quota step, and quota steps should inherit all other dependencies.
for _, dep := range twf.wf.Dependencies[createStepName] {
dStep, ok := twf.wf.Steps[dep]
if ok {
if err := twf.wf.AddDependency(quotaStep, dStep); err != nil {
return err
}
}
}
if err := twf.wf.AddDependency(createStep, quotaStep); err != nil {
return err
}
}
// Assume amd64 when arch is not set.
arch := "amd64"
if twf.Image.Architecture == "ARM64" {
arch = "arm64"
}
createDisksStep, createDisksOk := twf.wf.Steps[createDisksStepName]
createVMsStep, ok := twf.wf.Steps[createVMsStepName]
if ok {
for _, vm := range createVMsStep.CreateInstances.Instances {
if vm.MachineType != "" {
log.Printf("VM %s machine type set to %s for test %s\n", vm.Name, vm.MachineType, twf.Name)
} else {
vm.MachineType = twf.MachineType.Name
}
if vm.Zone != "" && vm.Zone != twf.wf.Zone {
log.Printf("VM %s zone is set to %s, differing from workflow zone %s for test %s, not overriding\n", vm.Name, vm.Zone, twf.wf.Zone, twf.Name)
}
if createDisksOk && (strings.HasPrefix(vm.MachineType, "c4-") || strings.HasPrefix(vm.MachineType, "n4-") || strings.HasPrefix(vm.MachineType, "c3-")) {
for _, attachedDisk := range vm.Disks {
for _, disk := range *createDisksStep.CreateDisks {
if attachedDisk.Source == disk.Name && disk.Type == "" {
disk.Type = HyperdiskBalanced
}
}
}
}
// Correct initialize params disk types for custom attached disks.
for _, attachedDisk := range vm.Disks {
if attachedDisk.InitializeParams != nil {
// Default to standard if no disk type is specified.
if attachedDisk.InitializeParams.DiskType != "" && !strings.HasPrefix(attachedDisk.InitializeParams.DiskType, "zones/") {
// Qualify the disk type with the zone if it's missing.
attachedDisk.InitializeParams.DiskType = fmt.Sprintf("zones/%s/diskTypes/%s", vm.Zone, attachedDisk.InitializeParams.DiskType)
}
}
}
}
}
if utils.HasFeature(twf.Image, "WINDOWS") {
archBits := "64"
if strings.Contains(twf.ImageURL, "x86") {
archBits = "32"
}
twf.wf.Sources["testpackage"] = fmt.Sprintf("%s/%s%s.exe", localPath, twf.Name, archBits)
twf.wf.Sources["wrapper.exe"] = fmt.Sprintf("%s/%s%s.exe", localPath, testWrapperPathWindows, archBits)
} else {
twf.wf.Sources["testpackage"] = fmt.Sprintf("%s/%s.%s.test", localPath, twf.Name, arch)
twf.wf.Sources["wrapper"] = fmt.Sprintf("%s%s.%s", localPath, testWrapperPath, arch)
}
// add a final copy-objects step which copies the daisy-outs-path directory to twf.gcsPath + /outs
copyGCSObject := daisy.CopyGCSObject{}
copyGCSObject.Source = "${OUTSPATH}/" // Trailing slash apparently crucial.
copyGCSObject.Destination = twf.GCSPath + "/outs"
copyGCSObjects := &daisy.CopyGCSObjects{copyGCSObject}
copyStep, err := twf.wf.NewStep("copy-objects")
if err != nil {
return fmt.Errorf("failed to add copy-objects step to workflow %s: %v", twf.Name, err)
}
copyStep.CopyGCSObjects = copyGCSObjects
// The "copy-objects" step depends on every wait step.
for stepname, step := range twf.wf.Steps {
if !strings.HasPrefix(stepname, "wait-") {
continue
}
if err := twf.wf.AddDependency(copyStep, step); err != nil {
return fmt.Errorf("failed to add copy-objects step: %v", err)
}
}
}
return nil
}