diff --git a/apiserver/controllers/metadata.go b/apiserver/controllers/metadata.go index 1e00b5b7..9a9496d2 100644 --- a/apiserver/controllers/metadata.go +++ b/apiserver/controllers/metadata.go @@ -41,14 +41,17 @@ func (a *APIController) JITCredentialsFileHandler(w http.ResponseWriter, r *http return } - data, err := a.r.GetJITConfigFile(ctx, fileName) + dotFileName := fmt.Sprintf(".%s", fileName) + + data, err := a.r.GetJITConfigFile(ctx, dotFileName) if err != nil { + log.Printf("getting JIT config file: %s", err) handleError(w, err) return } // Note the leading dot in the filename - name := fmt.Sprintf("attachment; filename=.%s", fileName) + name := fmt.Sprintf("attachment; filename=%s", dotFileName) w.Header().Set("Content-Disposition", name) w.Header().Set("Content-Type", "octet-stream") w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data))) diff --git a/apiserver/routers/routers.go b/apiserver/routers/routers.go index 6e853a99..8d80e356 100644 --- a/apiserver/routers/routers.go +++ b/apiserver/routers/routers.go @@ -121,10 +121,10 @@ func NewAPIRouter(han *controllers.APIController, logWriter io.Writer, authMiddl metadataRouter.Handle("/credentials/{fileName}/", http.HandlerFunc(han.JITCredentialsFileHandler)).Methods("GET", "OPTIONS") metadataRouter.Handle("/credentials/{fileName}", http.HandlerFunc(han.JITCredentialsFileHandler)).Methods("GET", "OPTIONS") // Systemd files - metadataRouter.Handle("/systemd/service-name/", http.HandlerFunc(han.SystemdServiceNameHandler)).Methods("GET", "OPTIONS") - metadataRouter.Handle("/systemd/service-name/", http.HandlerFunc(han.SystemdServiceNameHandler)).Methods("GET", "OPTIONS") - metadataRouter.Handle("/systemd/runner-service/", http.HandlerFunc(han.SystemdUnitFileHandler)).Methods("GET", "OPTIONS") - metadataRouter.Handle("/systemd/runner-service", http.HandlerFunc(han.SystemdUnitFileHandler)).Methods("GET", "OPTIONS") + metadataRouter.Handle("/system/service-name/", http.HandlerFunc(han.SystemdServiceNameHandler)).Methods("GET", "OPTIONS") + metadataRouter.Handle("/system/service-name", http.HandlerFunc(han.SystemdServiceNameHandler)).Methods("GET", "OPTIONS") + metadataRouter.Handle("/systemd/unit-file/", http.HandlerFunc(han.SystemdUnitFileHandler)).Methods("GET", "OPTIONS") + metadataRouter.Handle("/systemd/unit-file", http.HandlerFunc(han.SystemdUnitFileHandler)).Methods("GET", "OPTIONS") // Login authRouter := apiSubRouter.PathPrefix("/auth").Subrouter() diff --git a/runner/metadata.go b/runner/metadata.go index fd2bca61..aa551e80 100644 --- a/runner/metadata.go +++ b/runner/metadata.go @@ -53,11 +53,13 @@ func validateInstanceState(ctx context.Context) (params.Instance, error) { func (r *Runner) GetRunnerServiceName(ctx context.Context) (string, error) { instance, err := validateInstanceState(ctx) if err != nil { + log.Printf("failed to get instance params: %s", err) return "", runnerErrors.ErrUnauthorized } pool, err := r.store.GetPoolByID(r.ctx, instance.PoolID) if err != nil { + log.Printf("failed to get pool: %s", err) return "", errors.Wrap(err, "fetching pool") } @@ -113,7 +115,7 @@ func (r *Runner) GetJITConfigFile(ctx context.Context, file string) ([]byte, err jitConfig := instance.JitConfiguration contents, ok := jitConfig[file] if !ok { - return nil, fmt.Errorf("file not found: %w", runnerErrors.ErrNotFound) + return nil, errors.Wrap(runnerErrors.ErrNotFound, "retrieving file") } decoded, err := base64.StdEncoding.DecodeString(contents) diff --git a/vendor/github.com/cloudbase/garm-provider-common/cloudconfig/templates.go b/vendor/github.com/cloudbase/garm-provider-common/cloudconfig/templates.go index 8ac8f0a7..7c14907a 100644 --- a/vendor/github.com/cloudbase/garm-provider-common/cloudconfig/templates.go +++ b/vendor/github.com/cloudbase/garm-provider-common/cloudconfig/templates.go @@ -52,11 +52,18 @@ function sendStatus() { call "{\"status\": \"installing\", \"message\": \"$MSG\"}" } +{{- if .UseJITConfig }} +function success() { + MSG="$1" + call "{\"status\": \"idle\", \"message\": \"$MSG\"}" +} +{{- else}} function success() { MSG="$1" ID=$2 call "{\"status\": \"idle\", \"message\": \"$MSG\", \"agent_id\": $ID}" } +{{- end}} function fail() { MSG="$1" @@ -104,15 +111,15 @@ function downloadAndExtractRunner() { # chown {{ .RunnerUsername }}:{{ .RunnerGroup }} -R /home/{{ .RunnerUsername }}/actions-runner/ || fail "failed to change owner" } -TEMP_TOKEN="" +{{- if not .UseJITConfig }} GH_RUNNER_GROUP="{{.GitHubRunnerGroup}}" - # $RUNNER_GROUP_OPT will be added to the config.sh line. If it's empty, nothing happens # if it holds a value, it will be part of the command. RUNNER_GROUP_OPT="" if [ ! -z $GH_RUNNER_GROUP ];then RUNNER_GROUP_OPT="--runnergroup=$GH_RUNNER_GROUP" fi +{{- end }} CACHED_RUNNER=$(getCachedToolsPath) if [ -z "$CACHED_RUNNER" ];then @@ -130,28 +137,32 @@ fi sendStatus "configuring runner" {{- if .UseJITConfig }} - function getRunnerFile() { curl --retry 5 --retry-delay 5 \ --retry-connrefused --fail -s \ -X GET -H 'Accept: application/json' \ -H "Authorization: Bearer ${BEARER_TOKEN}" \ - "${METADATA_URL}/$1 -o $2" + "${METADATA_URL}/$1" -o "$2" } +sendStatus "downloading JIT credentials" getRunnerFile "credentials/runner" "/home/{{ .RunnerUsername }}/actions-runner/.runner" || fail "failed to get runner file" getRunnerFile "credentials/credentials" "/home/{{ .RunnerUsername }}/actions-runner/.credentials" || fail "failed to get credentials file" getRunnerFile "credentials/credentials_rsaparams" "/home/{{ .RunnerUsername }}/actions-runner/.credentials_rsaparams" || fail "failed to get credentials_rsaparams file" -getRunnerFile "systemd/service-name" "/home/{{ .RunnerUsername }}/actions-runner/.service" || fail "failed to get service name file" +getRunnerFile "system/service-name" "/home/{{ .RunnerUsername }}/actions-runner/.service" || fail "failed to get service name file" +sed -i 's/$/\.service/' /home/{{ .RunnerUsername }}/actions-runner/.service SVC_NAME=$(cat /home/{{ .RunnerUsername }}/actions-runner/.service) -getRunnerFile "systemd/runner-service?runAsUser={{ .RunnerUsername }}" "$SVC_NAME" || fail "failed to get service file" +sendStatus "generating systemd unit file" +getRunnerFile "systemd/unit-file?runAsUser={{ .RunnerUsername }}" "$SVC_NAME" || fail "failed to get service file" +sudo mv $SVC_NAME /etc/systemd/system/ || fail "failed to move service file" +sendStatus "enabling runner service" cp /home/{{ .RunnerUsername }}/actions-runner/bin/runsvc.sh /home/{{ .RunnerUsername }}/actions-runner/ || fail "failed to copy runsvc.sh" -sudo mv $SVC_NAME /etc/systemd/system/ || fail "failed to move service file" sudo chown {{ .RunnerUsername }}:{{ .RunnerGroup }} -R /home/{{ .RunnerUsername }} || fail "failed to change owner" sudo systemctl daemon-reload || fail "failed to reload systemd" +sudo systemctl enable $SVC_NAME {{- else}} GITHUB_TOKEN=$(curl --retry 5 --retry-delay 5 --retry-connrefused --fail -s -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "${METADATA_URL}/runner-registration-token/") @@ -195,6 +206,8 @@ if [ -e "/sys/fs/selinux" ];then fi {{- if .UseJITConfig }} +sudo systemctl start $SVC_NAME || fail "failed to start service" +success "runner successfully installed" {{- else}} sendStatus "starting service" sudo ./svc.sh start || fail "failed to start service" @@ -205,9 +218,8 @@ if [ $? -ne 0 ];then fail "failed to get agent ID" fi set -e -{{- end}} - success "runner successfully installed" $AGENT_ID +{{- end}} ` var WindowsSetupScriptTemplate = `#ps1_sysnative @@ -427,7 +439,20 @@ function Install-Runner() { } Update-GarmStatus -CallbackURL $CallbackURL -Message "configuring and starting runner" cd $runnerDir + {{- if .UseJITConfig }} + Update-GarmStatus -CallbackURL $CallbackURL -Message "downloading JIT credentials" + wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/credentials/runner -OutFile .runner + wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/credentials/credentials -OutFile .credentials + wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/credentials/credentials_rsaparams -OutFile .credentials_rsaparams + wget -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/system/service-name -OutFile .service + + Update-GarmStatus -CallbackURL $CallbackURL -Message "Creating system service" + $SVC_NAME=(gc -raw "C:\runner\.service") + New-Service -Name "$SVC_NAME" -BinaryPathName "C:\runner\bin\RunnerService.exe" -DisplayName "$SVC_NAME" -Description "GitHub Actions Runner ($SVC_NAME)" -StartupType Automatic + Start-Service "$SVC_NAME" + Update-GarmStatus -Message "runner successfully installed" -CallbackURL $CallbackURL -Status "idle" | Out-Null + {{- else }} $GithubRegistrationToken = Invoke-WebRequest -UseBasicParsing -Headers @{"Accept"="application/json"; "Authorization"="Bearer $Token"} -Uri $MetadataURL/runner-registration-token/ ./config.cmd --unattended --url "{{ .RepoURL }}" --token $GithubRegistrationToken $runnerGroupOpt --name "{{ .RunnerName }}" --labels "{{ .RunnerLabels }}" --ephemeral --runasservice