211 lines
4.8 KiB
Go
211 lines
4.8 KiB
Go
package spec
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/cloudbase/garm-provider-common/params"
|
|
corev1 "k8s.io/api/core/v1"
|
|
)
|
|
|
|
type GitHubScopeDetails struct {
|
|
BaseURL string
|
|
Repo string
|
|
Org string
|
|
Enterprise string
|
|
}
|
|
|
|
type RunnerExtraSpecs struct {
|
|
RunnerWorkDir string `json:"runner_workdir"`
|
|
DisableRunnerUpdate *bool `json:"disable_runner_update"`
|
|
RunnerEphemeral *bool `json:"runner_ephemeral"`
|
|
PodSpec *corev1.PodSpec `json:"pod_spec,omitempty"`
|
|
}
|
|
|
|
func ExtractGitHubScopeDetails(gitRepoURL string) (GitHubScopeDetails, error) {
|
|
if gitRepoURL == "" {
|
|
return GitHubScopeDetails{}, fmt.Errorf("no gitRepoURL supplied")
|
|
}
|
|
u, err := url.Parse(gitRepoURL)
|
|
if err != nil {
|
|
return GitHubScopeDetails{}, fmt.Errorf("invalid URL: %w", err)
|
|
}
|
|
|
|
if u.Scheme == "" || u.Host == "" {
|
|
return GitHubScopeDetails{}, fmt.Errorf("invalid URL: %s", gitRepoURL)
|
|
}
|
|
|
|
pathParts := strings.Split(strings.Trim(u.Path, "/"), "/")
|
|
|
|
scope := GitHubScopeDetails{
|
|
BaseURL: u.Scheme + "://" + u.Host,
|
|
}
|
|
|
|
switch {
|
|
case len(pathParts) == 1:
|
|
scope.Org = pathParts[0]
|
|
case len(pathParts) == 2 && pathParts[0] == "enterprises":
|
|
scope.Enterprise = pathParts[1]
|
|
case len(pathParts) == 2:
|
|
scope.Org = pathParts[0]
|
|
scope.Repo = pathParts[1]
|
|
default:
|
|
return GitHubScopeDetails{}, fmt.Errorf("URL does not match the expected patterns")
|
|
}
|
|
|
|
return scope, nil
|
|
}
|
|
|
|
func ParseExtraSpecs(bootstrapParams params.BootstrapInstance) RunnerExtraSpecs {
|
|
var extraSpecs RunnerExtraSpecs
|
|
if len(bootstrapParams.ExtraSpecs) > 0 {
|
|
_ = json.Unmarshal(bootstrapParams.ExtraSpecs, &extraSpecs)
|
|
}
|
|
return extraSpecs
|
|
}
|
|
|
|
func GetRunnerEnvs(gitHubScope GitHubScopeDetails, bootstrapParams params.BootstrapInstance) []corev1.EnvVar {
|
|
extraSpecs := ParseExtraSpecs(bootstrapParams)
|
|
|
|
runnerWorkDir := extraSpecs.RunnerWorkDir
|
|
if runnerWorkDir == "" {
|
|
runnerWorkDir = "/runner/_work/"
|
|
}
|
|
|
|
disableRunnerUpdate := "true"
|
|
if extraSpecs.DisableRunnerUpdate != nil {
|
|
disableRunnerUpdate = fmt.Sprintf("%t", *extraSpecs.DisableRunnerUpdate)
|
|
}
|
|
|
|
runnerEphemeral := "true"
|
|
if extraSpecs.RunnerEphemeral != nil {
|
|
runnerEphemeral = fmt.Sprintf("%t", *extraSpecs.RunnerEphemeral)
|
|
}
|
|
|
|
return []corev1.EnvVar{
|
|
{
|
|
Name: "RUNNER_GITEA_INSTANCE",
|
|
Value: bootstrapParams.RepoURL,
|
|
},
|
|
{
|
|
Name: "RUNNER_GROUP",
|
|
Value: bootstrapParams.GitHubRunnerGroup,
|
|
},
|
|
{
|
|
Name: "RUNNER_NAME",
|
|
Value: bootstrapParams.Name,
|
|
},
|
|
{
|
|
Name: "RUNNER_LABELS",
|
|
Value: strings.Join(bootstrapParams.Labels, ","),
|
|
},
|
|
{
|
|
Name: "RUNNER_NO_DEFAULT_LABELS",
|
|
Value: "true",
|
|
},
|
|
{
|
|
Name: "DISABLE_RUNNER_UPDATE",
|
|
Value: disableRunnerUpdate,
|
|
},
|
|
{
|
|
Name: "RUNNER_WORKDIR",
|
|
Value: runnerWorkDir,
|
|
},
|
|
{
|
|
Name: "GITHUB_URL",
|
|
Value: gitHubScope.BaseURL,
|
|
},
|
|
{
|
|
Name: "RUNNER_EPHEMERAL",
|
|
Value: runnerEphemeral,
|
|
},
|
|
{
|
|
Name: "RUNNER_TOKEN",
|
|
Value: "dummy",
|
|
},
|
|
{
|
|
Name: "METADATA_URL",
|
|
Value: bootstrapParams.MetadataURL,
|
|
},
|
|
{
|
|
Name: "BEARER_TOKEN",
|
|
Value: bootstrapParams.InstanceToken,
|
|
},
|
|
{
|
|
Name: "CALLBACK_URL",
|
|
Value: bootstrapParams.CallbackURL,
|
|
},
|
|
{
|
|
Name: "JIT_CONFIG_ENABLED",
|
|
Value: fmt.Sprintf("%t", bootstrapParams.JitConfigEnabled),
|
|
},
|
|
}
|
|
}
|
|
|
|
func GetPodSpec(gitHubScope GitHubScopeDetails, bootstrapParams params.BootstrapInstance) corev1.PodSpec {
|
|
extraSpecs := ParseExtraSpecs(bootstrapParams)
|
|
|
|
if extraSpecs.PodSpec != nil {
|
|
return *extraSpecs.PodSpec
|
|
}
|
|
|
|
envs := GetRunnerEnvs(gitHubScope, bootstrapParams)
|
|
|
|
return corev1.PodSpec{
|
|
RestartPolicy: corev1.RestartPolicyNever,
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "runner",
|
|
Image: "edp.buildth.ing/devfw-cicd/garm-act-runner:1",
|
|
ImagePullPolicy: "Always",
|
|
Env: envs,
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: "buildkitd-deamon",
|
|
MountPath: "/run/user/1000/buildkit",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "buildkitd",
|
|
Image: "moby/buildkit:buildx-stable-1-rootless",
|
|
Args: []string{
|
|
"--allow-insecure-entitlement=network.host",
|
|
"--oci-worker-no-process-sandbox",
|
|
},
|
|
ImagePullPolicy: corev1.PullIfNotPresent,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
Exec: &corev1.ExecAction{
|
|
Command: []string{
|
|
"buildctl",
|
|
"debug",
|
|
"workers",
|
|
},
|
|
},
|
|
},
|
|
FailureThreshold: 3,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
TimeoutSeconds: 1,
|
|
},
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: "buildkitd-deamon",
|
|
MountPath: "/run/user/1000/buildkit",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "buildkitd-deamon",
|
|
VolumeSource: corev1.VolumeSource{
|
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|