-
Notifications
You must be signed in to change notification settings - Fork 35
feat(ibmcloud): add GitHub Actions runner support for IBM Power and IBM Z #831
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c9a4b05
9af3e13
f68b509
68f31f4
78d423b
753b7ef
9e03696
7829062
a6893f0
60e93b8
ef87753
265345e
de8fc1f
9f02ad6
246c1c0
28e55f7
107ab7f
43b2865
93c91ee
7c2ee65
a1d6416
baad7fb
d75b79c
9761706
a8e6f9c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| name: s390x Runner Smoke Test | ||
| on: workflow_dispatch | ||
| jobs: | ||
| smoke-test: | ||
| runs-on: [self-hosted, S390X] | ||
| steps: | ||
| - name: Check architecture | ||
| run: | | ||
| echo "Architecture: $(uname -m)" | ||
| cat /etc/os-release | grep PRETTY_NAME | ||
| echo "Runner is alive on $(arch)" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| package github | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "io" | ||
| "net/http" | ||
| "strings" | ||
| "time" | ||
| ) | ||
|
|
||
| type registrationTokenResponse struct { | ||
| Token string `json:"token"` | ||
| ExpiresAt string `json:"expires_at"` | ||
| } | ||
|
|
||
| // GenerateRegistrationToken calls the GitHub API to create a short-lived | ||
| // runner registration token for the given repository. | ||
| // pat is a Personal Access Token with repo admin scope. | ||
| // repoURL is in the form "owner/repo" or "https://github.com/owner/repo". | ||
| func GenerateRegistrationToken(pat, repoURL string) (string, error) { | ||
| ownerRepo := repoURL | ||
| ownerRepo = strings.TrimPrefix(ownerRepo, "https://github.com/") | ||
| ownerRepo = strings.TrimPrefix(ownerRepo, "http://github.com/") | ||
| ownerRepo = strings.TrimSuffix(ownerRepo, "/") | ||
|
|
||
| parts := strings.Split(ownerRepo, "/") | ||
| if len(parts) != 2 || parts[0] == "" || parts[1] == "" { | ||
| return "", fmt.Errorf("invalid repo format %q, expected owner/repo", repoURL) | ||
| } | ||
|
|
||
| url := fmt.Sprintf("https://api.github.com/repos/%s/%s/actions/runners/registration-token", parts[0], parts[1]) | ||
|
deekay2310 marked this conversation as resolved.
|
||
|
|
||
| req, err := http.NewRequest(http.MethodPost, url, nil) | ||
| if err != nil { | ||
| return "", fmt.Errorf("creating request: %w", err) | ||
| } | ||
| req.Header.Set("Authorization", "token "+pat) | ||
| req.Header.Set("Accept", "application/vnd.github+json") | ||
| req.Header.Set("X-GitHub-Api-Version", "2022-11-28") | ||
|
|
||
| client := &http.Client{Timeout: 30 * time.Second} | ||
| resp, err := client.Do(req) | ||
| if err != nil { | ||
| return "", fmt.Errorf("calling GitHub API: %w", err) | ||
| } | ||
| defer func() { _ = resp.Body.Close() }() | ||
|
|
||
| body, err := io.ReadAll(resp.Body) | ||
| if err != nil { | ||
| return "", fmt.Errorf("reading response: %w", err) | ||
| } | ||
|
|
||
| if resp.StatusCode != http.StatusCreated { | ||
| return "", fmt.Errorf("GitHub API returned %d: %s (ensure GITHUB_TOKEN has admin scope on the repo)", resp.StatusCode, string(body)) | ||
| } | ||
|
|
||
| var tokenResp registrationTokenResponse | ||
| if err := json.Unmarshal(body, &tokenResp); err != nil { | ||
| return "", fmt.Errorf("parsing response: %w", err) | ||
| } | ||
|
|
||
| if tokenResp.Token == "" { | ||
| return "", fmt.Errorf("empty token in GitHub API response") | ||
| } | ||
|
|
||
| return tokenResp.Token, nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| dnf install -y git-core | ||
|
|
||
| git clone --branch "{{ .RunnerImageRepoVersion }}" --depth=1 "{{ .RunnerImageRepo }}" /opt/action-runner-image-pz | ||
|
|
||
| cd /opt/action-runner-image-pz | ||
| bash -c '. scripts/vm.sh rhel 9 minimal --skip-snap-lxd' || true | ||
|
|
||
| # The upstream configure-system.sh runs chmod -R 777 /usr/share which breaks | ||
| # sshd privilege separation (/usr/share/empty.sshd must be root-owned, not | ||
| # world-writable). Also fix PAM duplicates from configure-limits.sh. | ||
| chmod 755 /usr/share/empty.sshd 2>/dev/null || true | ||
| chown root:root /usr/share/empty.sshd 2>/dev/null || true | ||
| for f in /etc/pam.d/system-auth /etc/pam.d/password-auth; do | ||
| if [ -f "$f" ]; then | ||
| awk '!seen[$0]++' "$f" > "${f}.tmp" && mv "${f}.tmp" "$f" | ||
| fi | ||
| done | ||
| systemctl restart sshd 2>/dev/null || true | ||
|
|
||
| if [ ! -f /opt/runner-cache/config.sh ]; then | ||
| echo "Runner binary not found after build" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| id -u runner &>/dev/null || useradd -m -s /bin/bash runner | ||
| chown -R runner:runner /opt/runner-cache | ||
|
|
||
| sudo -u runner bash -c ' | ||
| cd /opt/runner-cache | ||
|
|
||
| ./config.sh \ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we explore options in config to only install the cli and set it up to join as runner?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once the fork is moved into |
||
| --unattended \ | ||
| --disableupdate \ | ||
| --ephemeral \ | ||
| --name "{{ .Name }}" \ | ||
| --labels "{{ .Labels }}" \ | ||
| --url "{{ .RepoURL }}" \ | ||
| --token "{{ .Token }}" | ||
|
|
||
| nohup ./run.sh > /tmp/gh-runner.log 2>&1 & | ||
| ' | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user doesn't provide
--ghactions-runner-token, the code uses GITHUB_TOKEN from their environment to auto-generate a runner registration token via the GitHub API (GenerateRegistrationToken). This way users don't have to manually create a short-lived registration token before each run.