Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions .github/workflows/orka-templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,28 @@ jobs:
- name: Set up Packer
uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 #v3.1.0

- name: Create dummy Packer variables file
working-directory: orka/templates
run: |
cat > variables.auto.pkrvars.hcl <<'EOF'
orka_endpoint = "https://mock-orka-endpoint"
xcode_version = "mock-xcode_version"
macos_version = "mock-macos_version"
orka_source_image = "mock-orka_source_image"
ssh_new_password = "mock-ssh_new_password"
ssh_image_password = "mock-ssh_image_password"
ssh_new_public_key = "mock-new_public_key"
EOF
- name: Mock secret files for validate
working-directory: orka/templates
run: |
mkdir -p files/secrets
: > "files/secrets/Apple Developer ID Node.js Foundation.p12"
: > "files/secrets/id_rsa"

- name: Initialize Packer
env:
ORKA_AUTH_TOKEN: 'mock-orka-auth-token'
run: |
for file in $(find . -name '*.pkr.hcl'); do
echo "Initializing $file"
Expand All @@ -32,25 +53,10 @@ jobs:

- name: Validate Packer templates
env:
ORKA_ENDPOINT: 'https://mock-orka-endpoint'
ORKA_AUTH_TOKEN: 'mock-orka-auth-token'
SSH_DEFAULT_USERNAME: 'mock-ssh-default-username'
SSH_DEFAULT_PASSWORD: 'mock-ssh-default-password'
SSH_TEST_PASSWORD: 'mock-ssh-test-password'
SSH_RELEASE_PASSWORD: 'mock-ssh-release-password'
SSH_TEST_PUBLIC_KEY: 'mock-ssh-test-public-key'
SSH_RELEASE_PUBLIC_KEY: 'mock-ssh-release-public-key'
working-directory: orka/templates
run: |
for file in $(find . -name '*.pkr.hcl'); do
echo "Validating $file"
vars="-var orka_endpoint=$ORKA_ENDPOINT -var orka_auth_token=$ORKA_AUTH_TOKEN -var ssh_default_username=$SSH_DEFAULT_USERNAME"

if echo "$file" | grep -q "release"; then
vars="$vars -var ssh_release_password=$SSH_RELEASE_PASSWORD -var ssh_release_public_key=$SSH_RELEASE_PUBLIC_KEY"
elif echo "$file" | grep -q "test"; then
vars="$vars -var ssh_test_password=$SSH_TEST_PASSWORD -var ssh_test_public_key=$SSH_TEST_PUBLIC_KEY -var ssh_default_password=$SSH_DEFAULT_PASSWORD"
fi

