Closed Bug 1715749 Opened 5 years ago Closed 5 years ago

rotate cot keys on gecko-3/b-win2012

Categories

(Infrastructure & Operations :: RelOps: Windows OS, task)

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: grenade, Assigned: grenade)

Details

Attachments

(14 files, 1 obsolete file)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
19.94 KB, text/plain
Details
1.00 MB, text/plain
Details
42.44 KB, text/plain
Details
3.64 KB, text/plain
Details
48.07 KB, patch
Details | Diff | Splinter Review
6.90 KB, text/plain
Details
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

i documented today's rotation at: https://gist.github.com/grenade/7d5c9f567951fbc3c3caf023bd356fa6 and have pasted the same below.

windows cot key rotation

  1. trigger occ ami builds
    git clone https://github.com/mozilla-releng/OpenCloudConfig ./occ
    cd ./occ
    git commit -m "cot key rotation $(date --iso-8601)" -m "deploy: gecko-3-b-win2012" --allow-empty
    
  2. deploy key to image build instance
    1. obtain instance credentials from ec2 userdata
      • option 1: using the console:
        • navigate to the "edit userdata" page of the running instance (see figure 01 below)
        • look for a line containing the administrator password. eg:
          <rootPassword>xxx999!!!</rootPassword>
          
      • option 2: using the aws cli:
        # assuming a `[moz-occ]` profile exists in ~/.aws/credentials
        instance_id=$(aws ec2 describe-instances \
          --profile moz-occ \
          --region us-west-2 \
          --filters Name=key-name,Values=mozilla-taskcluster-worker-gecko-3-b-win2012 Name=instance-state-name,Values=running \
          --query Reservations[].Instances[].InstanceId \
          --output text)
        instance_password=$(aws ec2 describe-instance-attribute \
          --profile moz-occ \
          --region us-west-2 \
          --instance-id ${instance_id} \
          --attribute userData \
          --query UserData.Value \
          --output text | base64 --decode | grep rootPassword | sed -e 's/\s*<[^>]*>//g')
        
    2. connect to the instance over remote desktop (rdp). note that the base windows 2012 image does not support tls 1.2 connections before the instance is bootstrapped completely. this means your rdp client will fail to connect unless it supports tls 1.0
      instance_ip=$(aws ec2 describe-instances \
        --profile moz-occ \
        --region us-west-2 \
        --filters Name=key-name,Values=mozilla-taskcluster-worker-gecko-3-b-win2012 Name=instance-state-name,Values=running \
        --query Reservations[].Instances[].PublicIpAddress \
        --output text)
      xfreerdp \
        /u:Administrator \
        /p:"${instance_password}" \
        /cert-ignore \
        /kbd:809 \
        /w:2400 \
        /h:1200 \
        +clipboard \
        /v:${instance_ip}
      
    3. open a text editor (sublime text is installed and uses sane file encodings by default) and paste the ed25519 cot private key into a new file. no newline is required after the key. save the file to C:\generic-worker\ed25519-private.key
    4. log out from the rdp session or shut down the instance (do not just close the connection. this will leave the occ session hanging and the image build incomplete).
    5. confirm that the occ image build task completes successfully. after the instance shuts down, occ will build an ami from it and distribute that ami to several regions. this can take half an hour. you can get to the image build task by clicking on the ci build associated with your commit and push from step 1 on the occ commits page. the task of interest is named Update gecko-3-b-win2012 AMIs and should complete green
    6. to troubleshoot an incomplete image build instance, examine the instance logs at: https://my.papertrailapp.com/events?q=system%3A${instance_id}
    7. to see ami availability look in the ec2 console:
  3. update ci configuration with the new ami ids obtained from the artifacts page of the task described in 2.v above. the artifact of interest is named ami-latest.json / ami-latest.yml.
Assignee: nobody → rthijssen
Status: NEW → ASSIGNED
Pushed by asasaki@mozilla.com: https://hg.mozilla.org/ci/ci-configuration/rev/9860b1d898ec new 2012 images with rotated cot keys r=aki
Pushed by mtabara@mozilla.com: https://hg.mozilla.org/ci/ci-configuration/rev/1a7003304c47 Backed out changeset 9860b1d898ec r=jcristau

Backing this out as all workers with the new AMI seem to die before claiming any task. The only green ones are the ones with the old AMI, so I'm backing out the patch until we understand what's going on.

