Skip to content

Commit

Permalink
generic-worker on macOS: run as unprivileged user, start as a service
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonSapin committed Nov 15, 2018
1 parent 889d479 commit 70f5078
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 16 deletions.
25 changes: 22 additions & 3 deletions etc/taskcluster/macos/README.md
@@ -1,7 +1,7 @@
# macOS

Servo’s macOS workers for Taskcluster are configured with
SaltStack in [agentless] mode.
This is the configuration for the `proj-servo/macos` worker type.
These macOS workers are configured with SaltStack in [agentless] mode.

[agentless]: https://docs.saltstack.com/en/getstarted/ssh/index.html

Expand All @@ -15,6 +15,25 @@ cd etc/taskcluster/macos
./salt-ssh '*' state.apply test=True
```

## Servers

Servers are provisioned manually from MacStadium.
The `config/roster` file lists them by DNS name.


## Taskcluster secrets

This SaltStack configuration has a custom module that uses Taskcluster’s
[secrets service](https://tools.taskcluster.net/secrets/).
These secrets include an [authentication token](
You’ll need to authenticate with a Taskcluster client ID
that has scope `secrets:get:project/servo/*`.
This should be the case if you’re a Servo project administrator (the `project-admin:servo` role).


## Worker’s client ID

`project/servo/worker/macos/1`
Workers are configured to authenticate with client ID
[`project/servo/worker/macos/1`](
https://tools.taskcluster.net/auth/clients/project%2Fservo%2Fworker%macos%2F1).
This client has the scopes required to run tasks for this worker type.
2 changes: 1 addition & 1 deletion etc/taskcluster/macos/Saltfile
@@ -1,3 +1,3 @@
salt-ssh:
config_dir: ./config
state_verbose: False
state_verbose: False
5 changes: 4 additions & 1 deletion etc/taskcluster/macos/config/master
@@ -1,4 +1,7 @@
root_dir: .salt
file_roots:
base:
- states
- states
extension_modules: ../modules
ext_pillar:
- taskcluster_secrets:
7 changes: 6 additions & 1 deletion etc/taskcluster/macos/config/roster
@@ -1,2 +1,7 @@
mac1:
host: servo-tc-mac1.servo.org
host: servo-tc-mac1.servo.org

# https://github.com/saltstack/salt/issues/50477
minion_opts:
providers:
user: mac_user
16 changes: 16 additions & 0 deletions etc/taskcluster/macos/modules/pillar/taskcluster_secrets.py
@@ -0,0 +1,16 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "..", "packet.net"))
import tc


def ext_pillar(_minion_id, _pillar, *_args):
tc.check()
data = {}
data.update(tc.secret("project/servo/tc-client/worker/macos/1"))
data.update(tc.secret("project/servo/livelog-secret/1"))
return data
2 changes: 1 addition & 1 deletion etc/taskcluster/macos/salt-ssh
Expand Up @@ -11,4 +11,4 @@ set -o pipefail
cd "$(dirname $0)"
VENV_BIN="../../../python/_virtualenv/bin"
[ -x "${VENV_BIN}/salt-ssh" ] || "${VENV_BIN}/pip" install salt-ssh
"${VENV_BIN}/salt-ssh" "${@}"
"${VENV_BIN}/salt-ssh" "${@}"
72 changes: 64 additions & 8 deletions etc/taskcluster/macos/states/generic-worker.sls
@@ -1,5 +1,6 @@
{% set bin = "/usr/local/bin" %}
{% set keyfile = "/etc/generic-worker/key" %}
{% set user = "worker" %}
{% set home = "/Users/" + user %}

{{ bin }}/generic-worker:
file.managed:
Expand All @@ -16,21 +17,76 @@
- mode: 755
- makedirs: True

/etc/generic-worker/config.json:
{{ user }}:
user.present:
- home: {{ home }}

# `user.present`’s `createhome` is apparently not supported on macOS
{{ home }}:
file.directory:
- user: {{ user }}

{{ home }}/config.json:
file.serialize:
- makedirs: True
- user: {{ user }}
- mode: 600
- show_changes: False
- formatter: json
- dataset:
provisionerId: proj-servo
workerType: macos
workerId: servo-macos-1
clientId: project/servo/worker/macos/1
workerGroup: servo-macos
workerId: mac1
tasksDir: {{ home }}/tasks
publicIP: {{ salt.network.ip_addrs()[0] }}
signingKeyLocation: {{ keyfile }}
signingKeyLocation: {{ home }}/key
clientId: {{ pillar["client_id"] }}
accessToken: {{ pillar["access_token"] }}
livelogSecret: {{ pillar["livelog_secret"] }}

generic-worker new-openpgp-keypair --file {{ keyfile }}:
{{ bin }}/generic-worker new-openpgp-keypair --file {{ home }}/key:
cmd.run:
- creates: {{ keyfile }}
- prepend_path: {{ bin }}
- creates: {{ home }}/key
- runas: worker

/Library/LaunchAgents/net.generic.worker.plist:
file.managed:
- mode: 644
- template: jinja
- contents: >-
<?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>net.generic.worker</string>
<key>ProgramArguments</key>
<array>
<string>{{ bin }}/generic-worker</string>
<string>run</string>
<string>--config</string>
<string>config.json</string>
</array>

<key>KeepAlive</key>
<true/>

<key>WorkingDirectory</key>
<string>{{ home }}</string>

<key>UserName</key>
<string>{{ user }}</string>

<key>StandardOutPath</key>
<string>stdout.log</string>

<key>StandardErrorPath</key>
<string>stderr.log</string>
</dict>
</plist>

net.generic.worker:
service.running:
- enable: True
2 changes: 1 addition & 1 deletion etc/taskcluster/packet.net/README.md
Expand Up @@ -39,7 +39,7 @@ This should be the case if you’re a Servo project administrator (the `project-
## Worker’s client ID

Workers are configured to authenticate with client ID
[project/servo/worker/docker-worker-kvm/1](
[`project/servo/worker/docker-worker-kvm/1`](
https://tools.taskcluster.net/auth/clients/project%2Fservo%2Fworker%2Fdocker-worker-kvm%2F1).
This client has the scopes required to run docker-worker
as well as for tasks that we run on this worker type.

0 comments on commit 70f5078

Please sign in to comment.