packer validate $vars $file || exit 1
done
working-directory: orka/templates
packer validate -var-file=variables.auto.pkrvars.hcl "$file" || exit 1
done
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ ansible/host_vars/*
Pipfile.lock

# Orka secrets files including naming mutations
orka/*/.env*
orka/*/.env*
/orka/templates/files/secrets/*
/orka/templates/*.pkrvars.hcl
8 changes: 8 additions & 0 deletions ansible/inventory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ hosts:
ip: 172.16.9.3
ansible_ssh_common_args: '-o ProxyCommand="ssh -i ~/.ssh/nodejs_build_test -W %h:%p [email protected]"'
ansible_user: root
smartos22-x64-3:
ip: 172.16.9.3
ansible_ssh_common_args: '-o ProxyCommand="ssh -i ~/.ssh/nodejs_build_test -W %h:%p [email protected]"'
ansible_user: root
smartos23-x64-4:
ip: 172.16.9.3
ansible_ssh_common_args: '-o ProxyCommand="ssh -i ~/.ssh/nodejs_build_test -W %h:%p [email protected]"'
Expand All @@ -208,6 +212,10 @@ hosts:
ip: 172.16.9.3
ansible_ssh_common_args: '-o ProxyCommand="ssh -i ~/.ssh/nodejs_build_test -W %h:%p [email protected]"'
ansible_user: root
smartos23-x64-6:
ip: 172.16.9.3
ansible_ssh_common_args: '-o ProxyCommand="ssh -i ~/.ssh/nodejs_build_test -W %h:%p [email protected]"'
ansible_user: root


- osuosl:
Expand Down
198 changes: 48 additions & 150 deletions orka/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Once installed, you can verify the installation by running the following command
packer --version
```

While writing this document, the latest version of Packer is `1.11.2`.
While writing this document, the latest version of Packer is `1.14.2`.

## Install dependencies

Expand All @@ -22,42 +22,65 @@ packer init .

## Access the Orka environment

You need to connect to the Orka VPN. You can find the instructions in the secrets repository.
1. You need to connect to the Orka VPN. You can find the instructions in the secrets repository. @TODO
2. Authenticate the cluster with `orka3 login` -> this will give a url to access to login to macstadium. This login lasts for 3600s.
3. Once logged into macstadium, you can `orka3 user get-token` to get a user token to do other things, like build images.

## Load the environment variables
## Authenticate to ghcr.io

You need to load the environment variables:
Some Macstadium base images are stored at ghcr.io (github's container registry). To allow packer to seamlessly pull
those images, you must provide the orka3 cli with a github personal access token (PAT). See [here]https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-with-a-personal-access-token-classic
```
orka3 regcred add https://ghcr.io --username GITHUB_USERNAME --password PAT_TOKEN
```

1. Get the `.env` file from the secrets repository. You will find the instructions in the repository.
2. Copy the `.env` file to this directory.
3. Run the following command:
```shell
source .env
```
4. Verify that the environment variables are loaded by running the following command:
```shell
echo $ORKA_ENDPOINT
echo $ORKA_AUTH_TOKEN
echo $SSH_DEFAULT_USERNAME
echo $SSH_DEFAULT_PASSWORD
echo $SSH_TEST_PASSWORD
echo $SSH_TEST_PUBLIC_KEY
```
## Load the build variables

You need to configure the variables.auto.pkrvars.hcl file

1. Get the `orka.variables.auto.pkrvars.hcl` file from the secrets repository. There is one in release, and one in test
2. Copy the `orka.variables.auto.pkrvars.hcl` to `variables.auto.pkrvars.hcl` file to this directory.

## Load the file secrets

We need the private key for node-www for the release images, as well as the apple developer certificate for code signing.

1. Copy the `secrets/build/release/staging_id_rsa_private.key` to orka/templates/files/secrets/id_rsa
2. Go to the `build/release` folder in the secrets repo
3. Extract from secrets/build/release and put it in this repo (adjust the orka path in this command): `dotgpg cat Apple\ Developer\ ID\ Node.js\ Foundation.p12.base64 | base64 -D > orka/templates/files/secrets/Apple\ Developer\ ID\ Node.js\ Foundation.p12`

## Download Xcode to the shared vm storage

1. Full Xcode installation

Xcode Command-line tools are not enough to perform a full notarization cycle, full Xcode must be fully installed on the release images.

* Login to https://developer.apple.com using the [email protected] account
* Download Xcode: https://developer.apple.com/download/more/ - find non-beta version, open Developer Tools in browser, Networking tab, start download (then cancel), in Networking tab "Copy as cURL" (available in Chrome & FF)
* On OSX 15 we currently install 16.4
* Manually launch one of the existing VM's (Arm ones are faster)
* `orka3 images list` to see available images
* `orka3 vm deploy --image IMAGE_NAME` to deploy a new image
* NOTE: don't try to connect to an existing image as jenkins may delete it while you're working on it.
* Connect to the VM with ssh, and navigate to /Volumes/orka/Xcode
* use orkaconnect.sh VM_NAME (ie. `orkaconnect.sh vm-h1tcv`)
* Execute the curl command to download Xcode, save it to a file named Xcode_{VERSION}.xip i.e. Xcode_16.4.xip
* This is where packer will look when installing xcode in the image.

## Validate the template

You can validate a specific template by running the following command:
You can validate a specific template by running the following command (replace test with release if doing release images)

```shell
packer validate -var "orka_endpoint=$ORKA_ENDPOINT" -var "orka_auth_token=$ORKA_AUTH_TOKEN" -var "ssh_default_username=$SSH_DEFAULT_USERNAME" -var "ssh_default_password=$SSH_DEFAULT_PASSWORD" -var "ssh_test_password=$SSH_TEST_PASSWORD" -var "ssh_release_password=$SSH_RELEASE_PASSWORD" -var "ssh_release_public_key=$SSH_RELEASE_PUBLIC_KEY" -var "ssh_test_public_key=$SSH_TEST_PUBLIC_KEY" <template_name>
```
ORKA_AUTH_TOKEN=$(orka3 user get-token) packer validate -var-file=variables.auto.pkrvars.hcl macos-test.pkr.hcl
```

## Build the image

You can build a specific template by running the following command:

```shell
packer build -var "orka_endpoint=$ORKA_ENDPOINT" -var "orka_auth_token=$ORKA_AUTH_TOKEN" -var "ssh_default_username=$SSH_DEFAULT_USERNAME" -var "ssh_default_password=$SSH_DEFAULT_PASSWORD" -var "ssh_test_password=$SSH_TEST_PASSWORD" -var "ssh_release_password=$SSH_RELEASE_PASSWORD" -var "ssh_release_public_key=$SSH_RELEASE_PUBLIC_KEY" -var "ssh_test_public_key=$SSH_TEST_PUBLIC_KEY" <template_name>
ORKA_AUTH_TOKEN=$(orka3 user get-token) packer build -var-file=variables.auto.pkrvars.hcl macos-test.pkr.hcl
```

## Continuous Integration
Expand All @@ -70,6 +93,8 @@ We don't plan to build the images in the CI pipeline. The images are built manua

Orka provides a base image that we need to customize to our needs.

Note that orka3 remote-image command is only for interacting with x64 images. arm64 images are at ghcr.io: https://github.com/macstadium/orka-images

1. find the image that you want to extend by running the following command:
```shell
orka3 remote-image list
Expand All @@ -95,130 +120,3 @@ Orka provides a base image that we need to customize to our needs.
orka3 vm delete <vm_name>
```
Note: Don't delete the vm until you have saved the image, check by running the command `orka3 image list`



### Manual Steps for all the images

1. Update Sudoers file:

this requires `NOPASSWD` to be added to the sudoers file to enable elevation

`sudo visudo`
and change:
`%admin ALL = (ALL) ALL`
to
`%admin ALL = (ALL) NOPASSWD:ALL`

2. Allow ssh access

```bash
sudo systemsetup -setremotelogin on
```
3. Install xcode

```bash
sudo xcode-select --install
```

Do a an update using the UI. Check the available updates and install them (click in "more info"). Note that you don't want to update the OS, just the software.

### Manual Steps for the release images

1. Full Xcode installation

Xcode Command-line tools are not enough to perform a full notarization cycle, full Xcode must be installed manually.

As root:

* Download Xcode: https://developer.apple.com/download/more/ - find non-beta version, open Developer Tools in browser, Networking tab, start download (then cancel), in Networking tab "Copy as cURL" (available in Chrome & FF)
* On OSX 13 we currently install 14.13.1.
* Go to downloads folder, decompress the xip file (double click) and delete the xip file
* Move the Xcode.app to /Applications
* Open xcode, accept the license, install the built-in components and close xcode
* `sudo xcode-select --switch /Applications/Xcode.app`
* `sudo xcodebuild -license` - accept license
* `git` - check that git is working (confirming license has been accepted)
* Empty the trash


2. OSX Keychain Profile

Unblok the keychain:

```bash
security unlock-keychain -u /Library/Keychains/System.keychain
```

Create a keychain profile (`NODE_RELEASE_PROFILE`) for the release machine:

```bash
sudo xcrun notarytool store-credentials NODE_RELEASE_PROFILE \
--apple-id XXXX \
--team-id XXXX \
--password XXXX \
--keychain /Library/Keychains/System.keychain
```

Note: `XXXX` values are found in `secrets/build/release/apple.md`

The expected output is:

```
This process stores your credentials securely in the Keychain. You reference these credentials later using a profile name.

Validating your credentials...
Success. Credentials validated.
Credentials saved to Keychain.
To use them, specify `--keychain-profile "NODE_RELEASE_PROFILE" --keychain /Library/Keychains/System.keychain`
```

3. Signing certificates

* Go to the `build/release` folder in the secrets repo.
* Extract from secrets/build/release: `dotgpg cat Apple\ Developer\ ID\ Node.js\ Foundation.p12.base64 | base64 -D > /tmp/Apple\ Developer\ ID\ Node.js\ Foundation.p12`
* Transfer to release machine (scp to /tmp)
* `sudo security import /tmp/Apple\ Developer\ ID\ Node.js\ Foundation.p12 -k /Library/Keychains/System.keychain -T /usr/bin/codesign -T /usr/bin/productsign -P 'XXXX'` (where XXXX is found in secrets/build/release/apple.md) (`security unlock-keychain -u /Library/Keychains/System.keychain` _may_ be required prior to running this command).

4. Validating certificates are in date and valid

1. `security -i unlock-keychain` Enter the password for the machine located in secrets
2. `security find-certificate -c "Developer ID Application" -p > /tmp/app.cert` outputs the PEM format of the cert so we can properly inspect it
3. `security find-certificate -c "Developer ID Installer" -p > /tmp/installer.cert`
4. `openssl x509 -inform PEM -text -in /tmp/app.cert | less`
5. `openssl x509 -inform PEM -text -in /tmp/installer.cert | less`
6. `security find-identity -p codesigning -v`

The steps 4 and 5 will show the details of the certificates allowing to see expiry dates.

Example:

```
Not Before: Jan 22 03:40:05 2020 GMT
Not After : Jan 22 03:40:05 2025 GMT
```

The step 6 will show the list of certificates available on the machine.

Example:

```
1) XXXXXXXXXXX "Developer ID Application: Node.js Foundation (XXXXXXX)"
1 valid identities found
```

5. Change the default password

Use the password found in the secrets repository to change the default password:

```shell
passwd
```

Also change the keychain password:

```shell
security set-keychain-password
```

**:warning: IMPORTANT** We do this step manually at this point and not while using Packer because we added already sensitive information to the image.
12 changes: 12 additions & 0 deletions orka/templates/files/admin_uid_change.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
source /Users/admin/.zprofile
if [ $IMAGE_ARCHITECTURE = x64 ]; then
echo "Re-numerating admin account. This takes a while to chmod"
dscl . -change /Users/admin UniqueID 501 107
time find /Users/admin -uid 501 -exec chown -h 107 {} \;
dscl . create /Groups/ci
dscl . create /Groups/ci gid 107
dscl . create /Groups/ci passwd '*'
dscl . create /Groups/ci GroupMembership admin
echo "Finally done."
fi
20 changes: 20 additions & 0 deletions orka/templates/files/com.mount9p.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.mount9p.plist</string>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/var/log/mount_9p_error.log</string>
<key>StandardOutPath</key>
<string>/var/log/mount_9p.log</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>mkdir -p /Volumes/orka && mount_9p orka</string>
</array>
</dict>
</plist>
4 changes: 4 additions & 0 deletions orka/templates/files/ssh_config.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Host node-www
HostName direct.nodejs.org
User staging
IdentityFile ~/.ssh/id_rsa
Loading