func publishImage()

in cli_tools/gce_image_publish/publish/publish.go [271:393]


func publishImage(p *Publish, img *Image, pubImgs []*computeAlpha.Image, skipDuplicates, rep, noRoot bool) (*daisy.CreateImages, *daisy.DeprecateImages, *daisy.DeleteResources, error) {
	if skipDuplicates && rep {
		return nil, nil, nil, errors.New("cannot set both skipDuplicates and replace")
	}

	publishName := img.Prefix
	if p.publishVersion != "" {
		publishName = fmt.Sprintf("%s-%s", publishName, p.publishVersion)
	}
	sourceName := img.Prefix
	if p.sourceVersion != "" {
		sourceName = fmt.Sprintf("%s-%s", sourceName, p.sourceVersion)
	}

	var ds *computeAlpha.DeprecationStatus
	if img.ObsoleteDate != nil {
		ds = &computeAlpha.DeprecationStatus{
			State:    "ACTIVE",
			Obsolete: img.ObsoleteDate.Format(time.RFC3339),
		}
	}

	ci := daisy.ImageAlpha{
		Image: computeAlpha.Image{
			Name:                         publishName,
			Description:                  img.Description,
			Architecture:                 img.Architecture,
			Licenses:                     img.Licenses,
			Family:                       img.Family,
			Deprecated:                   ds,
			ShieldedInstanceInitialState: img.ShieldedInstanceInitialState,
			RolloutOverride:              img.RolloutPolicy,
			Labels:                       img.Labels,
		},
		ImageBase: daisy.ImageBase{
			Resource: daisy.Resource{
				NoCleanup: true,
				Project:   p.PublishProject,
				RealName:  publishName,
			},
			IgnoreLicenseValidationIfForbidden: img.IgnoreLicenseValidationIfForbidden,
		},
		GuestOsFeatures: img.GuestOsFeatures,
	}

	var source string
	if p.SourceProject != "" && p.SourceGCSPath != "" {
		return nil, nil, nil, errors.New("only one of SourceProject or SourceGCSPath should be set")
	}
	if p.SourceProject != "" {
		source = fmt.Sprintf("projects/%s/global/images/%s", p.SourceProject, sourceName)
		ci.Image.SourceImage = source
	} else if p.SourceGCSPath != "" {
		if noRoot {
			source = fmt.Sprintf("%s/%s.tar.gz", p.SourceGCSPath, sourceName)
		} else {
			source = fmt.Sprintf("%s/%s/%s", p.SourceGCSPath, sourceName, gcsImageObj)
		}
		ci.Image.RawDisk = &computeAlpha.ImageRawDisk{Source: source}
	} else {
		return nil, nil, nil, errors.New("neither SourceProject or SourceGCSPath was set")
	}
	cis := &daisy.CreateImages{ImagesAlpha: []*daisy.ImageAlpha{&ci}}

	dis := &daisy.DeprecateImages{}
	drs := &daisy.DeleteResources{}
	for _, pubImg := range pubImgs {
		if pubImg.Name == publishName {
			msg := fmt.Sprintf("%q already exists in project %q", publishName, p.PublishProject)
			if skipDuplicates {
				fmt.Printf("    Image %s, skipping image creation\n", msg)
				cis = nil
				continue
			} else if rep {
				fmt.Printf("    Image %s, replacing\n", msg)
				(*cis).ImagesAlpha[0].OverWrite = true
				continue
			}
			return nil, nil, nil, errors.New(msg)
		}

		if pubImg.Family != img.Family {
			continue
		}

		// Delete all images in the same family with insert date older than p.expiryDate.
		if p.expiryDate != nil {
			createTime, err := time.Parse(time.RFC3339, pubImg.CreationTimestamp)
			if err != nil {
				continue
			}
			if createTime.Before(*p.expiryDate) {
				drs.Images = append(drs.Images, fmt.Sprintf("projects/%s/global/images/%s", p.PublishProject, pubImg.Name))
				continue
			}
		}

		if pubImg.Family == "" {
			continue
		}

		// Deprecate all images in the same family.
		if pubImg.Deprecated == nil || pubImg.Deprecated.State == "" {
			*dis = append(*dis, &daisy.DeprecateImage{
				Image:   pubImg.Name,
				Project: p.PublishProject,
				DeprecationStatusAlpha: computeAlpha.DeprecationStatus{
					State:         "DEPRECATED",
					Replacement:   fmt.Sprintf(fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/images/%s", p.PublishProject, publishName)),
					StateOverride: img.RolloutPolicy,
				},
			})
		}
	}
	if len(*dis) == 0 {
		dis = nil
	}
	if len(drs.Images) == 0 {
		drs = nil
	}

	return cis, dis, drs, nil
}