Skip to content

Commit cbecacb

Browse files
committed
builddecisionscript: use temporary task credentials to create tasks and trigger hooks
This relies on a change in scriptworker to write temp credentials to disk so we can pick them up and use the task's scopes.
1 parent 591f0c9 commit cbecacb

5 files changed

Lines changed: 52 additions & 6 deletions

File tree

builddecisionscript/src/builddecisionscript/cron/action.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
import taskcluster
88

99
from ..util.http import SESSION
10+
from ..util.taskcluster import get_taskcluster_options
1011
from ..util.trigger_action import render_action
1112

1213
logger = logging.getLogger(__name__)
1314

1415

1516
def find_decision_task(repository, revision):
1617
"""Given repository and revision, find the taskId of the decision task."""
17-
index = taskcluster.Index(taskcluster.optionsFromEnvironment(), session=SESSION)
18+
index = taskcluster.Index(get_taskcluster_options(), session=SESSION)
1819
decision_index = f"{repository.trust_domain}.v2.{repository.project}.revision.{revision}.taskgraph.decision"
1920
logger.info("Looking for index: %s", decision_index)
2021
task_id = index.findTask(decision_index)["taskId"]

builddecisionscript/src/builddecisionscript/decision.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import taskcluster
1313

1414
from .util.http import SESSION
15+
from .util.taskcluster import get_taskcluster_options
1516

1617
logger = logging.getLogger(__name__)
1718

@@ -49,5 +50,5 @@ def display(self):
4950

5051
def submit(self):
5152
logger.info("Task Id: %s", self.task_id)
52-
queue = taskcluster.Queue(taskcluster.optionsFromEnvironment(), session=SESSION)
53+
queue = taskcluster.Queue(get_taskcluster_options(), session=SESSION)
5354
queue.createTask(self.task_id, self.task_payload)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public License,
2+
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
3+
# obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
import json
6+
import os
7+
8+
def get_taskcluster_options():
9+
"""Return options for a Taskcluster client, reading credentials from the
10+
file written by scriptworker and updated on each reclaim."""
11+
creds_path = os.environ["TASKCLUSTER_CREDENTIALS_FILE"]
12+
with open(creds_path) as f:
13+
credentials = json.load(f)
14+
return {
15+
"rootUrl": os.environ["TASKCLUSTER_ROOT_URL"],
16+
"credentials": credentials,
17+
}

builddecisionscript/src/builddecisionscript/util/trigger_action.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from . import scopes
2424
from .http import SESSION
25+
from .taskcluster import get_taskcluster_options
2526

2627
logger = logging.getLogger(__name__)
2728

@@ -62,8 +63,8 @@ def _filter_relevant_actions(actions_json, original_task):
6263

6364

6465
def _check_decision_task_scopes(decision_task_id, hook_group_id, hook_id):
65-
queue = taskcluster.Queue(taskcluster.optionsFromEnvironment(), session=SESSION)
66-
auth = taskcluster.Auth(taskcluster.optionsFromEnvironment(), session=SESSION)
66+
queue = taskcluster.Queue(get_taskcluster_options(), session=SESSION)
67+
auth = taskcluster.Auth(get_taskcluster_options(), session=SESSION)
6768
decision_task = queue.task(decision_task_id)
6869
decision_task_scopes = auth.expandScopes({"scopes": decision_task["scopes"]})["scopes"]
6970
in_tree_scope = f"in-tree:hook-action:{hook_group_id}/{hook_id}"
@@ -77,7 +78,7 @@ def _check_decision_task_scopes(decision_task_id, hook_group_id, hook_id):
7778

7879

7980
def render_action(*, action_name, task_id, decision_task_id, action_input):
80-
queue = taskcluster.Queue(taskcluster.optionsFromEnvironment(), session=SESSION)
81+
queue = taskcluster.Queue(get_taskcluster_options(), session=SESSION)
8182

8283
logger.debug("Fetching actions.json...")
8384
actions_url = queue.buildUrl("getLatestArtifact", decision_task_id, "public/actions.json")
@@ -141,7 +142,7 @@ def display(self):
141142
)
142143

143144
def submit(self):
144-
hooks = taskcluster.Hooks(taskcluster.optionsFromEnvironment(), session=SESSION)
145+
hooks = taskcluster.Hooks(get_taskcluster_options(), session=SESSION)
145146
logger.info("Triggering hook %s/%s", self.hook_group_id, self.hook_id)
146147
result = hooks.triggerHook(self.hook_group_id, self.hook_id, self.hook_payload)
147148
logger.info("Task Id: %s", result["status"]["taskId"])
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# This Source Code Form is subject to the terms of the Mozilla Public
2+
# License, v. 2.0. If a copy of the MPL was not distributed with this
3+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4+
5+
import json
6+
import os
7+
8+
import pytest
9+
10+
from builddecisionscript.util.taskcluster import get_taskcluster_options
11+
12+
13+
def test_get_taskcluster_options(tmp_path, monkeypatch):
14+
credentials = {"clientId": "test-client", "accessToken": "test-token"}
15+
creds_file = tmp_path / "credentials.json"
16+
creds_file.write_text(json.dumps(credentials))
17+
18+
monkeypatch.setenv("TASKCLUSTER_CREDENTIALS_FILE", str(creds_file))
19+
monkeypatch.setenv("TASKCLUSTER_ROOT_URL", "https://tc.example.com")
20+
21+
result = get_taskcluster_options()
22+
23+
assert result == {
24+
"rootUrl": "https://tc.example.com",
25+
"credentials": credentials,
26+
}

0 commit comments

Comments
 (0)