the problem was caused by some no longer supported (by generic-worker/worker-runner) worker-pool configuration settings. specifically: capacity and livelogPUTPort (at: https://firefox-ci-tc.services.mozilla.com/worker-manager/gecko-3%2Fb-win2012).

the key rotation change also updates generic worker (and other tc-tools) to 43.2.0 (from 16.5.1), however:

  • 43.2.0 will not claim tasks if capacity and livelogPUTPort are set.
  • 16.5.1 uses those settings.

i had also noticed the failure to take tasks and had already corrected pool configuration to work correctly for 43.2.0 but my changes overlapped the rollback to old amis and 16.5.1.

i am on pto, so i'll just revert my changes as well so that the pool config contains capacity and livelogPUTPort again.

if there is appetite to get the key rotation and tc-tools update back in, whoever does the ci-config merge will also need to modify the resulting worker pool configuration at: https://firefox-ci-tc.services.mozilla.com/worker-manager/gecko-3%2Fb-win2012 so that each launchConfig does mot contain capacity and livelogPUTPort.

additionally to support 43.2.0, the genericWorker.config block for each launchConfig should contain:

  • "disableReboots": false, (not "disableReboots": true, as required by 16.5.1)
  • "shutdownMachineOnIdle": true, (not "shutdownMachineOnIdle": false, as required by 16.5.1)

if someone wants to reintroduce the key rotation and tc-tools update today, i am happy to assist with these changes but i would prefer if this didn't drag on into the coming days.

Bah, seems like we race-conditioned there, too bad. I'm around today to help with re-landing this or we can coordinate on (re)deploying this when you're back from PTO.

i did not revert my config changes but i see that the old amis seem to work fine with the new settings (no capacity and livelogPUTPort settings, "disableReboots": false,, "shutdownMachineOnIdle": true,). all pending tasks have been claimed. so, i will leave settings as they are since they don't seem to affect 16.5.1 and we must have them for 43.2.0.

When can we try this again?

Flags: needinfo?(rthijssen)

We discussed about this in the IT/RelEng mtg earlier today. It seems that Mark may be able to help with this too. Dropping a NI for him, happy to coordinate on this either with me or someone else in RelEng who has better timezone overlap. I think on our end we need to re-land the ci-config patch + make sure the new-AMI based workers can tackle the Windows jobs.

Flags: needinfo?(mcornmesser)

(In reply to Mihai Tabara [:mtabara]⌚️GMT from comment #10)

We discussed about this in the IT/RelEng mtg earlier today. It seems that Mark may be able to help with this too. Dropping a NI for him, happy to coordinate on this either with me or someone else in RelEng who has better timezone overlap. I think on our end we need to re-land the ci-config patch + make sure the new-AMI based workers can tackle the Windows jobs.

Rob's documentation seems pretty straight forward (Thank you Rob!).

Where do I find the COT key, and when do we want to plan the rotation? I would prefer to do this in the (west coast) morning one of the next 2 days.

Flags: needinfo?(mcornmesser) → needinfo?(mtabara)

Rob and Dave House have the generic-worker CoT key. I should be around both mornings, and I think we'll know fairly quickly if the AMI needs to be backed out.

(In reply to Aki Sasaki [:aki] (he/him) (UTC-7) from comment #12)

Rob and Dave House have the generic-worker CoT key. I should be around both mornings, and I think we'll know fairly quickly if the AMI needs to be backed out.

+1 to this.

Also, just in case this is helpful, once we reland the ci-config patch on our end, what I've done is to run:
./taskcluster api workerManager listWorkersForWorkerPool gecko-3/b-win2012 | jq ‘.workers | map(select(.created > “2021-06-11T10:05”))’ to check whether the new workers are correctly being requested and started from AWS. Last time the query showed they were stopped after being requested.

Flags: needinfo?(mtabara)

(In reply to Aki Sasaki [:aki] (he/him) (UTC-7) from comment #12)

Rob and Dave House have the generic-worker CoT key. I should be around both mornings, and I think we'll know fairly quickly if the AMI needs to be backed out.

I will reach out in the morning. I was able to get the COT key from Dave. I am trying to generate the AMIs now, but I have seem have hit an issue . trying to work it through it now.

There are new AMIs generated using the new COT key and I have a patch in to update the AMIs. Let me know when we want to land it.

Pushed by asasaki@mozilla.com: https://hg.mozilla.org/ci/ci-configuration/rev/791348dddf02 2nd try new 2012 images with rotated cot keys r=aki

Backed out the above patch -- new generic-worker instances weren't spinning up.

Rob, I'm wondering if you can pick this back up when you're back.

yup. i found and patched the issue in occ which caused instances to not take tasks (caused by occ having some outdated logic to only expect modern tc tooling on azure or beta workers).

one problem i discovered in testing is that builds which have sccache enabled, always fail (eg: https://firefox-ci-tc.services.mozilla.com/tasks/GXdlI3HkSGqZf_GUPYhtUg/runs/3/logs/public/logs/live.log).

the failure occurs when the build calls sccache.exe --stop-server here, which returns an error code.

i don't really know why these builds used to succeed because to my thinking, failure on error exit code is the expected behaviour but for whatever reason, we get away with this on the existing older images.

Flags: needinfo?(rthijssen)

Your log:
https://firefoxci.taskcluster-artifacts.net/GXdlI3HkSGqZf_GUPYhtUg/3/public/logs/live_backing.log

Esr78 log:
https://firefoxci.taskcluster-artifacts.net/J5DOK2DoSNmlb7mq1W6Utw/0/public/logs/live_backing.log

It looks like the failure is actually in get-secrets:

[task 2021-07-12T13:26:33.787Z] 13:26:33     INFO - [mozharness: 2021-07-12 13:26:33.787000Z] Running get-secrets step.
[task 2021-07-12T13:26:33.787Z] 13:26:33     INFO - Running main action method: get_secrets
[task 2021-07-12T13:26:33.787Z] 13:26:33     INFO - fetching secret project/releng/gecko/build/level-3/gls-gapi.data from API
[task 2021-07-12T13:26:36.184Z] 13:26:36     INFO - [mozharness: 2021-07-12 13:26:36.184000Z] Finished get-secrets step (failed)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL - Uncaught exception: Traceback (most recent call last):
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "z:\build\build\src\testing\mozharness\mozharness\base\script.py", line 2132, in run
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     self.run_action(action)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "z:\build\build\src\testing\mozharness\mozharness\base\script.py", line 2071, in run_action
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     self._possibly_run_method(method_name, error_if_missing=True)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "z:\build\build\src\testing\mozharness\mozharness\base\script.py", line 2026, in _possibly_run_method
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     return getattr(self, method_name)()
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "z:\build\build\src\testing\mozharness\mozharness\mozilla\secrets.py", line 74, in get_secrets
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     secret = self._fetch_secret(secret_name)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "z:\build\build\src\testing\mozharness\mozharness\mozilla\secrets.py", line 23, in _fetch_secret
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     res = urllib.request.urlopen(url)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "c:\mozilla-build\python\lib\urllib2.py", line 154, in urlopen
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     return opener.open(url, data, timeout)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "c:\mozilla-build\python\lib\urllib2.py", line 429, in open
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     response = self._open(req, data)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "c:\mozilla-build\python\lib\urllib2.py", line 447, in _open
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     '_open', req)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "c:\mozilla-build\python\lib\urllib2.py", line 407, in _call_chain
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     result = func(*args)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "c:\mozilla-build\python\lib\urllib2.py", line 1228, in http_open
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     return self.do_open(httplib.HTTPConnection, req)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -   File "c:\mozilla-build\python\lib\urllib2.py", line 1198, in do_open
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL -     raise URLError(err)
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL - URLError: <urlopen error [Errno 11001] getaddrinfo failed>
[task 2021-07-12T13:26:36.185Z] 13:26:36    FATAL - Running post_fatal callback...
[task 2021-07-12T13:26:36.185Z] 13:26:36    ERROR - setting return code to 2 because fatal was called
[task 2021-07-12T13:26:36.185Z] 13:26:36  WARNING - setting return code to 2

We appear to be missing the secrets:get:project/releng/gecko/build/level-3/* scope. How did we create the test task?

Flags: needinfo?(rthijssen)

re comment 21, IIRC there were infra issues with resolving "taskcluster" a couple of days ago, that may be a red herring?

https://hg.mozilla.org/mozilla-central/file/89aa523/client.mk#l55 is prefixed by "-" meaning make is told to ignore any error codes from sccache --stop-server

(In reply to Aki Sasaki [:aki] (he/him) (UTC-7) from comment #21)

We appear to be missing the secrets:get:project/releng/gecko/build/level-3/* scope. How did we create the test task?

it's a real task rather than a test task. i modified the ami id in worker manager manually (for a few availability zones rather than all of them) so that i could see workers claiming tasks in production (after verifying that they do so in testing).

if the word sccache appeared in the log, the build always and consistently failed without exception. many dozens of tasks succeeded but none of the successful tasks contained the word sccache in the build log.

note that the major difference between the ami's containing the new cot key and those containing the old cot key is that new uses taskcluster 43.2.0 whereas old uses 16.5.1. it would not surprise me if scope requirements have changed between these versions.

Flags: needinfo?(rthijssen)

(In reply to Julien Cristau [:jcristau] from comment #22)

re comment 21, IIRC there were infra issues with resolving "taskcluster" a couple of days ago, that may be a red herring?

Ah, that may be the source of the bustage. If the taskcluster proxy is down, then the task wouldn't be able to get scopes to download the needed secrets.

i will retest in european friday morning (to minimise impact) by retriggering green builds that make use of sccache to see if they remain green when run on new images.

so i saw the same issue in testing this morning.
i'm now working on the assumption that either anything requiring the taskcluster proxy is borked on these images or that for some reason we don't get the right scopes associated with these new images.

Looking at the previous task, the task actually has the right scope, but didn't use it during the secrets download. So yes, there may be something wrong with the taskcluster proxy in that AMI.

Pete, do you know what might have changed in generic-worker taskcluster-proxy setup between generic-worker 16.5.1 and now?

A better way to phrase that might be: how is taskcluster-proxy set up in generic-worker on the community cluster? (I assume we're using relatively new versions of the cluster, generic-worker, and proxy there, correct?) Do you have a way to debug the taskcluster-proxy bustage here?

Right now I'm digging through git logs and diffs trying to find out what all has changed. Generic-worker 16.5.1 is nearly 2 years old, so it might be quite a bit.

Flags: needinfo?(pmoore)

Generic-worker 16.5.1 was released on Oct 26, 2019. That's about the taskcluster monorepo v21.0.0 on Oct 17, 2019. We moved to the monorepo in Feb 2020.

We used the taskcluster-proxy repo until April 2020; then we moved to the monorepo.

Comment on attachment 9232514 [details]
monorepo generic-worker directory diff from migration until now

The diff in the monorepo is probably not so useful -- either I get the entire codebase (nothing -> everything diff) or I get too many rename redirects. Maybe the changelog is more useful?

Attachment #9232514 - Attachment is obsolete: true

Potential breaking changes:

  • taskcluster root url needs to be set in the proxy
  • /app/version.json needs to exist for the proxy for dockerflow?

Possibly less suspicious:

  • proxy is now statically linked
  • content-type header
  • proxy no longer follows redirects
  • correctly proxies non-canonical urls

i have identified (and patched) the problem within occ.

occ has a checksum mechanism that was related to tooltool sha512 hashes. some time ago, binaries and files installed on new images were installed via tooltool. as such occ manifests contained a sha512 hash which served as the tooltool index.

a feature was later added to occ to make use of the sha512 hash when determining if a file should be downloaded or if an existing file found on the instance already produced the correct hash.

later still when tooltool was updated to make use of taskcluster scopes, occ dropped support for installing from tooltool, because it was impractical to maintain the secrets required to download from tooltool.

some time after that a change was made to occ to remove sha512 hashes from manifests to prevent failed attempts at downloading from tooltool.

this caused a failure of occ to recognise that C:\Windows\System32\drivers\etc\hosts on the local filesystem, was not the same file it should download from https://raw.githubusercontent.com/mozilla-releng/OpenCloudConfig/master/userdata/Configuration/etc/hosts.

the hosts file that instances should have on them contains the critical dns mapping 127.0.0.1 taskcluster which tells tasks how to resolve taskcluster proxy urls for secrets (by fetching them from the local taskcluster proxy service).

resulting in a failure of tasks to communicate with taskcluster via its local proxy.

i will reattempt tests with patched instances again in (european) morning to limit task failures.

Flags: needinfo?(pmoore)

the above phab patch contains rebuilt images for gecko-[123]/b-win2012. the cot key for l3 has been rotated.

one issue we have seen in the past is that someone or some process updates worker configurations to include configuration that causes modern generic-worker and worker-runner to panic and crash or fail to reboot when required. see comment 6 above, but in particular, newly built images containing tc-tools 43.2 cannot work with worker manager configuration containing a capacity property in worker config blocks. eg:

will cause panics and crashes in modern tc-tools

      "workerConfig": {
        "capacity": 1,
        "genericWorker": {

will work normally in modern tc-tools

      "workerConfig": {
        "genericWorker": {

further, all genericWorker.config configuration blocks must have the following shutdown and reboot configuration values in order for reboots to work correctly:

        "genericWorker": {
          "config": {
            ...
            "disableReboots": false,
            "shutdownMachineOnIdle": true,
            ...
          }
        }

if these configuration values are not set correctly or are set incorrectly, these workers will not claim tasks. i have not been able to identify the source of the incorrect values we often see in worker manager and have resorted to documenting this problem here in the hopes that someone else knows what is messing up these values in worker manager configuration.

Thank you!

ci-admin is applying the "capacity": 1 lines. I applied your phab patch and ran ci-admin diff --environment firefoxci | tee diff and see that if we land your patch, we'll re-add the "capacity": 1 lines, and break in modern tc-tools. I'm wondering if we need to change our configs, or if there's a bug in tc-tools. I can move this line, if I know where to move it to; I'll do some digging.

Per https://bugzilla.mozilla.org/show_bug.cgi?id=1715749#c40, let's
set disableReboots to false, shutdownMachineOnIdle to true,
and stop setting workerConfig.capacity.

Depends on D120811

Pushed by asasaki@mozilla.com: https://hg.mozilla.org/ci/ci-configuration/rev/c1d784b95dd2 tc-tools 43.2 for b-win2012 r=aki https://hg.mozilla.org/ci/ci-configuration/rev/240ebf8d32a9 generic-worker and capacity changes for new ami. r=releng-reviewers,bhearsum

We may want to keep an eye on the other pools, to make sure that removing capacity didn't break them.

thank you aki! that capacity flag had me confused for a while.

i noticed that after the rollout:

  • the value of the workerConfig.genericWorker.config.deploymentId field was set to f37dd7ee1cae. f37dd7ee1cae refers to an occ commit from october 2019.
  • the workerConfig.genericWorker.config.livelogPUTPort field was reinstated

it looks like these fields are set in ci-configuration. i have manually corrected them and am preparing a patch now. there was a growing pending task count because modern generic worker also panics and crashes on detection of the livelogPUTPort field. the pending count should resolve itself now that i have manually corrected configs but will require the ci-config patch that i am preparing shortly, going forward.

the deploymentId field is used by generic worker to determine if it should commit seppuku. between tasks, a worker checks if its own deployment id matches the deployment id of worker manager configuration, if it determines that it does not, it shuts itself down, effectively terminating the spot instance. this feature is exceptionally useful when rolling out upgrades as it provides a mechanism for workers to finish their immediate task before gracefully disappearing from our universe.

it would be useful if ci-admin were able to set the value of deploymentId to the commit hash of the last change for the workerType config in ci-config, but i'll just update the value for now which has the downside that it affects all generic-worker/windows workers instead of just the workers targeted by this patch. - edit: i figured out how to target deploymentId for specific worker types

Pushed by asasaki@mozilla.com: https://hg.mozilla.org/ci/ci-configuration/rev/acfa694d4e42 win: set deploymentId, omit livelogPUTPort r=aki https://hg.mozilla.org/ci/ci-configuration/rev/92b01703c1f0 win: correction to wstServerURL r=aki

Thanks Rob!

it would be useful if ci-admin were able to set the value of deploymentId to the commit hash of the last change for the workerType config in ci-config

hm. the commit hash might be trickier. we could potentially hash up the worker config or similar and populate deploymentId if it's not specified explicitly, or similar.

(In reply to Aki Sasaki [:aki] (he/him) (UTC-7) from comment #49)

hm. the commit hash might be trickier. we could potentially hash up the worker config or similar and populate deploymentId if it's not specified explicitly, or similar.

that might work if we include the ami-id in the hash, since both a gw config change and an ami change would warrant worker deprecation.

Ok. Sorry for the delay, lots of plates in the air.
The above patch will set a deploymentId if we're an AWS generic-worker that doesn't have one set already. Currently this only looks like a sha256 hash, which will change if the workerConfig.genericWorker.config contents or the ImageId change. Does that sound right?

Flags: needinfo?(rthijssen)

yes, lgtm!

Flags: needinfo?(rthijssen)
Attachment #9234586 - Attachment description: WIP: Bug 1715749 - populate deploymentId in AWS generic workers if not set. → Bug 1715749 - populate deploymentId in AWS generic workers if not set. r=#releng
Pushed by asasaki@mozilla.com: https://hg.mozilla.org/ci/ci-configuration/rev/07dac9d8008d populate deploymentId in AWS generic workers if not set. r=releng-reviewers,jmaher

I think we're all done here, thanks Rob!

Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: