service

package
v0.0.0-...-b74f83a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 3, 2024 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const AgentMinIdlePeriodDefault = time.Duration(5 * time.Minute)
View Source
const AzureWorkingDirMountName = "workspace"
View Source
const AzureWorkingDirMountPath = "/azp/_work"
View Source
const CapabilitiesAnnotationName = "AzurePipelinesCapabilities"
View Source
const DebugLogEnvVarName = "DEBUG_FILE_PATH"
View Source
const DummyAgentNamePrefix = "dummy-agent"
View Source
const ExtraAgentContainersAnnotationKey = "ExtraAgentContainers"
View Source
const IdleAgentPodFirstDetectionTimestampAnnotationKey = "FirstIdleDetectionTimestamp"
View Source
const NonExistentContainerImageSuffix = "does-not-exist-for-sure"
View Source
const PodTerminationInProgressAnnotationKey = "TerminationInProgress"
View Source
const ReusableCacheVolumeNameAnnotationKey = "ReusableCacheVolumeName"
View Source
const ReusableCacheVolumePromisedAnnotationKey = "PromisedForPod"

Variables

This section is empty.

Functions

func ComputeCustomResourceHash

func ComputeCustomResourceHash(spec *apscalerv1.AutoScaledAgentSpec) (string, error)

func ComputeMapHash

func ComputeMapHash(capabilities *map[string]string) string

func ComputePvcMaxCountsPerReusableCacheVolume

func ComputePvcMaxCountsPerReusableCacheVolume(agent *apscalerv1.AutoScaledAgent) *map[string]int

ComputePvcMaxCountsPerReusableCacheVolume computes a dict that maps from the name of a reusable cache volume to the maximum number of PVC instances we want to instantiate. It only contains entries for those reusable cache volumes that are actually used by at least one Pod. The goal is to avoid creating too many PVCs, resulting from the problem that the removal of the "promised" label of PVCs is slow.

func CreateHTTPClient

func CreateHTTPClient() *http.Client

func CreateOrUpdateDummyAgents

func CreateOrUpdateDummyAgents(ctx context.Context, poolId int64, azurePat string, httpClient *http.Client,
	crName string, spec *apscalerv1.AutoScaledAgentSpec) ([]string, error)

CreateOrUpdateDummyAgents registers one dummy agent for each PodsWithCapabilities, as otherwise Azure DevOps would immediately abort a pipeline

func DeleteAgent

func DeleteAgent(ctx context.Context, organizationUrl string, poolId int64, azurePat string, httpClient *http.Client, agentId int) error

func DeleteDeadDummyAgents

func DeleteDeadDummyAgents(ctx context.Context, poolId int64, azurePat string, httpClient *http.Client,
	spec *apscalerv1.AutoScaledAgentSpec, crName string, dummyAgentsToKeep []string) error

DeleteDeadDummyAgents deletes all those registered Azure DevOps agents that have an "offline" status, have a name starting with <DummyAgentNamePrefix> and that have been created some time ago (i.e., any AZP job that needs a registered agent is very likely to already have started). DeleteDeadDummyAgents performs actual API calls only in regular intervals, to avoid spamming the AZP API.

func GenerateRandomString

func GenerateRandomString() string

func GetCapabilitiesMapFromString

func GetCapabilitiesMapFromString(capabilities string) *map[string]string

GetCapabilitiesMapFromString does the inverse of GetSortedStringificationOfCapabilitiesMap

func GetContainerSpecIndex

func GetContainerSpecIndex(pod *corev1.Pod, containerStatusIndex int) (int, error)

GetContainerSpecIndex is the reverse of GetContainerStatusIndex. It returns the index of the container in the Pod template spec(!) whose name matches the name of the container in the Pod status for the given containerStatusIndex.

func GetContainerStatusIndex

func GetContainerStatusIndex(pod *corev1.Pod, containerIndexInSpec int) (int, error)

GetContainerStatusIndex returns the index of the container status in the Pod whose name matches the name of the container in the Pod spec for the given containerIndexInSpec. This is necessary because the container statuses in the Pod are not guaranteed to be in the same order as the containers in the Pod template spec (but the statuses may e.g. be sorted alphabetically).

func GetFilteredRunningPods

func GetFilteredRunningPods(pods []corev1.Pod) []corev1.Pod

func GetJobCount

func GetJobCount(pendingJobs *map[string][]PendingJob) int

func GetMatchingCacheVolume

func GetMatchingCacheVolume(volumeName string, reusableVolumes []apscalerv1.ReusableCacheVolume) *apscalerv1.ReusableCacheVolume

func GetPodCountAndNames

func GetPodCountAndNames(runningPods *map[string][]corev1.Pod) (int32, []string)

func GetPoolIdFromName

func GetPoolIdFromName(ctx context.Context, azurePat string, httpClient *http.Client,
	spec *apscalerv1.AutoScaledAgentSpec) (int64, error)

func GetSortedStringificationOfCapabilitiesMap

func GetSortedStringificationOfCapabilitiesMap(m *map[string]string) string

GetSortedStringificationOfCapabilitiesMap returns a stringified map, of the form <key1>=<value1>;<key2>=<value2>;...

func GetUnpromisedPvc

func GetUnpromisedPvc(pvcs []corev1.PersistentVolumeClaim, volumeName string) *corev1.PersistentVolumeClaim

func HasPodPermanentlyDisappeared

func HasPodPermanentlyDisappeared(podName string) bool

HasPodPermanentlyDisappeared is given the name of a pod that can no longer be found, and returns true if this method has been called for the same podName for several seconds, thus increasing the likelihood that the pod is really gone (due to client-side caching)

func IsPvcLimitExceeded

func IsPvcLimitExceeded(agent *apscalerv1.AutoScaledAgent, cacheVolumeName string, pvcs []corev1.PersistentVolumeClaim) bool

func IsVerboseDebugLoggingEnabled

func IsVerboseDebugLoggingEnabled() bool

func ParseExtraAgentContainerDefinition

func ParseExtraAgentContainerDefinition(extraAgentContainers string) ([]corev1.Container, error)

ParseExtraAgentContainerDefinition takes a string such as "name=ubuntu,image=docker.io/library/ubuntu:22.04,cpu=250m,memory=64Mi||name=postgresql,image=docker.io/library/postgres:14,cpu=250m,memory=1Gi" (where the "cpu" and "memory" attributes are optional) and converts them to an array of Container objects

func PrintPendingJobsIfChanged

func PrintPendingJobsIfChanged(ctx context.Context, crName string, pendingJobs *PendingJobsWrapper)

PrintPendingJobsIfChanged stringifies the PendingJobs and logs them if they changed since the last reconciliation

Types

type AzurePipelinesAgent

type AzurePipelinesAgent struct {
	CreatedOn time.Time `json:"createdOn"`
	Name      string    `json:"name"`
	Id        int       `json:"id"`
	Status    string    `json:"status"`
}

type AzurePipelinesAgentList

type AzurePipelinesAgentList struct {
	Count int                   `json:"count"`
	Value []AzurePipelinesAgent `json:"value"`
}

type AzurePipelinesApiJobRequest

type AzurePipelinesApiJobRequest struct {
	RequestID     int       `json:"requestId"`
	QueueTime     time.Time `json:"queueTime"`
	AssignTime    time.Time `json:"assignTime,omitempty"`
	ReceiveTime   time.Time `json:"receiveTime,omitempty"`
	LockedUntil   time.Time `json:"lockedUntil,omitempty"`
	ServiceOwner  string    `json:"serviceOwner"`
	HostID        string    `json:"hostId"`
	Result        *string   `json:"result"`
	ScopeID       string    `json:"scopeId"`
	PlanType      string    `json:"planType"`
	PlanID        string    `json:"planId"`
	JobID         string    `json:"jobId"`
	Demands       []string  `json:"demands"`
	ReservedAgent *struct {
		Links struct {
			Self struct {
				Href string `json:"href"`
			} `json:"self"`
			Web struct {
				Href string `json:"href"`
			} `json:"web"`
		} `json:"_links"`
		ID                int    `json:"id"`
		Name              string `json:"name"`
		Version           string `json:"version"`
		OsDescription     string `json:"osDescription"`
		Enabled           bool   `json:"enabled"`
		Status            string `json:"status"`
		ProvisioningState string `json:"provisioningState"`
		AccessPoint       string `json:"accessPoint"`
	} `json:"reservedAgent,omitempty"`
	Definition struct {
		Links struct {
			Web struct {
				Href string `json:"href"`
			} `json:"web"`
			Self struct {
				Href string `json:"href"`
			} `json:"self"`
		} `json:"_links"`
		ID   int    `json:"id"`
		Name string `json:"name"`
	} `json:"definition"`
	Owner struct {
		Links struct {
			Web struct {
				Href string `json:"href"`
			} `json:"web"`
			Self struct {
				Href string `json:"href"`
			} `json:"self"`
		} `json:"_links"`
		ID   int    `json:"id"`
		Name string `json:"name"`
	} `json:"owner"`
	Data struct {
		ParallelismTag string `json:"ParallelismTag"`
		IsScheduledKey string `json:"IsScheduledKey"`
	} `json:"data"`
	PoolID          int    `json:"poolId"`
	OrchestrationID string `json:"orchestrationId"`
	Priority        int    `json:"priority"`
	MatchedAgents   *[]struct {
		Links struct {
			Self struct {
				Href string `json:"href"`
			} `json:"self"`
			Web struct {
				Href string `json:"href"`
			} `json:"web"`
		} `json:"_links"`
		ID                int    `json:"id"`
		Name              string `json:"name"`
		Version           string `json:"version"`
		Enabled           bool   `json:"enabled"`
		Status            string `json:"status"`
		ProvisioningState string `json:"provisioningState"`
	} `json:"matchedAgents,omitempty"`
}

type AzurePipelinesApiJobRequests

type AzurePipelinesApiJobRequests struct {
	Count int                           `json:"count"`
	Value []AzurePipelinesApiJobRequest `json:"value"`
}

type AzurePipelinesApiPoolNameResponse

type AzurePipelinesApiPoolNameResponse struct {
	// Because there could be multiple Azure Pipeline pools with the same name, the API returns an array. The objects
	// have many more fields, but we only care about the ID, and omit defining the other fields.
	Value []struct {
		ID int `json:"id"`
	} `json:"value"`
}

type AzurePipelinesRegisterAgentRequest

type AzurePipelinesRegisterAgentRequest struct {
	Name               string            `json:"name"`
	Version            string            `json:"version"`
	OsDescription      string            `json:"osDescription"`
	Enabled            bool              `json:"enabled"`
	Status             string            `json:"status"`
	ProvisioningState  string            `json:"provisioningState"`
	SystemCapabilities map[string]string `json:"systemCapabilities"`
}

type InexactMatchStringMap

type InexactMatchStringMap map[string]string

func (*InexactMatchStringMap) GetSortedStringificationOfMap

func (m *InexactMatchStringMap) GetSortedStringificationOfMap() string

GetSortedStringificationOfMap returns a stringified map, of the form <key1>=<value1>,<key2>=<value2>,...

func (*InexactMatchStringMap) IsInexactMatch

func (m *InexactMatchStringMap) IsInexactMatch(input *map[string]string) bool

IsInexactMatch returns true if all elements in `input` are also in `m`. `m` may contain one additional key named "ExtraAgentContainers"

type PendingJob

type PendingJob struct {
	RequestID  int
	QueueTime  time.Time
	AssignTime time.Time
	Demands    map[string]string
}

PendingJob is based on AzurePipelinesApiJobRequest, but has much fewer fields. The AzurePipelinesApiJobRequest.demands are turned into a string-string-map

type PendingJobsWithDemands

type PendingJobsWithDemands struct {
	// contains filtered or unexported fields
}

type PendingJobsWrapper

type PendingJobsWrapper struct {
	PendingJobs []PendingJobsWithDemands
}

func GetPendingJobs

func GetPendingJobs(ctx context.Context, poolId int64, azurePat string, httpClient *http.Client,
	spec *apscalerv1.AutoScaledAgentSpec) (*PendingJobsWrapper, error)

func (*PendingJobsWrapper) AddJobRequest

func (pjw *PendingJobsWrapper) AddJobRequest(jobRequestFromApi *AzurePipelinesApiJobRequest)

func (*PendingJobsWrapper) GetInexactMatch

func (pjw *PendingJobsWrapper) GetInexactMatch(capabilities *map[string]string) *map[string][]PendingJob

type PvcExhaustionError

type PvcExhaustionError struct {
	ReusableCacheVolumeName string
}

func (*PvcExhaustionError) Error

func (e *PvcExhaustionError) Error() string

type RunningPodsWithCapabilities

type RunningPodsWithCapabilities struct {
	Capabilities InexactMatchStringMap
	RunningPods  []corev1.Pod
}

type RunningPodsWrapper

type RunningPodsWrapper struct {
	RunningPods []RunningPodsWithCapabilities
}

func NewRunningPodsWrapper

func NewRunningPodsWrapper(runningPods []corev1.Pod) *RunningPodsWrapper

func (*RunningPodsWrapper) GetInexactMatch

func (rpw *RunningPodsWrapper) GetInexactMatch(capabilities *map[string]string) *map[string][]corev1.Pod

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL