mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 01:03:40 +00:00
633b9582e7
* Added multiarch build support for teleport oss, ent, and fips * Exported image/imageTag types * Resigned dronegen * Removed remainder of testing changes * Removed changes to submodules * Reverted dockerfile-fips change * FIxed docs wording * Un-exported most constants * Removed teleport.e makefile deb call * Moved "sed | cut magic" to files * Re-added `mkdir -pv /go/cache` to push.go * Command deterministic order fix * Added staging-only tag pipeline * Moved PR to teleport operator to minimize potential issue impact * Updated promote to pull and push without build * Made cron triggers not affect canonical tags * Added check for pre-existing tags on immutable CRs * Added immutability check to manifests * Updated staging ecr to only apply $TIMESTAMP tag on cron triggers * Updated triggerinfo struct to use a triggerflag struct * Fixed makefile after git mistake * Makefile fix * PR fixes * Moved internal tools Go version to constant * Separated container images gofile into multiple files * Moved testing comment * Added licenses * Reorganized and added docs for container images * Moved const to correct file * Tag trigger logic test * Testing specific fix * Moved testing to v10.3.2 * Make semver dirs * Refactored local registry name/socket * Merged previous dockerfile changes * Added TARGETOS TARGETARCH args * Updatd tag to testing tag * Promotion logic test * Promotion fixes * Testing specific fix * Removed prerelease check for testing * Added staging login commands to promote * Fixed missing credentials on promotion pull * Rerun tag test with new "full" semver * Made staging builds only publish full semver * Added semver logging command * Empty commit to trigger Drone * Promotion test * Fixed preceeding v on promote pull * Empty commit to trigger Drone * Re-enabled verify not prerelease step on promote * Cron trigger test * Testing fix * Testing fix 2 * Added sleep timer on docker buildx build * Testing cleanup
231 lines
7.3 KiB
Go
231 lines
7.3 KiB
Go
// Copyright 2021 Gravitational, Inc
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
varDirectory = "/go/var"
|
|
)
|
|
|
|
// Describes a Teleport/repo release version. All product releases are tied to Teleport's release cycle
|
|
// via this struct.
|
|
type ReleaseVersion struct {
|
|
MajorVersion string // This is the major version of a given build. `SearchVersion` should match this when evaluated.
|
|
ShellVersion string // This value will be evaluated by the shell in the context of a Drone step
|
|
RelativeVersionName string // The set of values for this should not change between major releases
|
|
SetupSteps []step // Version-specific steps that must be ran before executing build and push steps
|
|
}
|
|
|
|
func (rv *ReleaseVersion) buildVersionPipeline(triggerSetupSteps []step, flags *TriggerFlags) pipeline {
|
|
pipelineName := fmt.Sprintf("teleport-container-images-%s", rv.RelativeVersionName)
|
|
|
|
setupSteps, dependentStepNames := rv.getSetupStepInformation(triggerSetupSteps)
|
|
|
|
pipeline := newKubePipeline(pipelineName)
|
|
pipeline.Workspace = workspace{Path: "/go"}
|
|
pipeline.Services = []service{
|
|
dockerService(),
|
|
dockerRegistryService(),
|
|
}
|
|
pipeline.Volumes = dockerVolumes()
|
|
pipeline.Environment = map[string]value{
|
|
"DEBIAN_FRONTEND": {
|
|
raw: "noninteractive",
|
|
},
|
|
}
|
|
pipeline.Steps = append(setupSteps, rv.buildSteps(dependentStepNames, flags)...)
|
|
|
|
return pipeline
|
|
}
|
|
|
|
func (rv *ReleaseVersion) getSetupStepInformation(triggerSetupSteps []step) ([]step, []string) {
|
|
triggerSetupStepNames := make([]string, 0, len(triggerSetupSteps))
|
|
for _, triggerSetupStep := range triggerSetupSteps {
|
|
triggerSetupStepNames = append(triggerSetupStepNames, triggerSetupStep.Name)
|
|
}
|
|
|
|
nextStageSetupStepNames := triggerSetupStepNames
|
|
if len(rv.SetupSteps) > 0 {
|
|
versionSetupStepNames := make([]string, 0, len(rv.SetupSteps))
|
|
for _, versionSetupStep := range rv.SetupSteps {
|
|
versionSetupStep.DependsOn = append(versionSetupStep.DependsOn, triggerSetupStepNames...)
|
|
versionSetupStepNames = append(versionSetupStepNames, versionSetupStep.Name)
|
|
}
|
|
|
|
nextStageSetupStepNames = versionSetupStepNames
|
|
}
|
|
|
|
setupSteps := append(triggerSetupSteps, rv.SetupSteps...)
|
|
|
|
return setupSteps, nextStageSetupStepNames
|
|
}
|
|
|
|
func (rv *ReleaseVersion) buildSteps(setupStepNames []string, flags *TriggerFlags) []step {
|
|
clonedRepoPath := "/go/src/github.com/gravitational/teleport"
|
|
steps := make([]step, 0)
|
|
|
|
setupSteps := []step{
|
|
waitForDockerStep(),
|
|
waitForDockerRegistryStep(),
|
|
cloneRepoStep(clonedRepoPath, rv.ShellVersion),
|
|
rv.buildSplitSemverSteps(flags.ShouldOnlyPublishFullSemver),
|
|
}
|
|
for _, setupStep := range setupSteps {
|
|
setupStep.DependsOn = append(setupStep.DependsOn, setupStepNames...)
|
|
steps = append(steps, setupStep)
|
|
setupStepNames = append(setupStepNames, setupStep.Name)
|
|
}
|
|
|
|
for _, product := range rv.getProducts(clonedRepoPath) {
|
|
steps = append(steps, product.buildSteps(rv, setupStepNames, flags)...)
|
|
}
|
|
|
|
return steps
|
|
}
|
|
|
|
type Semver struct {
|
|
Name string // Human-readable name for the information contained in the semver, i.e. "major"
|
|
FilePath string // The path under the working dir where the information can be read from
|
|
FieldCount int // The number of significant version fields available in the semver i.e. "v11" -> 1
|
|
IsImmutable bool
|
|
IsFull bool
|
|
}
|
|
|
|
func (rv *ReleaseVersion) GetSemvers() []*Semver {
|
|
return []*Semver{
|
|
{
|
|
Name: "major",
|
|
FilePath: path.Join(varDirectory, "major-version"),
|
|
FieldCount: 1,
|
|
IsImmutable: false,
|
|
},
|
|
{
|
|
Name: "minor",
|
|
FilePath: path.Join(varDirectory, "minor-version"),
|
|
FieldCount: 2,
|
|
IsImmutable: false,
|
|
},
|
|
rv.GetFullSemver(),
|
|
}
|
|
}
|
|
|
|
func (rv *ReleaseVersion) GetFullSemver() *Semver {
|
|
return &Semver{
|
|
// For releases this is the "canonical" semver.
|
|
// For prereleases this is canonical + metadata.
|
|
// This is done to keep prereleases pushed to staging
|
|
// from overwriting release versions.
|
|
Name: "full",
|
|
FilePath: path.Join(varDirectory, "full-version"),
|
|
IsImmutable: true,
|
|
IsFull: true,
|
|
}
|
|
}
|
|
|
|
func (s *Semver) GetSemverValue() string {
|
|
return fmt.Sprintf("$(cat %q)", s.FilePath)
|
|
}
|
|
|
|
func (rv *ReleaseVersion) buildSplitSemverSteps(onlyBuildFullSemver bool) step {
|
|
semvers := rv.GetSemvers()
|
|
|
|
// Build the commands that generate the semvers
|
|
commands := make([]string, 0, len(semvers))
|
|
stepNameVersions := make([]string, 0, len(semvers))
|
|
for _, semver := range semvers {
|
|
if onlyBuildFullSemver && !semver.IsFull {
|
|
continue
|
|
}
|
|
|
|
commands = append(commands, fmt.Sprintf("mkdir -pv $(dirname %q)", semver.FilePath))
|
|
if semver.IsFull {
|
|
// Special case for full semver where only the "v" should be trimmed
|
|
commands = append(commands, fmt.Sprintf("echo %s | sed 's/v//' > %q", rv.ShellVersion, semver.FilePath))
|
|
} else {
|
|
// Trim the semver metadata and some digits
|
|
// Ex: semver.FieldCount = 3, cutFieldString = "1,2,3"
|
|
cutFieldStrings := make([]string, 0, semver.FieldCount)
|
|
for i := 1; i <= semver.FieldCount; i++ {
|
|
cutFieldStrings = append(cutFieldStrings, strconv.Itoa(i))
|
|
}
|
|
cutFieldString := strings.Join(cutFieldStrings, ",")
|
|
|
|
commands = append(commands, fmt.Sprintf("echo %s | sed 's/v//' | cut -d'.' -f %q > %q",
|
|
rv.ShellVersion, cutFieldString, semver.FilePath))
|
|
}
|
|
// For debugging
|
|
commands = append(commands, fmt.Sprintf("echo %s", semver.GetSemverValue()))
|
|
|
|
stepNameVersions = append(stepNameVersions, semver.Name)
|
|
}
|
|
|
|
// Build the formatted, human-readable step name
|
|
concatStepNameVersions := "Build"
|
|
for i, stepNameVersion := range stepNameVersions {
|
|
if i+1 < len(stepNameVersions) {
|
|
// If not the last version name
|
|
concatStepNameVersions = fmt.Sprintf("%s %s,", concatStepNameVersions, stepNameVersion)
|
|
} else {
|
|
if len(stepNameVersions) > 1 {
|
|
concatStepNameVersions = fmt.Sprintf("%s and", concatStepNameVersions)
|
|
}
|
|
|
|
concatStepNameVersions = fmt.Sprintf("%s %s semver", concatStepNameVersions, stepNameVersion)
|
|
if len(stepNameVersions) > 1 {
|
|
concatStepNameVersions = fmt.Sprintf("%ss", concatStepNameVersions)
|
|
}
|
|
}
|
|
}
|
|
|
|
return step{
|
|
Name: concatStepNameVersions,
|
|
Image: "alpine",
|
|
Commands: commands,
|
|
}
|
|
}
|
|
|
|
func (rv *ReleaseVersion) getProducts(clonedRepoPath string) []*Product {
|
|
teleportOperatorProduct := NewTeleportOperatorProduct(clonedRepoPath)
|
|
|
|
products := make([]*Product, 0, 1)
|
|
products = append(products, teleportOperatorProduct)
|
|
|
|
return products
|
|
}
|
|
|
|
func (rv *ReleaseVersion) getTagsForVersion(onlyBuildFullSemver bool) []*ImageTag {
|
|
semvers := rv.GetSemvers()
|
|
imageTags := make([]*ImageTag, 0, len(semvers))
|
|
for _, semver := range semvers {
|
|
if onlyBuildFullSemver && !semver.IsFull {
|
|
continue
|
|
}
|
|
|
|
imageTags = append(imageTags, &ImageTag{
|
|
ShellBaseValue: semver.GetSemverValue(),
|
|
DisplayBaseValue: semver.Name,
|
|
IsImmutable: semver.IsImmutable,
|
|
})
|
|
}
|
|
|
|
return imageTags
|
|
}
|