This is an automated email from the ASF dual-hosted git repository.

shahar1 pushed a commit to branch remove-legacy-runner-code
in repository https://gitbox.apache.org/repos/asf/airflow-ci-infra.git

commit 710fe7f5a184ffe7ebf6f7ae35ca71bacfb740a4
Author: Shahar Epstein <[email protected]>
AuthorDate: Fri Nov 6 17:16:08 2026 +0200

    Remove the code of the retired self-hosted runners
    
    Airflow's jobs run on RunsOn or GitHub-hosted runners, and the AWS 
resources this code built and
    deployed (the scale-out Lambda, the runner AMIs and their SSM parameters) 
were deleted on
    2026-11-03. Keeping it means Dependabot bumps, license checks and reviews 
for code nothing can
    run any more, and it suggests to readers that the 2021 runners still exist.
    
    Generated-by: Claude Opus 5.5
---
 .apache-magpie-overrides/repo-health-config.md     |   3 -
 .github/dependabot.yml                             |   4 +-
 .gitignore                                         |   5 -
 .pre-commit-config.yaml                            |   5 +-
 arm-docker-ami/packer/files/docker-permissions.sh  |  18 -
 .../packer/files/install-dependencies.sh           |  22 -
 arm-docker-ami/packer/linux-ami.pkr.hcl            |  96 ---
 arm-docker-ami/packer/vars/variables.pkrvars.hcl   |  22 -
 cloud-init.yml                                     |  20 -
 .../packer/files/actions-runner-ec2-reporting.sh   |  22 -
 .../packer/files/actions.runner-supervisor.service |  30 -
 .../packer/files/actions.runner.service            |  39 -
 github-runner-ami/packer/files/cleanup.sh          |  30 -
 .../packer/files/cloudwatch-metrics-github-runners |  18 -
 github-runner-ami/packer/files/configure_kernel.sh |  22 -
 .../packer/files/create-hostedtools-cache.sh       |  21 -
 github-runner-ami/packer/files/docker.sh           |  47 --
 github-runner-ami/packer/files/git.sh              |  88 ---
 .../packer/files/install-dependencies.sh           |  50 --
 github-runner-ami/packer/files/install-files.sh    |  29 -
 .../packer/files/install-github-cli.sh             |  28 -
 github-runner-ami/packer/files/install-nodejs.sh   |  25 -
 .../packer/files/install-subversion.sh             |  22 -
 github-runner-ami/packer/files/mounts_setup.sh     |  19 -
 github-runner-ami/packer/files/regctl.sh           |  29 -
 github-runner-ami/packer/files/rules.v4            |  28 -
 github-runner-ami/packer/files/runner              |  18 -
 .../packer/files/runner-cleanup-workdir.sh         |  44 --
 .../packer/files/runner-supervisor.py              | 853 ---------------------
 github-runner-ami/packer/files/runner_bootstrap.sh |  45 --
 .../packer/files/source-list-additions.sh          |  23 -
 .../packer/files/stop-runner-if-no-job.sh          |  46 --
 github-runner-ami/packer/files/timber.key          |  36 -
 github-runner-ami/packer/files/vector.toml         | 105 ---
 github-runner-ami/packer/ubuntu2004.pkr.hcl        | 166 ----
 .../packer/vars/variables.pkrvars.hcl              |  24 -
 lambdas/scale_out_runner/.chalice/config.json      |  20 -
 .../scale_out_runner/.chalice/deployed/prod.json   |  28 -
 lambdas/scale_out_runner/.chalice/prod_iam.json    |  33 -
 lambdas/scale_out_runner/.gitignore                |  20 -
 lambdas/scale_out_runner/app.py                    | 210 -----
 lambdas/scale_out_runner/requirements.txt          |  19 -
 requirements-test.txt                              |   1 -
 requirements.txt                                   |  27 -
 scripts/list_committers                            | 102 ---
 scripts/store-agent-creds.py                       | 206 -----
 tests/conftest.py                                  |  16 -
 tests/lambdas/scale_out_runner/conftest.py         |  35 -
 tests/lambdas/scale_out_runner/test_app.py         |  61 --
 49 files changed, 3 insertions(+), 2877 deletions(-)

diff --git a/.apache-magpie-overrides/repo-health-config.md 
b/.apache-magpie-overrides/repo-health-config.md
index 9b97730..7a2775c 100644
--- a/.apache-magpie-overrides/repo-health-config.md
+++ b/.apache-magpie-overrides/repo-health-config.md
@@ -117,9 +117,6 @@ repo_health:
     # Source paths to audit for license headers (relative to upstream repo 
root).
     source_paths:
       - ".github/"
-      - "arm-docker-ami/"
-      - "github-runner-ami/"
-      - "lambdas/"
       - "scripts/"
       - "terraform/"
       - "tests/"
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index e0bd437..fa91eb6 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -40,9 +40,7 @@ updates:
         patterns: ["*"]
 
   - package-ecosystem: pip
-    directories:
-      - /
-      - /lambdas/scale_out_runner
+    directory: /
     schedule:
       interval: weekly
     cooldown:
diff --git a/.gitignore b/.gitignore
index 994f4d7..17d19fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,12 +57,7 @@ override.tf.json
 .idea
 *.iml
 
-# Session manager binaries
-session-manager-plugin.*
-
 # End of https://www.toptal.com/developers/gitignore/api/terraform
-github-runner-ami/packer/session-manager-plugin.deb
-github-runner-ami/packer/session-manager-plugin.rpm
 
 # Apache Magpie personal layer
 /.apache-magpie-local/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3020db8..e2e5778 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -31,9 +31,8 @@ repos:
       - id: forbid-tabs
       - id: insert-license
         name: Add license
-        # LICENSE is the license itself, lock files are generated, and 
cloud-init.yml must start with
-        # #cloud-config.
-        exclude: 
^\.github/.*$|^license-templates/|\.json$|\.md$|\.rst$|^LICENSE$|\.terraform\.lock\.hcl$|^cloud-init\.yml$
+        # LICENSE is the license itself and lock files are generated.
+        exclude: 
^\.github/.*$|^license-templates/|\.json$|\.md$|\.rst$|^LICENSE$|\.terraform\.lock\.hcl$
         args:
           - --comment-style
           - "|#|"
diff --git a/arm-docker-ami/packer/files/docker-permissions.sh 
b/arm-docker-ami/packer/files/docker-permissions.sh
deleted file mode 100644
index cf1fb13..0000000
--- a/arm-docker-ami/packer/files/docker-permissions.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-sudo usermod -a -G docker ec2-user
diff --git a/arm-docker-ami/packer/files/install-dependencies.sh 
b/arm-docker-ami/packer/files/install-dependencies.sh
deleted file mode 100644
index 3486545..0000000
--- a/arm-docker-ami/packer/files/install-dependencies.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-yum update
-yum install docker --assumeyes
diff --git a/arm-docker-ami/packer/linux-ami.pkr.hcl 
b/arm-docker-ami/packer/linux-ami.pkr.hcl
deleted file mode 100644
index 64c6ecb..0000000
--- a/arm-docker-ami/packer/linux-ami.pkr.hcl
+++ /dev/null
@@ -1,96 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-variable "vpc_id" {
-  type = string
-}
-variable "ami_name" {
-  type = string
-}
-variable "aws_regions" {
-  type = list(string)
-}
-variable "packer_role_arn" {
-  type = string
-}
-variable "session_manager_instance_profile_name" {
-  type = string
-}
-
-source "amazon-ebs" "docker-runner" {
-  region = var.aws_regions[0]
-  ami_name = "${var.ami_name}-v2"
-  ami_regions = var.aws_regions
-  tag {
-    key   = "Name"
-    value = "arm-docker-ami"
-  }
-  snapshot_tag {
-    key   = "Name"
-    value = "arm-docker-ami-root"
-  }
-  encrypt_boot = false
-  instance_type = "m6g.large"
-  communicator = "ssh"
-  ssh_username = "ec2-user"
-  ssh_interface = "session_manager"
-  iam_instance_profile = var.session_manager_instance_profile_name
-  subnet_filter {
-    #  Just pick a random subnet in the VPC -- we only have the three defaults 
so this is fine!
-    random = true
-  }
-  vpc_id = var.vpc_id
-  source_ami_filter {
-    filters = {
-       virtualization-type = "hvm"
-       architecture=  "arm64",
-       name = "amzn2-ami-kernel-5.10-hvm-*"
-       root-device-type = "ebs"
-    }
-    owners = ["amazon"]
-    most_recent = true
-  }
-}
-
-build {
-  sources = [
-    "source.amazon-ebs.docker-runner"
-  ]
-
-  provisioner "shell" {
-      inline = [
-        "echo Connected via SSM at '${build.User}@${build.Host}:${build.Port}'"
-      ]
-  }
-
-  # Since we connect as a non-root user, we have to "stage" the files to a 
writable folder, which we then move
-  # in to place with the approriate permissions via install-files.sh 
provisioner step
-  provisioner "shell" {
-    inline = [
-      "mkdir -p /tmp/etc-systemd-system /tmp/usr-local-sbin /tmp/usr-local-bin 
/tmp/etc-sudoers.d /tmp/etc-iptables /tmp/etc-cron.d"
-    ]
-  }
-  provisioner "shell" {
-    scripts = [
-      "./files/install-dependencies.sh",
-      "./files/docker-permissions.sh",
-    ]
-    execute_command = "chmod +x '{{ .Path }}'; sudo sh -c '{{ .Vars }} {{ 
.Path }}'"
-    environment_vars = [
-    ]
-  }
-}
diff --git a/arm-docker-ami/packer/vars/variables.pkrvars.hcl 
b/arm-docker-ami/packer/vars/variables.pkrvars.hcl
deleted file mode 100644
index f01a76e..0000000
--- a/arm-docker-ami/packer/vars/variables.pkrvars.hcl
+++ /dev/null
@@ -1,22 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-vpc_id = "vpc-d73487bd"
-ami_name = "arm-docker-ami"
-aws_regions = ["eu-central-1", "us-east-2"]
-packer_role_arn = "arn:aws:iam::827901512104:role/packer-role"
-session_manager_instance_profile_name = "packer_ssm_instance_profile"
diff --git a/cloud-init.yml b/cloud-init.yml
deleted file mode 100644
index 459708d..0000000
--- a/cloud-init.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-#cloud-config
-# 2022-01-21 19:31 BMT
-
-mounts:
-  - [tmpfs, /var/lib/docker, tmpfs, "defaults,noatime,size=85%"]
-  - [tmpfs, /home/runner/actions-runner/_work, tmpfs, "defaults,noatime"]
-
-
-runcmd:
-  -
-    - bash
-    - -c
-    - |
-      set -eu -o pipefail
-      echo "AWS_DEFAULT_REGION=$(cloud-init query region)" >> /etc/environment
-      echo "AWS_DEFAULT_REGION=$(cloud-init query region)" >> 
/etc/default/vector
-      #aws logs create-log-stream --log-group-name GitHubRunners 
--log-stream-name $(hostname) || true
-      #systemctl enable --now vector
-      systemctl enable --now actions.runner
-      sysctl -w net.netfilter.nf_conntrack_tcp_be_liberal=1
diff --git a/github-runner-ami/packer/files/actions-runner-ec2-reporting.sh 
b/github-runner-ami/packer/files/actions-runner-ec2-reporting.sh
deleted file mode 100644
index d79b0c9..0000000
--- a/github-runner-ami/packer/files/actions-runner-ec2-reporting.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-if pgrep -c Runner.Worker >/dev/null; then
-    # Only report metric when we're doing something -- no point paying to 
submit zeros
-    aws cloudwatch put-metric-data --metric-name jobs-running --value "$(pgrep 
-c Runner.Worker)" --namespace github.actions
-fi
diff --git a/github-runner-ami/packer/files/actions.runner-supervisor.service 
b/github-runner-ami/packer/files/actions.runner-supervisor.service
deleted file mode 100644
index baffc90..0000000
--- a/github-runner-ami/packer/files/actions.runner-supervisor.service
+++ /dev/null
@@ -1,30 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-[Unit]
-Description=Fetch credentials and supervise GitHub Actions Runner
-After=network.target
-Before=actions.runner.service
-
-[Service]
-Type=notify
-ExecStart=/opt/runner-supervisor/bin/python 
/opt/runner-supervisor/bin/runner-supervisor
-# We need to run as root to have the ability to open the netlink connector 
socket
-User=root
-WorkingDirectory=/home/runner/actions-runner
-Restart=always
-EnvironmentFile=/etc/environment
diff --git a/github-runner-ami/packer/files/actions.runner.service 
b/github-runner-ami/packer/files/actions.runner.service
deleted file mode 100644
index 67a1d44..0000000
--- a/github-runner-ami/packer/files/actions.runner.service
+++ /dev/null
@@ -1,39 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-[Unit]
-Description=GitHub Actions Runner
-After=network.target actions.runner-supervisor.service
-Requires=actions.runner-supervisor.service
-BindsTo=actions.runner-supervisor.service
-
-[Service]
-ExecStartPre=!/usr/local/sbin/runner-cleanup-workdir.sh
-ExecStart=/home/runner/actions-runner/run.sh --once --startuptype service 
--labels $RUNNER_LABELS
-ExecStop=/usr/local/bin/stop-runner-if-no-job.sh $MAINPID
-EnvironmentFile=/etc/environment
-Environment=GITHUB_ACTIONS_RUNNER_CHANNEL_TIMEOUT=300
-Environment=RUNNER_LABELS=airflow-runner,vm-runner
-User=runner
-WorkingDirectory=/home/runner/actions-runner
-KillMode=mixed
-KillSignal=SIGTERM
-TimeoutStopSec=30min
-Restart=on-success
-
-[Install]
-WantedBy=multi-user.target
diff --git a/github-runner-ami/packer/files/cleanup.sh 
b/github-runner-ami/packer/files/cleanup.sh
deleted file mode 100644
index 4b6443a..0000000
--- a/github-runner-ami/packer/files/cleanup.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -ex
-
-rm ~ubuntu/.ssh/authorized_keys
-
-journalctl --rotate
-sleep 2
-journalctl --vacuum-time=1s
-
-rm -rf /var/lib/cloud/ /var/log/cloud-init*.log
-
-rm -rf /var/cache/* /var/lib/apt/*
diff --git a/github-runner-ami/packer/files/cloudwatch-metrics-github-runners 
b/github-runner-ami/packer/files/cloudwatch-metrics-github-runners
deleted file mode 100644
index 0380246..0000000
--- a/github-runner-ami/packer/files/cloudwatch-metrics-github-runners
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-*/1 * * * * nobody /usr/local/sbin/actions-runner-ec2-reporting.sh
diff --git a/github-runner-ami/packer/files/configure_kernel.sh 
b/github-runner-ami/packer/files/configure_kernel.sh
deleted file mode 100644
index 5fb2855..0000000
--- a/github-runner-ami/packer/files/configure_kernel.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# Needed to run multiple kind instances
-cat >>/etc/sysctl.conf <<EOF
-fs.inotify.max_user_watches = 524288
-fs.inotify.max_user_instances = 512
-net.netfilter.nf_conntrack_tcp_be_liberal = 1
-EOF
diff --git a/github-runner-ami/packer/files/create-hostedtools-cache.sh 
b/github-runner-ami/packer/files/create-hostedtools-cache.sh
deleted file mode 100644
index 89a9f74..0000000
--- a/github-runner-ami/packer/files/create-hostedtools-cache.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -eu -o pipefail
-echo "Creating hosted tools cache:"
-install --owner runner --directory /opt/hostedtoolcache
diff --git a/github-runner-ami/packer/files/docker.sh 
b/github-runner-ami/packer/files/docker.sh
deleted file mode 100644
index 73e4be9..0000000
--- a/github-runner-ami/packer/files/docker.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -exu -o pipefail
-
-for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; 
do sudo apt-get remove $pkg --assume-yes || true; done
-
-sudo apt-get update
-sudo apt-get install ca-certificates curl gnupg
-
-sudo install -m 0755 -d /etc/apt/keyrings
-curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor 
-o /etc/apt/keyrings/docker.gpg
-sudo chmod a+r /etc/apt/keyrings/docker.gpg
-
-echo \
-  "deb [arch="$(dpkg --print-architecture)" 
signed-by=/etc/apt/keyrings/docker.gpg] 
https://download.docker.com/linux/ubuntu \
-  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
-  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
-
-sudo apt-get update
-
-# Same version as MIN_VERSIONS in Breeze
-DOCKER_VERSION_STRING="5:24.0.7-1~ubuntu.20.04~focal"
-DOCKER_COMPOSE_VERSION_STRING="2.20.2-1~ubuntu.20.04~focal"
-DOCKER_BUILDX_VERSION_STRING="0.11.2-1~ubuntu.20.04~focal"
-sudo apt-get install \
-  "docker-ce=${DOCKER_VERSION_STRING}" \
-  "docker-ce-cli=${DOCKER_VERSION_STRING}" \
-  containerd.io \
-  "docker-buildx-plugin=${DOCKER_BUILDX_VERSION_STRING}" \
-  "docker-compose-plugin=${DOCKER_COMPOSE_VERSION_STRING}" --assume-yes 
--allow-downgrades
diff --git a/github-runner-ami/packer/files/git.sh 
b/github-runner-ami/packer/files/git.sh
deleted file mode 100644
index fc79f0a..0000000
--- a/github-runner-ami/packer/files/git.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-GIT_REPO="ppa:git-core/ppa"
-GIT_LFS_REPO="https://packagecloud.io/install/repositories/github/git-lfs";
-
-function download_with_retries() {
-# Due to restrictions of bash functions, positional arguments are used here.
-# In case if you using latest argument NAME, you should also set value to all 
previous parameters.
-# Example: download_with_retries $ANDROID_SDK_URL "." "android_sdk.zip"
-    local URL="$1"
-    local DEST="${2:-.}"
-    local NAME="${3:-${URL##*/}}"
-    local COMPRESSED="$4"
-
-    if [[ $COMPRESSED == "compressed" ]]; then
-        local COMMAND="curl $URL -4 -sL --compressed -o '$DEST/$NAME' -w 
'%{http_code}'"
-    else
-        local COMMAND="curl $URL -4 -sL -o '$DEST/$NAME' -w '%{http_code}'"
-    fi
-
-    echo "Downloading '$URL' to '${DEST}/${NAME}'..."
-    retries=20
-    interval=30
-    while [ $retries -gt 0 ]; do
-        ((retries--))
-        # Temporary disable exit on error to retry on non-zero exit code
-        set +e
-        http_code=$(eval $COMMAND)
-        exit_code=$?
-        if [ $http_code -eq 200 ] && [ $exit_code -eq 0 ]; then
-            echo "Download completed"
-            return 0
-        else
-            echo "Error — Either HTTP response code for '$URL' is wrong - 
'$http_code' or exit code is not 0 - '$exit_code'. Waiting $interval seconds 
before the next attempt, $retries attempts left"
-            sleep $interval
-        fi
-        # Enable exit on error back
-        set -e
-    done
-
-    echo "Could not download $URL"
-    return 1
-}
-
-## Install git
-add-apt-repository $GIT_REPO -y
-apt-get update
-apt-get install --upgrade git -y
-git --version
-
-# Install git-lfs
-curl -s $GIT_LFS_REPO/script.deb.sh | bash
-apt-get install -y git-lfs=2.13.3
-
-# Install git-ftp
-apt-get install git-ftp -y
-
-# Remove source repo's
-add-apt-repository --remove $GIT_REPO
-rm /etc/apt/sources.list.d/github_git-lfs.list
-
-#Install hub
-tmp_hub="/tmp/hub"
-mkdir -p "$tmp_hub"
-url=$(curl --location -s 
https://api.github.com/repos/github/hub/releases/latest | jq -r 
'.assets[].browser_download_url | select(contains("hub-linux-amd64"))')
-download_with_retries "$url" "$tmp_hub"
-tar xzf "$tmp_hub"/hub-linux-amd64-*.tgz --strip-components 1 -C "$tmp_hub"
-mv "$tmp_hub"/bin/hub /usr/local/bin
-
-# Add well-known SSH host keys to known_hosts
-ssh-keyscan -t rsa github.com >> /etc/ssh/ssh_known_hosts
-ssh-keyscan -t rsa ssh.dev.azure.com >> /etc/ssh/ssh_known_hosts
diff --git a/github-runner-ami/packer/files/install-dependencies.sh 
b/github-runner-ami/packer/files/install-dependencies.sh
deleted file mode 100644
index 9d24d99..0000000
--- a/github-runner-ami/packer/files/install-dependencies.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-debconf-set-selections <<EOF
-iptables-persistent iptables-persistent/autosave_done boolean true
-iptables-persistent iptables-persistent/autosave_v4 boolean false
-iptables-persistent iptables-persistent/autosave_v6 boolean false
-EOF
-
-export DEBIAN_FRONTEND=noninteractive
-
-apt-get update
-apt-get install -yq --no-install-recommends -o 
Dpkg::Options::="--force-confold" \
-            awscli \
-            build-essential \
-            autossh \
-            git \
-            haveged \
-            iptables-persistent \
-            jq \
-            parallel \
-            python3-dev \
-            python3-venv \
-            python3-wheel \
-            yarn \
-            vector='0.15.*'
-
-
-# Re-enabled in clout-init once AWS_DEFAULT_REGION env var is set
-systemctl disable vector
-
-# validate the vector config file we have already installed
-sudo -u vector vector validate --no-environment
diff --git a/github-runner-ami/packer/files/install-files.sh 
b/github-runner-ami/packer/files/install-files.sh
deleted file mode 100644
index 9c726f6..0000000
--- a/github-runner-ami/packer/files/install-files.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -eu -o pipefail
-
-mkdir /etc/iptables/ /etc/vector
-
-install --owner root --mode=0644 --target-directory "/etc/systemd/system/" 
"/tmp/etc-systemd-system/"*
-install --owner root --mode=0755 --target-directory "/usr/local/sbin" 
"/tmp/usr-local-sbin/"*
-install --owner root --mode=0755 --target-directory "/usr/local/bin" 
"/tmp/usr-local-bin/"*
-install --owner root --mode=0644 --target-directory "/etc/iptables" 
"/tmp/etc-iptables/"*
-install --owner root --mode=0644 --target-directory "/etc/cron.d" 
"/tmp/etc-cron.d/"*
-install --owner root --mode=0644 --target-directory "/etc/sudoers.d" 
"/tmp/etc-sudoers.d/"*
-install --owner root --mode=0644 --target-directory "/etc/vector/" 
"/tmp/etc-vector/"*
diff --git a/github-runner-ami/packer/files/install-github-cli.sh 
b/github-runner-ami/packer/files/install-github-cli.sh
deleted file mode 100644
index a09714e..0000000
--- a/github-runner-ami/packer/files/install-github-cli.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash -e
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -uo pipefail
-
-# 
https://github.com/actions/virtual-environments/blob/f2fdcef0e020770b1b6cc58bda3b4a01f0286f5e/images/linux/scripts/installers/github-cli.sh
-url=$(curl -s https://api.github.com/repos/cli/cli/releases/latest | jq -r 
'.assets[].browser_download_url|select(contains("linux") and contains("amd64") 
and contains(".deb"))')
-
-cd /tmp
-curl -fsL --remote-name "$url"
-apt install /tmp/gh_*_linux_amd64.deb
-rm /tmp/gh_*_linux_amd64.deb
diff --git a/github-runner-ami/packer/files/install-nodejs.sh 
b/github-runner-ami/packer/files/install-nodejs.sh
deleted file mode 100644
index d2a4eed..0000000
--- a/github-runner-ami/packer/files/install-nodejs.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash -e
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# 
https://github.com/actions/virtual-environments/blob/525f79f479cca77aef4e0a680548b65534c64a18/images/linux/scripts/installers/nodejs.sh
-curl -sL 
https://raw.githubusercontent.com/mklement0/n-install/stable/bin/n-install | 
bash -s -- -ny -
-~/n/bin/n lts
-npm install -g grunt gulp n parcel-bundler typescript newman
-npm install -g --save-dev webpack webpack-cli
-npm install -g npm
-rm -rf ~/n
diff --git a/github-runner-ami/packer/files/install-subversion.sh 
b/github-runner-ami/packer/files/install-subversion.sh
deleted file mode 100644
index 9a974f3..0000000
--- a/github-runner-ami/packer/files/install-subversion.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash -e
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -uo pipefail
-
-apt install subversion -y
diff --git a/github-runner-ami/packer/files/mounts_setup.sh 
b/github-runner-ami/packer/files/mounts_setup.sh
deleted file mode 100644
index 03f449b..0000000
--- a/github-runner-ami/packer/files/mounts_setup.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-sudo mount -t tmpfs -o size=85% tmpfs /var/lib/docker
-sudo mount -t tmpfs -o tmpfs /home/runner/actions-runner/_work
diff --git a/github-runner-ami/packer/files/regctl.sh 
b/github-runner-ami/packer/files/regctl.sh
deleted file mode 100644
index 1a8e712..0000000
--- a/github-runner-ami/packer/files/regctl.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-set -exu -o pipefail
-
-architecture=$(uname -m)
-if [[ ${architecture} == "x86_64" ]] ; then
-    # Well. Docker compose got it right, but regctl didn't ¯\_(ツ)_/¯
-    architecture="amd64"
-fi
-# Hard-code regctl version
-regctl_version="v0.4.3"
-regctl_binary="regctl-$(uname -s)-${architecture}"
-curl -L 
"https://github.com/regclient/regclient/releases/download/${regctl_version}/${regctl_binary}";
 -o "/usr/local/bin/regctl"
-chmod a+x "/usr/local/bin/regctl"
diff --git a/github-runner-ami/packer/files/rules.v4 
b/github-runner-ami/packer/files/rules.v4
deleted file mode 100644
index 6d19ac1..0000000
--- a/github-runner-ami/packer/files/rules.v4
+++ /dev/null
@@ -1,28 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# Generated by iptables-save v1.8.4 on Thu Jan 14 13:59:27 2021
-*filter
-:INPUT ACCEPT [833:75929]
-:FORWARD DROP [0:0]
-:OUTPUT ACCEPT [794:143141]
-:DOCKER-USER - [0:0]
--A FORWARD -j DOCKER-USER
-# Dis-allow any docker container to access the metadata service
--A DOCKER-USER -d 169.254.169.254/32 -j REJECT --reject-with 
icmp-port-unreachable
--A DOCKER-USER -j RETURN
-COMMIT
diff --git a/github-runner-ami/packer/files/runner 
b/github-runner-ami/packer/files/runner
deleted file mode 100644
index 1d79760..0000000
--- a/github-runner-ami/packer/files/runner
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-runner ALL=(ALL) NOPASSWD:/usr/sbin/swapoff -a, /usr/bin/rm -f /swapfile, 
/usr/bin/apt clean
diff --git a/github-runner-ami/packer/files/runner-cleanup-workdir.sh 
b/github-runner-ami/packer/files/runner-cleanup-workdir.sh
deleted file mode 100644
index 23141d7..0000000
--- a/github-runner-ami/packer/files/runner-cleanup-workdir.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -eu -o pipefail
-echo "Left-over containers:"
-docker ps -a
-docker ps -qa | xargs --verbose --no-run-if-empty docker rm -fv
-
-echo "Log in to a paid docker user to get unlimited docker pulls"
-aws ssm get-parameter --with-decryption --name 
/runners/apache/airflow/dockerPassword | \
-    jq .Parameter.Value -r | \
-    sudo -u runner docker login --username airflowcirunners --password-stdin
-
-if [[ -d ~runner/actions-runner/_work/airflow/airflow ]]; then
-    cd ~runner/actions-runner/_work/airflow/airflow
-
-    chown --changes -R runner: .
-    if [[ -e .git ]]; then
-        sudo -u runner bash -c "
-        git reset --hard && \
-        git submodule deinit --all -f && \
-        git submodule foreach git clean -fxd && \
-        git clean -fxd \
-        "
-    fi
-fi
-
-# Remove left over mssql data dirs
-find . -maxdepth 1 -name 'tmp-mssql-volume-*' -type d -printf 'Deleting %f\n' 
-exec sudo rm -r {} +
diff --git a/github-runner-ami/packer/files/runner-supervisor.py 
b/github-runner-ami/packer/files/runner-supervisor.py
deleted file mode 100755
index fe6e8e5..0000000
--- a/github-runner-ami/packer/files/runner-supervisor.py
+++ /dev/null
@@ -1,853 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-"""
-Obtain credentials for Actions runner and co-operate with auto scaling group
-
-The purpose of this script is to enable the self-hosted runners to operate in
-an AutoScaling environment (without needing admin permissions on the GitHub
-repo to create and delete runners.)
-
-The order of operations is:
-
-1. Obtain credentials
-
-   We have pre-created a number of credentials and stored them in Amazon KMS.
-   This script makes use of dynamodb to obtain an exclusive lock on a set of
-   credentials.
-
-   We need the "locking" as if you use credentials that are already
-   in use the new runner process will wait (but never error) until they are not
-   in use.
-
-2. Complete the ASG lifecycle action so the instance is marked as InService
-
-   This might not be strictly necessary, we don't want the instance to be "in
-   service" until the runner has started.
-
-3. Emit metric saying whether instance is running a job or not
-
-   This is used to drive the scale-in CloudWatch alarm
-
-4. Monitor for the runner starting jobs, and protecting the instance from 
Scale-In when it is
-
-   Since we are running in an autoscaling group we can't dictate which instance
-   AWS choses to terminate, so we instead have to set scale-in protection when 
a job is running.
-
-   The way we watch for jobs being executed is using the Netlink Process
-   Connector, which is a datagram socket that a (root) process can open to the
-   kernel, to receive push events for whenever a process starts or stops.
-
-   There are more events than that send, and to limit it to the only ones we
-   care about we use a BPF filter to drop everything else.
-
-   Since it is a datagram socket it is possible we might miss a notification, 
so
-   we also periodically check if the process is still alive
-
-5. Watch for ASG instance state changing to Terminating:Wait
-
-   When the ASG wants to terminate the instance, we have it configured to put
-   the instance in to a "requested" state -- this is to avoid a race condition
-   where the instance _isn't_ running a job (so isn't protected from scale in),
-   gets set to Terminating, but before AWS shuts down the machine the runner
-   process picks up and starts a Job, which leads to the job failing with "The
-   self-hosted runner: Airflow Runner $N lost communication with the server".
-
-   When we notice being in this state, we _gracefully_ shut down the runner
-   (letting it complete any job it might have), stop it from restarting, and
-   then allow the termination lifecycle to continue
-
-"""
-
-import ctypes
-import datetime
-import enum
-import errno
-import json
-import logging
-import os
-import random
-import selectors
-import shutil
-import signal
-import socket
-from subprocess import check_call
-from typing import Callable, List, Tuple, Union
-
-import boto3
-import click
-import psutil
-from python_dynamodb_lock.python_dynamodb_lock import DynamoDBLockClient, 
DynamoDBLockError
-from tenacity import before_sleep_log, retry, stop_after_delay, 
wait_exponential
-
-logging.basicConfig(level=logging.INFO)
-log = logging.getLogger(__name__)
-log.setLevel(logging.DEBUG)
-
-logging.getLogger('python_dynamodb_lock').setLevel(logging.WARNING)
-
-
-TABLE_NAME = os.getenv('COUNTER_TABLE', 'GithubRunnerQueue')
-
-
[email protected]()
[email protected]('--repo', default='apache/airflow')
[email protected]('--user', default='runner')
[email protected](
-    '--output-folder',
-    help="Folder to write credentials to. Default of ~runner/actions-runner",
-    default='~runner/actions-runner',
-)
-def main(repo, output_folder, user):
-    global INSTANCE_ID
-    # Notify the ASG LifeCycle hook that we are now In Service and ready to
-    # process requests/safe to be shut down
-
-    # Fetch current instance ID from where cloutinit writes it to
-    if not INSTANCE_ID:
-        with open('/var/lib/cloud/data/instance-id') as fh:
-            INSTANCE_ID = fh.readline().strip()
-
-    log.info("Starting on %s...", INSTANCE_ID)
-
-    output_folder = os.path.expanduser(output_folder)
-
-    short_time = datetime.timedelta(microseconds=1)
-
-    dynamodb = boto3.resource('dynamodb')
-    client = DynamoDBLockClient(
-        dynamodb,
-        table_name='GitHubRunnerLocks',
-        expiry_period=datetime.timedelta(0, 300),
-        heartbeat_period=datetime.timedelta(seconds=10),
-    )
-
-    # Just keep trying until we get some credentials.
-    while True:
-        # Have each runner try to get a credential in a random order.
-        possibles = get_possible_credentials(repo)
-        random.shuffle(possibles)
-
-        log.info("Trying to get a set of credentials in this order: %r", 
possibles)
-
-        notify = get_sd_notify_func()
-
-        for index in possibles:
-            try:
-                lock = client.acquire_lock(
-                    f'{repo}/{index}',
-                    retry_period=short_time,
-                    retry_timeout=short_time,
-                    raise_context_exception=True,
-                )
-            except DynamoDBLockError as e:
-                log.info("Could not lock %s (%s)", index, e)
-                continue
-
-            with lock:
-                log.info("Obtained lock on %s", index)
-                write_credentials_to_files(repo, index, output_folder, user)
-                merge_in_settings(repo, output_folder)
-                notify(f"STATUS=Obtained lock on {index}")
-
-                if get_lifecycle_state() == "Pending:Wait":
-                    complete_asg_lifecycle_hook()
-
-                notify("READY=1")
-                log.info("Watching for Runner.Worker processes")
-                ProcessWatcher().run()
-
-            client.close()
-
-            exit()
-
-
-def get_sd_notify_func() -> Callable[[str], None]:
-    # http://www.freedesktop.org/software/systemd/man/sd_notify.html
-    addr = os.getenv('NOTIFY_SOCKET')
-    if not addr:
-        return lambda status: None
-
-    sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
-    if addr[0] == '@':
-        addr = '\0' + addr[1:]
-    sock.connect(addr)
-
-    def notify(status: str):
-        sock.sendall(status.encode('utf-8'))
-
-    return notify
-
-
-def write_credentials_to_files(
-    repo: str, index: str, out_folder: str = '~runner/actions-runner', user: 
str = 'runner'
-):
-    param_path = os.path.join('/runners/', repo, index)
-
-    resp = boto3.client("ssm").get_parameters_by_path(Path=param_path, 
Recursive=False, WithDecryption=True)
-
-    param_to_file = {
-        'config': '.runner',
-        'credentials': '.credentials',
-        'rsaparams': '.credentials_rsaparams',
-    }
-
-    for param in resp['Parameters']:
-        # "/runners/apache/airflow/config" -> "config"
-        name = os.path.basename(param['Name'])
-        filename = param_to_file.get(name, None)
-        if filename is None:
-            log.info("Unknown Parameter from SSM: %r", param['Name'])
-            continue
-        log.info("Writing %r to %r", param['Name'], filename)
-        with open(os.path.join(out_folder, filename), "w") as fh:
-            fh.write(param['Value'])
-            shutil.chown(fh.name, user)
-            os.chmod(fh.name, 0o600)
-        del param_to_file[name]
-    if param_to_file:
-        raise RuntimeError(f"Missing expected params: 
{list(param_to_file.keys())}")
-
-
-def merge_in_settings(repo: str, out_folder: str) -> None:
-    client = boto3.client('ssm')
-
-    param_path = os.path.join('/runners/', repo, 'configOverlay')
-    log.info("Loading config overlay from %s", param_path)
-
-    try:
-
-        resp = client.get_parameter(Name=param_path, WithDecryption=True)
-    except client.exceptions.ParameterNotFound:
-        log.debug("Failed to load config overlay", exc_info=True)
-        return
-
-    try:
-        overlay = json.loads(resp['Parameter']['Value'])
-    except ValueError:
-        log.debug("Failed to parse config overlay", exc_info=True)
-        return
-
-    with open(os.path.join(out_folder, ".runner"), "r+") as fh:
-        settings = json.load(fh)
-
-        for key, val in overlay.items():
-            settings[key] = val
-
-        fh.seek(0, os.SEEK_SET)
-        os.ftruncate(fh.fileno(), 0)
-        json.dump(settings, fh, indent=2)
-
-
-def get_possible_credentials(repo: str) -> List[str]:
-    client = boto3.client("ssm")
-    paginator = client.get_paginator("describe_parameters")
-
-    path = os.path.join('/runners/', repo, '')
-    baked_path = os.path.join(path, 'runnersList')
-
-    # Pre-compute the list, to avoid making lots of requests and getting 
throttled by SSM API in case of
-    # thundering herd
-    try:
-        log.info("Using pre-computed credentials indexes from %s", baked_path)
-        resp = client.get_parameter(Name=baked_path)
-        return resp['Parameter']['Value'].split(',')
-    except client.exceptions.ParameterNotFound:
-        pass
-
-    log.info("Looking at %s for possible credentials", path)
-
-    pages = paginator.paginate(
-        ParameterFilters=[{"Key": "Path", "Option": "Recursive", "Values": 
[path]}],
-        PaginationConfig={
-            "PageSize": 50,
-        },
-    )
-
-    seen = set()
-
-    for i, page in enumerate(pages):
-        log.info("Page %d", i)
-        for param in page['Parameters']:
-            name = param['Name']
-            log.info("%s", name)
-
-            # '/runners/x/1/config' -> '1/config',
-            # '/runners/x/y/1/config' -> 'y/1/config',
-            local_name = name[len(path) :]
-
-            try:
-                # '1/config' -> '1'
-                index, _ = local_name.split('/')
-            except ValueError:
-                # Ignore any 'x/y' when we asked for 'x'. There should only be 
an index and a filename
-                log.debug("Ignoring nested path %s", name)
-                continue
-
-            try:
-                # Check it's a number, but keep variable as string
-                int(index)
-            except ValueError:
-                log.debug("Ignoring non-numeric index %s", name)
-                continue
-
-            index = os.path.basename(os.path.dirname(name))
-            seen.add(index)
-
-    if not seen:
-        raise RuntimeError(f'No credentials found in SSM ParameterStore for 
{repo!r}')
-
-    try:
-        resp = client.put_parameter(
-            Name=baked_path, Type='StringList', Value=','.join(list(seen)), 
Overwrite=False
-        )
-        log.info("Stored pre-computed credentials indexes at %s", baked_path)
-    except client.exceptions.ParameterAlreadyExists:
-        # Race, we lost, never mind!
-        pass
-
-    return list(seen)
-
-
-OWN_ASG = None
-INSTANCE_ID = None
-
-
-def get_lifecycle_state() -> str:
-    global INSTANCE_ID, OWN_ASG
-
-    if not INSTANCE_ID:
-        with open('/var/lib/cloud/data/instance-id') as fh:
-            INSTANCE_ID = fh.readline().strip()
-
-    asg_client = boto3.client('autoscaling')
-
-    try:
-        instances = asg_client.describe_auto_scaling_instances(
-            InstanceIds=[INSTANCE_ID],
-        )['AutoScalingInstances']
-    except asg_client.exceptions.ClientError:
-        return "UNKNOWN"
-
-    if len(instances) != 1:
-        return "UNKNOWN"
-
-    details = instances[0]
-
-    if not OWN_ASG:
-        OWN_ASG = details['AutoScalingGroupName']
-
-    return details['LifecycleState']
-
-
-def complete_asg_lifecycle_hook(hook_name='WaitForInstanceReportReady', 
retry=False):
-    global OWN_ASG, INSTANCE_ID
-    # Notify the ASG LifeCycle hook that we are now InService and ready to
-    # process requests/safe to be shut down
-
-    asg_client = boto3.client('autoscaling')
-
-    try:
-        asg_client.complete_lifecycle_action(
-            AutoScalingGroupName=OWN_ASG,
-            InstanceId=INSTANCE_ID,
-            LifecycleHookName=hook_name,
-            LifecycleActionResult='CONTINUE',
-        )
-        log.info("LifeCycle hook %s set to CONTINUE instance=%s", hook_name, 
INSTANCE_ID)
-    except asg_client.exceptions.ClientError as e:
-        # If the script fails for whatever reason and we re-run, the lifecycle 
hook may have already be
-        # completed, so this would fail. That is not an error
-
-        # We don't want the stacktrace here, just the message
-        log.warning("Failed to complete lifecycle hook %s: %s", hook_name, 
str(e))
-        pass
-
-
-# Constants and types from
-# 
https://github.com/torvalds/linux/blob/fcadab740480e0e0e9fa9bd272acd409884d431a/include/uapi/linux/cn_proc.h
-class NlMsgFlag(enum.IntEnum):
-    NoOp = 1
-    Error = 2
-    Done = 3
-    Overrun = 4
-
-
-class NLMsgHdr(ctypes.Structure):
-    """Netlink Message Header"""
-
-    _fields_ = [
-        ("len", ctypes.c_uint32),
-        ("type", ctypes.c_uint16),
-        ("flags", ctypes.c_uint16),
-        ("seq", ctypes.c_uint32),
-        ("pid", ctypes.c_uint32),
-    ]
-
-
-class ProcConnectorOp(enum.IntEnum):
-    MCAST_LISTEN = 1
-    MCAST_IGNORE = 2
-
-
-class cn_msg(ctypes.Structure):
-    """Linux kernel Connector message"""
-
-    CN_IDX_PROC = 1
-    CN_VAL_PROC = 1
-
-    _fields_ = [
-        ("cb_id_idx", ctypes.c_uint32),
-        ("cb_id_val", ctypes.c_uint32),
-        ("seq", ctypes.c_uint32),
-        ("ack", ctypes.c_uint32),
-        ("len", ctypes.c_uint16),
-        ("flags", ctypes.c_uint16),
-    ]
-
-    def __init__(self, header, data, **kwargs):
-        super().__init__(**kwargs)
-        self.header = header
-        self.len = ctypes.sizeof(data)
-        self.data = data
-        self.header.len = ctypes.sizeof(header) + ctypes.sizeof(self) + 
self.len
-
-    def to_bytes(self):
-        return bytes(self.header) + bytes(self) + bytes(self.data)  # type: 
ignore
-
-
-class ProcEventWhat(enum.IntFlag):
-    NONE = 0x0
-    FORK = 0x1
-    EXEC = 0x2
-    UID = 0x4
-    GID = 0x40
-    SID = 0x80
-    PTRACE = 0x0000010
-    COMM = 0x0000020
-    COREDUMP = 0x40000000
-    EXIT = 0x80000000
-
-
-class proc_event(ctypes.Structure):
-    """Base proc_event field"""
-
-    _fields_ = [
-        ("what", ctypes.c_uint32),
-        ("cpu", ctypes.c_uint32),
-        ("timestamp", ctypes.c_uint64),  # Number of nano seconds since system 
boot
-    ]
-
-    @classmethod
-    def from_netlink_packet(
-        cls, data
-    ) -> Tuple["proc_event", Union[None, "exec_proc_event", 
"exit_proc_event"]]:
-        """
-        Parse the netlink packet in to a
-        """
-        # Netlink message header (struct nlmsghdr)
-        header = NLMsgHdr.from_buffer_copy(data)
-        data = data[ctypes.sizeof(header) :]
-
-        # We already checked/filtered on header.type == NlMsgFlag.Done
-
-        # Connector message header (struct cn_msg)
-        connector_msg = cn_msg.from_buffer_copy(data)
-
-        # Ignore messages from other Netlink connector types: done via BPF
-
-        data = data[ctypes.sizeof(connector_msg) :]
-
-        event = proc_event.from_buffer_copy(data)
-        data = data[ctypes.sizeof(event) :]
-        event.what = ProcEventWhat(event.what)
-
-        if event.what == ProcEventWhat.EXEC:
-            return event, exec_proc_event.from_buffer_copy(data)
-        elif event.what == ProcEventWhat.EXIT:
-            return event, exit_proc_event.from_buffer_copy(data)
-        return event, None
-
-
-class exec_proc_event(ctypes.Structure):
-    _fields_ = [
-        ("pid", ctypes.c_int32),
-        ("tid", ctypes.c_int32),
-    ]
-
-
-class exit_proc_event(ctypes.Structure):
-    _fields_ = [
-        ("pid", ctypes.c_int32),
-        ("tid", ctypes.c_int32),
-        ("exit_code", ctypes.c_int32),
-        ("signal", ctypes.c_int32),
-    ]
-
-
-class ProcessWatcher:
-    interesting_processes = {}
-
-    protected = None
-    in_termating_lifecycle = False
-
-    def run(self):
-        # Create a signal pipe that we can poll on
-        sig_read, sig_write = socket.socketpair()
-
-        sel = selectors.DefaultSelector()
-
-        def sig_handler(signal, frame):
-            # no-op
-            ...
-
-        sig_read.setblocking(False)
-        sig_write.setblocking(False)
-        sel.register(sig_read, selectors.EVENT_READ, None)
-
-        proc_socket = self.open_proc_connector_socket()
-        proc_socket.setblocking(False)
-
-        signal.signal(signal.SIGINT, sig_handler)
-        signal.signal(signal.SIGALRM, sig_handler)
-        signal.setitimer(signal.ITIMER_REAL, 30, 30.0)
-        signal.set_wakeup_fd(sig_write.fileno(), warn_on_full_buffer=False)
-
-        sel.register(proc_socket, selectors.EVENT_READ, self.handle_proc_event)
-
-        self.pgrep()
-
-        try:
-            while True:
-                for key, mask in sel.select():
-
-                    if key.fileobj == sig_read:
-                        sig = signal.Signals(key.fileobj.recv(1)[0])  # type: 
ignore
-                        if sig == signal.SIGALRM:
-                            self.check_still_alive()
-                            continue
-                        else:
-                            log.info(f"Got {sig.name}, exiting")
-                            return
-                    callback = key.data
-                    callback(key.fileobj, mask)
-        finally:
-            # Disable the timers for any cleanup code to run
-            signal.setitimer(signal.ITIMER_REAL, 0)
-            signal.set_wakeup_fd(-1)
-
-    def pgrep(self):
-        """Check for any interesting processes we might have missed."""
-        listener_found = False
-
-        for proc in psutil.process_iter(['name', 'cmdline']):
-            try:
-                if proc.name() == "Runner.Worker" and proc.pid not in 
self.interesting_processes:
-                    log.info(
-                        "Found existing interesting processes, protecting from 
scale in %d: %s",
-                        proc.pid,
-                        proc.cmdline(),
-                    )
-                    self.interesting_processes[proc.pid] = proc
-                    self.protect_from_scale_in(protect=True)
-                    self.dynamodb_atomic_decrement()
-                if proc.name() == "Runner.Listener":
-                    listener_found = True
-            except psutil.NoSuchProcess:
-                # Process went away before we could
-                pass
-
-        if not listener_found:
-            if self.in_termating_lifecycle:
-                log.info("Runner.Listener process not found - OkayToTerminate 
instance")
-                complete_asg_lifecycle_hook('OkayToTerminate')
-            else:
-                # Unprotect ourselves if somehow the runner is no longer 
working
-                self.protect_from_scale_in(protect=False)
-
-    def check_still_alive(self):
-        # Check ASG status
-        if not self.in_termating_lifecycle:
-            state = get_lifecycle_state()
-            if state == 'Terminating:Wait':
-                self.in_termating_lifecycle = True
-                self.gracefully_terminate_runner()
-            elif state == 'Pending:Wait':
-                complete_asg_lifecycle_hook()
-
-        # proc_connector is un-reliable (UDP) so periodically check if the 
processes are still alive
-        if not self.interesting_processes:
-            self.pgrep()
-            return
-
-        # list() is used to prevent "Dict changed size during iteration" 
during loop below
-        pids = list(self.interesting_processes.keys())
-        log.info("Checking processes %r are still alive", pids)
-
-        for pid in pids:
-            proc = self.interesting_processes[pid]
-            if not proc.is_running() or proc.status() == psutil.STATUS_ZOMBIE:
-                log.info("Proc %d dead but we didn't notice!", pid)
-                del self.interesting_processes[pid]
-
-        if not self.interesting_processes:
-            log.info("No interesting processes left, unprotecting from scale 
in")
-            self.protect_from_scale_in(protect=False)
-        elif not self.protected:
-            # If we didn't manage to protect last time, try again
-            self.protect_from_scale_in()
-
-    def gracefully_terminate_runner(self):
-        check_call(['systemctl', 'stop', 'actions.runner', '--no-block'])
-
-    def protect_from_scale_in(self, protect: bool = True):
-        """Set (or unset) ProtectedFromScaleIn on our instance"""
-        if not OWN_ASG:
-            # Not part of an ASG
-            return
-
-        if self.in_termating_lifecycle:
-            log.info("Not trying to SetInstanceProtection, we are already in 
the terminating lifecycle step")
-            return
-
-        asg_client = boto3.client('autoscaling')
-        try:
-            self._protect_from_scale_in(asg_client, protect)
-            self.protected = protect
-        except asg_client.exceptions.ClientError as e:
-            # This can happen if this the runner picks up a job "too quick", 
and the ASG still has the state
-            # as Pending:Proceed, so we can't yet set it as protected
-            log.warning("Failed to set scale in protection: %s", str(e))
-
-    @retry(
-        wait=wait_exponential(multiplier=1, max=10),
-        stop=stop_after_delay(30),
-        before_sleep=before_sleep_log(log, logging.INFO),
-        reraise=True,
-    )
-    def _protect_from_scale_in(self, asg_client, protect):
-        asg_client.set_instance_protection(
-            AutoScalingGroupName=OWN_ASG,
-            InstanceIds=[INSTANCE_ID],
-            ProtectedFromScaleIn=protect,
-        )
-
-    def dynamodb_atomic_decrement(self):
-        dynamodb = boto3.client('dynamodb')
-        try:
-            resp = dynamodb.update_item(
-                TableName=TABLE_NAME,
-                Key={'id': {'S': 'queued_jobs'}},
-                ExpressionAttributeValues={':delta': {'N': '-1'}, ':limit': 
{'N': '0'}},
-                UpdateExpression='ADD queued :delta',
-                # Make sure it never goes below zero!
-                ConditionExpression='queued > :limit',
-                ReturnValues='UPDATED_NEW',
-            )
-
-            log.info("Updated DynamoDB queue length: %s", 
resp['Attributes']['queued']['N'])
-        except dynamodb.exceptions.ConditionalCheckFailedException:
-            log.warning("%s.queued was already 0, we won't decrease it any 
further!", TABLE_NAME)
-
-    def handle_proc_event(self, sock, mask):
-        try:
-            data, (nlpid, nlgrps) = sock.recvfrom(1024)
-        except OSError as e:
-            if e.errno == errno.ENOBUFS:
-                return
-            raise
-        if nlpid != 0:
-            # Ignore messages from non-root processes
-            return
-
-        event, detail = proc_event.from_netlink_packet(data)
-        if event.what == ProcEventWhat.EXEC:
-            try:
-                proc = psutil.Process(detail.pid)
-
-                with proc.oneshot():
-                    if proc.name() == "Runner.Worker":
-                        log.info(
-                            "Found new interesting processes, protecting from 
scale in %d: %s",
-                            detail.pid,
-                            proc.cmdline(),
-                        )
-                        self.interesting_processes[detail.pid] = proc
-                        self.protect_from_scale_in(protect=True)
-                        self.dynamodb_atomic_decrement()
-
-            except psutil.NoSuchProcess:
-                # We lost the race, process has already exited. If it was that 
short lived it wasn't that
-                # interesting anyway
-                pass
-        elif event.what == ProcEventWhat.EXIT:
-            if detail.pid in self.interesting_processes:
-                log.info("Interesting process %d exited", detail.pid)
-                del self.interesting_processes[detail.pid]
-
-                if not self.interesting_processes:
-                    log.info("Watching no processes, disabling termination 
protection")
-                    self.protect_from_scale_in(protect=False)
-            elif self.in_termating_lifecycle:
-                try:
-                    proc = psutil.Process(detail.pid)
-                    if proc.name() == "Runner.Listener":
-                        log.info("Runner.Listener process %d exited - 
OkayToTerminate instance", detail.pid)
-                        complete_asg_lifecycle_hook('OkayToTerminate')
-                except psutil.NoSuchProcess:
-                    # We lost the race, process has already exited. If it was 
that short lived it wasn't that
-                    # interesting anyway
-                    pass
-
-    def open_proc_connector_socket(self) -> socket.socket:
-        """Open and set up a socket connected to the kernel's Proc Connector 
event stream
-
-        This uses the Netlink family of socket, the Connector message type and 
the proc_event connector to get
-        send a (UDP) message whenever a process starts or exits.
-
-        We use this mechansim to get notified when processes start or stop, so 
we can watch for the
-        "Runner.Worker" and enable/disable termination protection.
-        """
-
-        class bpf_insn(ctypes.Structure):
-            """The BPF instruction data structure"""
-
-            _fields_ = [
-                ("code", ctypes.c_ushort),
-                ("jt", ctypes.c_ubyte),
-                ("jf", ctypes.c_ubyte),
-                ("k", ctypes.c_uint32),
-            ]
-
-        class bpf_program(ctypes.Structure):
-            """Structure for BIOCSETF"""
-
-            _fields_ = [("bf_len", ctypes.c_uint), ("bf_insns", 
ctypes.POINTER(bpf_insn))]
-
-            def __init__(self, program):
-                self.bf_len = len(program)
-                bpf_insn_array = bpf_insn * self.bf_len
-                self.bf_insns = bpf_insn_array()
-
-                # Fill the pointer
-                for i, insn in enumerate(program):
-                    self.bf_insns[i] = insn
-
-        def bpf_jump(code, k, jt, jf) -> bpf_insn:
-            """
-            :param code: BPF instruction op codes
-            :param k: argument
-            :param jt: jump offset if true
-            :param jf: jump offset if false
-            """
-            return bpf_insn(code, jt, jf, k)
-
-        def bpf_stmt(code, k):
-            return bpf_jump(code, k, 0, 0)
-
-        def packet_filter_prog():
-            """
-            A Berkley Packet Filter program to filter down the "firehose" of 
info we receive over the netlink
-            socket.
-
-            The Proc Connector doesn't provide any easy way to filter out the 
firehose of package events, and
-            while we could ignore the things we don't care about in Python, 
it's more efficient to never
-            receive those packets. "Luckily" there is the BPF, or Berkley 
Packet Filter, which can operate on
-            any socket. This BPF program was taken from
-            
https://web.archive.org/web/20130601175512/https://netsplit.com/2011/02/09/the-proc-connector-and-socket-filters/
-            """
-            # A subset of Berkeley Packet Filter constants and macros, as 
defined in linux/filter.h.
-
-            # Instruction classes
-            BPF_LD = 0x00
-            BPF_JMP = 0x05
-            BPF_RET = 0x06
-
-            # ld/ldx fields
-            BPF_W = 0x00
-            BPF_H = 0x08
-            BPF_ABS = 0x20
-
-            # alu/jmp fields
-            BPF_JEQ = 0x10
-            BPF_K = 0x00
-
-            return bpf_program(
-                [
-                    # Load 16-bit ("half"-word) nlmsg.type field
-                    bpf_stmt(BPF_LD | BPF_H | BPF_ABS, NLMsgHdr.type.offset),
-                    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 
socket.htons(NlMsgFlag.Done), 1, 0),
-                    # Not NlMsgFlag.Done, return whole packet
-                    bpf_stmt(BPF_RET | BPF_K, 0xFFFFFFFF),
-                    #
-                    # Load 32-bit (word) cb_id_idx field
-                    bpf_stmt(BPF_LD | BPF_W | BPF_ABS, ctypes.sizeof(NLMsgHdr) 
+ cn_msg.cb_id_idx.offset),
-                    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 
socket.htonl(cn_msg.CN_IDX_PROC), 1, 0),
-                    # If not CN_IDX_PROC, return whole packet
-                    bpf_stmt(BPF_RET | BPF_K, 0xFFFFFFFF),
-                    #
-                    # Load cb_id_val field
-                    bpf_stmt(BPF_LD | BPF_W | BPF_ABS, ctypes.sizeof(NLMsgHdr) 
+ cn_msg.cb_id_val.offset),
-                    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 
socket.htonl(cn_msg.CN_VAL_PROC), 1, 0),
-                    # If not CN_VAL_PROC, return whole packet
-                    bpf_stmt(BPF_RET | BPF_K, 0xFFFFFFFF),
-                    #
-                    # If not ProcEventWhat.EXEC or ProcEventWhat.EXIT, event, 
filter out the packet
-                    bpf_stmt(
-                        BPF_LD | BPF_W | BPF_ABS,
-                        ctypes.sizeof(NLMsgHdr) + ctypes.sizeof(cn_msg) + 
proc_event.what.offset,
-                    ),
-                    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 
socket.htonl(ProcEventWhat.EXEC), 2, 0),
-                    bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, 
socket.htonl(ProcEventWhat.EXIT), 1, 0),
-                    bpf_stmt(BPF_RET | BPF_K, 0x0),
-                    # Return everything
-                    bpf_stmt(BPF_RET | BPF_K, 0xFFFFFFFF),
-                ]
-            )
-
-        # Create Netlink socket
-
-        # Missing from most/all pythons
-        NETLINK_CONNECTOR = getattr(socket, "NETLINK_CONNECTOR", 11)
-        SO_ATTACH_FILTER = getattr(socket, "SO_ATTACH_FILTER", 26)
-
-        sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, 
NETLINK_CONNECTOR)
-
-        filter_prog = packet_filter_prog()
-        sock.setsockopt(socket.SOL_SOCKET, SO_ATTACH_FILTER, 
bytes(filter_prog))  # type: ignore
-
-        sock.bind((os.getpid(), cn_msg.CN_IDX_PROC))
-
-        # Send PROC_CN_MCAST_LISTEN to start receiving messages
-        msg = cn_msg(
-            header=NLMsgHdr(type=NlMsgFlag.Done, pid=os.getpid()),
-            cb_id_idx=cn_msg.CN_IDX_PROC,
-            cb_id_val=cn_msg.CN_VAL_PROC,
-            seq=0,
-            ack=0,
-            data=ctypes.c_uint32(ProcConnectorOp.MCAST_LISTEN),
-        )
-
-        data = msg.to_bytes()
-        if sock.send(data) != len(data):
-            raise RuntimeError("Failed to send PROC_CN_MCAST_LISTEN")
-
-        return sock
-
-
-if __name__ == "__main__":
-    main()
diff --git a/github-runner-ami/packer/files/runner_bootstrap.sh 
b/github-runner-ami/packer/files/runner_bootstrap.sh
deleted file mode 100644
index 132d870..0000000
--- a/github-runner-ami/packer/files/runner_bootstrap.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -exu -o pipefail
-
-# Validate params
-: "${RUNNER_VERSION?}"
-
-# Set an env var (that is visible in runners) that will let us know we are on 
a self-hosted runner
-echo 'AIRFLOW_SELF_HOSTED_RUNNER="[\"self-hosted\"]"' >> /etc/environment
-
-useradd  --create-home runner -G docker
-
-install --owner runner --directory ~runner/actions-runner
-
-cd ~runner/actions-runner
-curl -L 
"https://github.com/ashb/runner/releases/download/v${RUNNER_VERSION}/actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz";
 | tar -zx
-
-python3 -mvenv /opt/runner-supervisor
-/opt/runner-supervisor/bin/pip install -U pip 
python-dynamodb-lock-whatnick==0.9.3 click==7.1.2 psutil 'tenacity~=6.0'
-
-install --owner root --mode 0755 /tmp/runner-supervisor 
/opt/runner-supervisor/bin/runner-supervisor
-
-systemctl enable iptables.service
-systemctl enable vector.service
-
-# We don't enable actions.runner.service here, but instead in the user-data
-# script, as otherwise it would happen to early, before we have had a chance to
-# drop the AWS_DEFAULT_REGION in to /etc/environment
diff --git a/github-runner-ami/packer/files/source-list-additions.sh 
b/github-runner-ami/packer/files/source-list-additions.sh
deleted file mode 100644
index 6f8b0af..0000000
--- a/github-runner-ami/packer/files/source-list-additions.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-apt-key adv --recv-key 0x1646B01B86E50310 "1646B01B86E50310"
-echo "deb https://dl.yarnpkg.com/debian/ stable main" > 
/etc/apt/sources.list.d/yarn.list
-apt-key add /tmp/timber.key
-echo "deb https://repositories.timber.io/public/vector/deb/ubuntu focal main" 
> /etc/apt/sources.list.d/timber.list
diff --git a/github-runner-ami/packer/files/stop-runner-if-no-job.sh 
b/github-runner-ami/packer/files/stop-runner-if-no-job.sh
deleted file mode 100644
index 9d988de..0000000
--- a/github-runner-ami/packer/files/stop-runner-if-no-job.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -u
-
-MAINPID="${MAINPID:-${1:-}}"
-
-if [[ -z "$MAINPID" ]]; then
-    echo "No MAINPID, assuming it already crashed!"
-    exit 0
-fi
-
-if pgrep --ns $MAINPID -a Runner.Worker > /dev/null; then
-  echo "Waiting for current job to finish"
-  while pgrep --ns $MAINPID -a Runner.Worker; do
-    # Job running -- just wait for it to exit
-    sleep 10
-  done
-
-else
-  # If there were _no_ Workers running, ask the main process to stop. If there
-  # were Workers running, then Runner.Listener would stop automatically because
-  # of the `--once`
-  pkill --ns $MAINPID Runner.Listener || true
-fi
-
-  # Wait for it to shut down
-echo "Waiting for main Runner.Listener $MAINPID process to stop"
-while pgrep --ns $MAINPID -a Runner.Listener; do
-  sleep 5
-done
diff --git a/github-runner-ami/packer/files/timber.key 
b/github-runner-ami/packer/files/timber.key
deleted file mode 100644
index f8b8df7..0000000
--- a/github-runner-ami/packer/files/timber.key
+++ /dev/null
@@ -1,36 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v2
-
-mQENBF9gFZ0BCADETtIHM8y5ehMoyNiZcriK+tHXyKnbZCKtMCKcC4ll94/6pekQ
-jKIPWg8OXojkCtwua/TsddtQmOhUxAUtv6K0jO8r6sJ8rezMhuNH8J8rMqWgzv9d
-2+U7Z7GFgcP0OeD+KigtnR8uyp50suBmEDC8YytmmbESmG261Y38vZME0VvQ+CMy
-Yi/FvKXBXugaiCtaz0a5jVE86qSZbKbuaTHGiLn05xjTqc4FfyP4fi4oT2r6GGyL
-Bn5ob84OjXLQwfbZIIrNFR10BvL2SRLL0kKKVlMBBADodtkdwaTt0pGuyEJ+gVBz
-629PZBtSrwVRU399jGSfsxoiLca9//c7OJzHABEBAAG0OkNsb3Vkc21pdGggUGFj
-a2FnZSAodGltYmVyL3ZlY3RvcikgPHN1cHBvcnRAY2xvdWRzbWl0aC5pbz6JATcE
-EwEIACEFAl9gFZ0CGy8FCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQNUPbLQor
-xLhf6gf8DyfIpKjvEeW/O8lRUTpkiPKezJbb+udZboCXJKDD02Q9PE3hfEfQRr5X
-muytL7YMPvzqBVuP3xV5CN3zvtiQQbZiDhstImVyd+t24pQTkjzkvy+A2yvUuIkE
-RWxuey41f5FNj/7wdfJnHoU9uJ/lvsb7DLXw7FBMZFNBR6LED/d+b61zMzVvmFZA
-gsrCGwr/jfySwnpShmKdJaMTHQx0qt2RfXwNm2V6i900tAuMUWnmUIz5/9vENPKm
-0+31I43a/QgmIrKEePhwn2jfA1oRlYzdv+PbblSTfjTStem+GqQkj9bZsAuqVH8g
-3vq0NvX0k2CLi/W9mTiSdHXFChI15A==
-=k36w
------END PGP PUBLIC KEY BLOCK-----
diff --git a/github-runner-ami/packer/files/vector.toml 
b/github-runner-ami/packer/files/vector.toml
deleted file mode 100644
index f9f3308..0000000
--- a/github-runner-ami/packer/files/vector.toml
+++ /dev/null
@@ -1,105 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-data_dir = "/var/lib/vector"
-
-[api]
-  enabled = true
-
-# Input data. Change me to a valid input source.
-[sources.logs]
-  type = "journald"
-  include_units = ["actions.runner.service", 
"actions.runner-supervisor.service"]
-
-[transforms.without_systemd_fields]
-  type = "remove_fields"
-  inputs = ["logs"]
-  fields = ["_CAP_EFFECTIVE", "_SYSTEMD_SLICE", "_SYSTEMD_CGROUP",
-    "_SYSTEMD_INVOCATION_ID", "_SELINUX_CONTEXT", "_COMM", "_BOOT_ID",
-    "_MACHINE_ID", "_STREAM_ID", "_PID", "_GID", "_UID","_TRANSPORT",
-    "__MONOTONIC_TIMESTAMP", "SYSLOG_IDENTIFIER", "SYSLOG_TIMESTAMP",
-    "PRIORITY", "_EXE", "source_type"]
-
-[sources.runner-logs]
-  type = "file"
-  include = ["/home/runner/actions-runner/_diag/*.log"]
-
-    [sources.runner-logs.multiline]
-      start_pattern = '^\[[0-9]{4}-[0-9]{2}-[0-9]{2}'
-      mode = "halt_before"
-      condition_pattern = '^\[[0-9]{4}-[0-9]{2}-[0-9]{2}'
-      timeout_ms = 250
-
-[transforms.grok-runner-logs]
-  type = "remap"
-  inputs=["runner-logs"]
-  source = '''
-    structured, err = parse_grok(.message, 
"(?m)\\[%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{NOTSPACE:logger}\\] 
%{GREEDYDATA:message}")
-
-    if err != null {
-      .err = err
-    } else {
-      . = merge(., structured)
-    }
-  '''
-[transforms.filter-runner-logs]
-  type = "filter"
-  inputs = ['grok-runner-logs']
-  condition = '''
-    if .logger == "JobServerQueue" {
-      !match!(.message, r'Try to append \d+ batches web console lines for 
record')
-    } else if .logger == "HostContext" {
-      !starts_with!(.message, "Well known directory")
-    } else if .logger == "JobDispatcher" {
-      !starts_with!(.message, "Successfully renew job request")
-    }
-    } else {
-      true
-    }
-  '''
-
-[sources.job-logs]
-  type = "file"
-  include = ["/home/runner/actions-runner/_diag/pages/*.log"]
-
-[transforms.grok-job-logs]
-  type = "remap"
-  inputs = ["job-logs"]
-  drop_on_abort = true
-  source = '''
-    structured, err = parse_grok(.message, "%{TIMESTAMP_ISO8601:timestamp} 
%{GREEDYDATA:message}")
-
-    if err == null {
-      . = merge(., structured)
-      .type = "job-output"
-
-      if length(.message) == 0 ?? true {
-        abort # Don't send empty messages to cloud watch!
-      }
-    }
-  '''
-
-# Output data
-[sinks.cloudwatch]
-inputs   = ["without_systemd_fields", "filter-runner-logs", "grok-job-logs"]
-type     = "aws_cloudwatch_logs"
-encoding = "json"
-create_missing_group = false
-create_missing_stream = true
-group_name = "GitHubRunners"
-stream_name = "{{ host }}"
-region = "${AWS_DEFAULT_REGION}"
diff --git a/github-runner-ami/packer/ubuntu2004.pkr.hcl 
b/github-runner-ami/packer/ubuntu2004.pkr.hcl
deleted file mode 100644
index 0f56d47..0000000
--- a/github-runner-ami/packer/ubuntu2004.pkr.hcl
+++ /dev/null
@@ -1,166 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-variable "vpc_id" {
-  type = string
-}
-variable "ami_name" {
-  type = string
-}
-variable "aws_regions" {
-  type = list(string)
-}
-variable "packer_role_arn" {
-  type = string
-}
-variable "runner_version" {
-  type = string
-}
-variable "runner_labels" {
-  type = string
-}
-variable "session_manager_instance_profile_name" {
-  type = string
-}
-
-source "amazon-ebs" "runner_builder" {
-  #access_key = ""
-  #secret_key = ""
-  region = var.aws_regions[0]
-  ami_name = "${var.ami_name}-${var.runner_version}-v20"
-  ami_regions = var.aws_regions
-  tag {
-    key   = "Name"
-    value = "github-runner-ami"
-  }
-  snapshot_tag {
-    key   = "Name"
-    value = "github-runner-ami-root"
-  }
-  encrypt_boot = false
-  instance_type = "t3.micro"
-  communicator = "ssh"
-  ssh_username = "ubuntu"
-  ssh_interface = "session_manager"
-  iam_instance_profile = var.session_manager_instance_profile_name
-  subnet_filter {
-    #  Just pick a random subnet in the VPC -- we only have the three defaults 
so this is fine!
-    random = true
-  }
-  vpc_id = var.vpc_id
-  source_ami_filter {
-    filters = {
-       virtualization-type = "hvm"
-       name = "ubuntu/images/*buntu-focal-20.04-amd64-server-*"
-       root-device-type = "ebs"
-    }
-    owners = ["099720109477"]
-    most_recent = true
-  }
-  launch_block_device_mappings {
-    device_name = "/dev/sda1"
-    volume_size = 16
-    volume_type = "gp3"
-    delete_on_termination = true
-  }
-}
-
-build {
-  sources = [
-    "source.amazon-ebs.runner_builder"
-  ]
-
-  provisioner "shell" {
-      inline = [
-        "echo Connected via SSM at '${build.User}@${build.Host}:${build.Port}'"
-      ]
-  }
-
-  # Since we connect as a non-root user, we have to "stage" the files to a 
writable folder, which we then move
-  # in to place with the approriate permissions via install-files.sh 
provisioner step
-  provisioner "shell" {
-    inline = [
-      "mkdir -p /tmp/etc-systemd-system /tmp/usr-local-sbin /tmp/usr-local-bin 
/tmp/etc-sudoers.d /tmp/etc-iptables /tmp/etc-cron.d /tmp/etc-vector 
/tmp/etc-systemd-system-vector.service.d"
-    ]
-  }
-  provisioner "file" {
-    destination = "/tmp/etc-systemd-system/actions.runner.service"
-    source      = "./files/actions.runner.service"
-  }
-  provisioner "file" {
-    destination = "/tmp/etc-systemd-system/actions.runner-supervisor.service"
-    source      = "./files/actions.runner-supervisor.service"
-  }
-  provisioner "file" {
-    destination = "/tmp/usr-local-sbin/runner-cleanup-workdir.sh"
-    source      = "./files/runner-cleanup-workdir.sh"
-  }
-  provisioner "file" {
-    destination = "/tmp/usr-local-bin/stop-runner-if-no-job.sh"
-    source      = "./files/stop-runner-if-no-job.sh"
-  }
-  provisioner "file" {
-    destination = "/tmp/etc-sudoers.d/runner"
-    source      = "./files/runner"
-  }
-  provisioner "file" {
-    destination = "/tmp/etc-iptables/rules.v4"
-    source      = "./files/rules.v4"
-  }
-  provisioner "file" {
-    destination = "/tmp/usr-local-sbin/actions-runner-ec2-reporting.sh"
-    source      = "./files/actions-runner-ec2-reporting.sh"
-  }
-  provisioner "file" {
-    destination = "/tmp/etc-cron.d/cloudwatch-metrics-github-runners"
-    source      = "./files/cloudwatch-metrics-github-runners"
-  }
-  provisioner "file" {
-    destination = "/tmp/timber.key"
-    source      = "./files/timber.key"
-  }
-  provisioner "file" {
-    destination = "/tmp/runner-supervisor"
-    source      = "./files/runner-supervisor.py"
-  }
-  provisioner "file" {
-    destination = "/tmp/etc-vector/vector.toml"
-    source      = "./files/vector.toml"
-  }
-  provisioner "shell" {
-    scripts = [
-      "./files/install-files.sh",
-      "./files/source-list-additions.sh",
-      "./files/install-dependencies.sh",
-      "./files/install-nodejs.sh",
-      "./files/install-github-cli.sh",
-      "./files/install-subversion.sh",
-      "./files/docker.sh",
-      "./files/configure_kernel.sh",
-      "./files/git.sh",
-      "./files/runner_bootstrap.sh",
-      "./files/create-hostedtools-cache.sh",
-      "./files/regctl.sh",
-      "./files/cleanup.sh",
-    ]
-    execute_command = "chmod +x '{{ .Path }}'; sudo sh -c '{{ .Vars }} {{ 
.Path }}'"
-    environment_vars = [
-      "RUNNER_VERSION=${var.runner_version}",
-      "RUNNER_LABELS=${var.runner_labels}",
-    ]
-  }
-}
diff --git a/github-runner-ami/packer/vars/variables.pkrvars.hcl 
b/github-runner-ami/packer/vars/variables.pkrvars.hcl
deleted file mode 100644
index c9ad301..0000000
--- a/github-runner-ami/packer/vars/variables.pkrvars.hcl
+++ /dev/null
@@ -1,24 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-vpc_id = "vpc-d73487bd"
-ami_name = "airflow-runner-ami"
-aws_regions = ["eu-central-1", "us-east-2"]
-packer_role_arn = "arn:aws:iam::827901512104:role/packer-role"
-runner_version = "2.309.0-airflow11"
-session_manager_instance_profile_name = "packer_ssm_instance_profile"
-runner_labels = "airflow-runner,vm-runner"
diff --git a/lambdas/scale_out_runner/.chalice/config.json 
b/lambdas/scale_out_runner/.chalice/config.json
deleted file mode 100644
index 669f935..0000000
--- a/lambdas/scale_out_runner/.chalice/config.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "version": "2.0",
-  "app_name": "scale_out_runner",
-  "stages": {
-    "dev": {
-      "api_gateway_stage": "api"
-    },
-    "prod": {
-      "api_gateway_stage": "api",
-      "autogen_policy": false,
-      "iam_policy_file": "prod_iam.json",
-      "environment_variables": {
-        "GH_WEBHOOK_TOKEN_ENCRYPTED": 
"AQICAHg1MGVq8MAqYXSkkgy6iL19KSI14nJw8DelmHFuRpAfvQEh/mniWicOD0N1aVuHhp+VAAAAfDB6BgkqhkiG9w0BBwagbTBrAgEAMGYGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMVqkAu70BaR2rDQ4qAgEQgDlIAxDrBlblL6XNKkJIs+zrNEMcGpS68JnoVh2s1oKEzbBXzYS16/9ZrW9CwUV4ULAd2EsGb90iz74=",
-        "ASG_NAME": "RunnerASG",
-        "ASG_REGION_NAME": "us-east-2"
-      }
-    }
-  },
-  "automatic_layer": true
-}
diff --git a/lambdas/scale_out_runner/.chalice/deployed/prod.json 
b/lambdas/scale_out_runner/.chalice/deployed/prod.json
deleted file mode 100644
index 7f1a411..0000000
--- a/lambdas/scale_out_runner/.chalice/deployed/prod.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "resources": [
-    {
-      "name": "managed-layer",
-      "resource_type": "lambda_layer",
-      "layer_version_arn": 
"arn:aws:lambda:eu-central-1:827901512104:layer:scale_out_runner-prod-managed-layer:35"
-    },
-    {
-      "name": "api_handler_role",
-      "resource_type": "iam_role",
-      "role_arn": 
"arn:aws:iam::827901512104:role/scale_out_runner-prod-api_handler",
-      "role_name": "scale_out_runner-prod-api_handler"
-    },
-    {
-      "name": "api_handler",
-      "resource_type": "lambda_function",
-      "lambda_arn": 
"arn:aws:lambda:eu-central-1:827901512104:function:scale_out_runner-prod"
-    },
-    {
-      "name": "rest_api",
-      "resource_type": "rest_api",
-      "rest_api_id": "2onm92olq7",
-      "rest_api_url": 
"https://2onm92olq7.execute-api.eu-central-1.amazonaws.com/api/";
-    }
-  ],
-  "schema_version": "2.0",
-  "backend": "api"
-}
diff --git a/lambdas/scale_out_runner/.chalice/prod_iam.json 
b/lambdas/scale_out_runner/.chalice/prod_iam.json
deleted file mode 100644
index 539bac3..0000000
--- a/lambdas/scale_out_runner/.chalice/prod_iam.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-    "Version": "2012-10-17",
-    "Statement": [
-        {
-            "Sid": "VisualEditor0",
-            "Effect": "Allow",
-            "Action": [
-                "logs:CreateLogStream",
-                "kms:Decrypt",
-                "autoscaling:SetDesiredCapacity",
-                "ssm:GetParameter",
-                "logs:CreateLogGroup",
-                "logs:PutLogEvents",
-                "dynamodb:UpdateItem"
-            ],
-            "Resource": [
-                "arn:aws:ssm:*:827901512104:parameter/runners/*/configOverlay",
-                
"arn:aws:autoscaling:*:827901512104:autoScalingGroup:*:autoScalingGroupName/AshbRunnerASG",
-                
"arn:aws:kms:*:827901512104:key/48a58710-7ac6-4f88-995f-758a6a450faa",
-                "arn:aws:dynamodb:*:827901512104:table/GithubRunnerQueue",
-                "arn:*:logs:*:*:*"
-            ]
-        },
-        {
-            "Sid": "VisualEditor1",
-            "Effect": "Allow",
-            "Action": [
-                "autoscaling:DescribeAutoScalingGroups"
-            ],
-            "Resource": "*"
-        }
-    ]
-}
diff --git a/lambdas/scale_out_runner/.gitignore 
b/lambdas/scale_out_runner/.gitignore
deleted file mode 100644
index 9e4df26..0000000
--- a/lambdas/scale_out_runner/.gitignore
+++ /dev/null
@@ -1,20 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-.chalice/deployments/
-.chalice/venv/
-__pycache__/
diff --git a/lambdas/scale_out_runner/app.py b/lambdas/scale_out_runner/app.py
deleted file mode 100644
index a02b341..0000000
--- a/lambdas/scale_out_runner/app.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import codecs
-import hmac
-import json
-import logging
-import os
-from typing import cast
-
-import boto3
-from chalice import BadRequestError, Chalice, ForbiddenError
-from chalice.app import Request
-
-app = Chalice(app_name='scale_out_runner')
-app.log.setLevel(logging.INFO)
-
-ASG_GROUP_NAME = os.getenv('ASG_NAME', 'AshbRunnerASG')
-ASG_REGION_NAME = os.getenv('ASG_REGION_NAME', None)
-TABLE_NAME = os.getenv('COUNTER_TABLE', 'GithubRunnerQueue')
-_commiters = set()
-GH_WEBHOOK_TOKEN = None
-
-REPOS = os.getenv('REPOS')
-if REPOS:
-    REPO_CONFIGURATION = json.loads(REPOS)
-else:
-    REPO_CONFIGURATION = {
-        # <repo>: [list-of-branches-to-use-self-hosted-on]
-        'apache/airflow': {'main', 'master'},
-    }
-del REPOS
-
-
[email protected]('/', methods=['POST'])
-def index():
-    validate_gh_sig(app.current_request)
-
-    if app.current_request.headers.get('X-GitHub-Event', None) != "check_run":
-        # Ignore things about installs/permissions etc
-        return {'ignored': 'not about check_runs'}
-
-    body = app.current_request.json_body
-
-    repo = body['repository']['full_name']
-
-    sender = body['sender']['login']
-
-    # Other repos configured with this app, but we don't do anything with them
-    # yet.
-    if repo not in REPO_CONFIGURATION:
-        app.log.info("Ignoring event for %r", repo)
-        return {'ignored': 'Other repo'}
-
-    interested_branches = REPO_CONFIGURATION[repo]
-
-    branch = body['check_run']['check_suite']['head_branch']
-
-    use_self_hosted = sender in commiters() or branch in interested_branches
-    payload = {'sender': sender, 'use_self_hosted': use_self_hosted}
-
-    if body['action'] == 'completed' and body['check_run']['conclusion'] == 
'cancelled':
-        if use_self_hosted:
-            # The only time we get a "cancelled" job is when it wasn't yet 
running.
-            queue_length = increment_dynamodb_counter(-1)
-            # Don't scale in the ASG -- let the CloudWatch alarm do that.
-            payload['new_queue'] = queue_length
-        else:
-            payload = {'ignored': 'unknown sender'}
-
-    elif body['action'] != 'created':
-        payload = {'ignored': "action is not 'created'"}
-
-    elif body['check_run']['status'] != 'queued':
-        # Skipped runs are "created", but are instantly completed. Ignore 
anything that is not queued
-        payload = {'ignored': "check_run.status is not 'queued'"}
-    else:
-        if use_self_hosted:
-            # Increment counter in DynamoDB
-            queue_length = increment_dynamodb_counter()
-            payload.update(**scale_asg_if_needed(queue_length))
-    app.log.info(
-        "delivery=%s branch=%s: %r",
-        app.current_request.headers.get('X-GitHub-Delivery', None),
-        branch,
-        payload,
-    )
-    return payload
-
-
-def commiters(ssm_repo_name: str = os.getenv('SSM_REPO_NAME', 
'apache/airflow')):
-    global _commiters
-
-    if not _commiters:
-        client = boto3.client('ssm')
-        param_path = os.path.join('/runners/', ssm_repo_name, 'configOverlay')
-        app.log.info("Loading config overlay from %s", param_path)
-
-        try:
-
-            resp = client.get_parameter(Name=param_path, WithDecryption=True)
-        except client.exceptions.ParameterNotFound:
-            app.log.debug("Failed to load config overlay", exc_info=True)
-            return set()
-
-        try:
-            overlay = json.loads(resp['Parameter']['Value'])
-        except ValueError:
-            app.log.debug("Failed to parse config overlay", exc_info=True)
-            return set()
-
-        _commiters = set(overlay['pullRequestSecurity']['allowedAuthors'])
-
-    return _commiters
-
-
-def validate_gh_sig(request: Request):
-    sig = request.headers.get('X-Hub-Signature-256', None)
-    if not sig or not sig.startswith('sha256='):
-        raise BadRequestError('X-Hub-Signature-256 not of expected format')
-
-    sig = sig[len('sha256=') :]
-    calculated_sig = sign_request_body(request)
-
-    app.log.debug('Checksum verification - expected %s got %s', 
calculated_sig, sig)
-
-    if not hmac.compare_digest(sig, calculated_sig):
-        raise ForbiddenError('Spoofed request')
-
-
-def sign_request_body(request: Request) -> str:
-    global GH_WEBHOOK_TOKEN
-    if GH_WEBHOOK_TOKEN is None:
-        if 'GH_WEBHOOK_TOKEN' in os.environ:
-            # Local dev support:
-            GH_WEBHOOK_TOKEN = os.environ['GH_WEBHOOK_TOKEN'].encode('utf-8')
-        else:
-            encrypted = os.environb[b'GH_WEBHOOK_TOKEN_ENCRYPTED']
-
-            kms = boto3.client('kms')
-            response = kms.decrypt(CiphertextBlob=codecs.decode(encrypted, 
'base64'))
-            GH_WEBHOOK_TOKEN = response['Plaintext']
-    body = cast(bytes, request.raw_body)
-    return hmac.new(GH_WEBHOOK_TOKEN, body, digestmod='SHA256').hexdigest()  # 
type: ignore
-
-
-def increment_dynamodb_counter(delta: int = 1) -> int:
-    dynamodb = boto3.client('dynamodb')
-    args = dict(
-        TableName=TABLE_NAME,
-        Key={'id': {'S': 'queued_jobs'}},
-        ExpressionAttributeValues={':delta': {'N': str(delta)}},
-        UpdateExpression='ADD queued :delta',
-        ReturnValues='UPDATED_NEW',
-    )
-
-    if delta < 0:
-        # Make sure it never goes below zero!
-        args['ExpressionAttributeValues'][':limit'] = {'N': str(-delta)}
-        args['ConditionExpression'] = 'queued >= :limit'
-
-    resp = dynamodb.update_item(**args)
-    return int(resp['Attributes']['queued']['N'])
-
-
-def scale_asg_if_needed(num_queued_jobs: int) -> dict:
-    asg = boto3.client('autoscaling', region_name=ASG_REGION_NAME)
-
-    resp = asg.describe_auto_scaling_groups(
-        AutoScalingGroupNames=[ASG_GROUP_NAME],
-    )
-
-    asg_info = resp['AutoScalingGroups'][0]
-
-    current = asg_info['DesiredCapacity']
-    max_size = asg_info['MaxSize']
-
-    busy = 0
-    for instance in asg_info['Instances']:
-        if instance['LifecycleState'] == 'InService' and 
instance['ProtectedFromScaleIn']:
-            busy += 1
-    app.log.info("Busy instances: %d, num_queued_jobs: %d, current_size: %d", 
busy, num_queued_jobs, current)
-
-    new_size = num_queued_jobs + busy
-    if new_size > current:
-        if new_size <= max_size or current < max_size:
-            try:
-                new_size = min(new_size, max_size)
-                asg.set_desired_capacity(AutoScalingGroupName=ASG_GROUP_NAME, 
DesiredCapacity=new_size)
-                return {'new_capcity': new_size}
-            except asg.exceptions.ScalingActivityInProgressFault as e:
-                return {'error': str(e)}
-        else:
-            return {'capacity_at_max': True}
-    else:
-        return {'idle_instances': True}
diff --git a/lambdas/scale_out_runner/requirements.txt 
b/lambdas/scale_out_runner/requirements.txt
deleted file mode 100644
index c5402f0..0000000
--- a/lambdas/scale_out_runner/requirements.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-boto3
-chalice
diff --git a/requirements-test.txt b/requirements-test.txt
index 5ca36b4..6023b51 100644
--- a/requirements-test.txt
+++ b/requirements-test.txt
@@ -16,4 +16,3 @@
 # under the License.
 
 pytest~=9.1
-moto
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index a36cc06..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-boto3
-click~=8.5
-chalice
-pygithub
-pytest~=9.1
-python-dynamodb-lock-whatnick~=0.9.3
-psutil
-rich-click
-requests
-tenacity~=9.2
diff --git a/scripts/list_committers b/scripts/list_committers
deleted file mode 100755
index d0b0d09..0000000
--- a/scripts/list_committers
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python3
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import rich_click as click
-from github import Github
-
-from rich.console import Console
-
-console = Console(color_system="standard", width=200)
-
-
[email protected](short_help='List committer logins - used to sync list of 
committers in CI configuration')
[email protected](
-    '--github-token',
-    envvar='GITHUB_TOKEN',
-    help="You can generate the token with readOrg permissions: "
-    
"https://github.com/settings/tokens/new?description=Read%20Org&scopes=read:org";,
-)
-def main(github_token):
-    gh = Github(github_token)
-    org = gh.get_organization('apache')
-    committers = org.get_team_by_slug('airflow-committers')
-    committer_usernames = sorted(f'"{c.login}"' for c in 
committers.get_members())
-
-    click.echo("Take the below list and:")
-    click.echo(" - update the `/runners/apache/airflow/configOverlay` 
parameter in AWS SSM ParameterStore")
-    click.echo(" - restart the self-hosted runners")
-    click.echo(
-        " - Inform the new committer, that it's time to open PR to update list 
of committers in "
-        "dev/breeze/src/airflow_breeze/global_constants.py (COMMITTERS 
variable)"
-    )
-    click.echo(',\n'.join(committer_usernames))
-    click.echo("""
-
-Add the following explanation:
-
-As a new committer, adding yourself to committer list gives you automated
-acccess to our self-hosted runners for your PRs.  Once you merge the changes,
-all your PRs by default will run using our self-hosted infrastructure, that is
-sponsored currently by AWS and Astronomer and involves running the builds on
-AWS spot instances that are started on-demand.
-
-Those instances are way bigger than the Public Runners available for all ASF
-projects. They have 8 cores and 64 GB memory and all the builds happen
-in-memory, and our builds are optimized to use parallelism and memory so that
-often what you will get is 3-4 times speed-up vs the Public instances.
-
-We currently have up to 35 such instances running at a time, so there is a
-possibility - if there are many committers pushing their changes in a short
-time that they will get into a queue so it's not always faster to get the
-feedback. Currently ASF has plenty (900) public runners, so the delays we
-experienced in the past for Public Runners is a distant pass so they should run
-relatively quickly as well, but this might change depending on other projects,
-because the runners are shared between all ASF projects.
-
-At any of your PRs you can apply the label "use public runners" before
-triggering the build and your build will switch to using Public Runners.
-
-Most PRs are "selective" - they will only run a subset of tests - the subeset
-is calculated by "Selective checks" job (you can open the job output and find
-out in details how the decisions are made - we have a simple rule engine that
-determines the set of tests to run. You can apply "full tests needed" label to
-PR before it starts - this way a complete set of tests will be executed -
-including all Python and DB versions.
-
-As a committer, you can also apply the labels to other's PRs and retrigger the
-build if you are in doubt if the selective checks decision was good-enough
-(looking at the content of the PR).
-
-We also have "canary" builds that run a complete set of tests in "main". They
-are run every night and after merging PRs to main. Usually 3-5 canary builds
-complete during the day when there are a number of PRs merged - we cancel
-running build when new PR gets merged before canary build succeeds and we start
-a new one (saves a lot of build time). The canary builds are designed to signal
-that some problems passed through the net and need to be fixed in order to turn
-"main" into "green" so watch out for those - we sometimes revert culprit PRs or
-simply implement fix PRs to do so. If you merged a PR and "canary" build 
failed,
-you should receieve notification about it (but it could be one of the previous
-commits that is the root cause so you need to verify that when diagnosing it
-by looking at past builds and other PRs.
-
-""")
-
-
-if __name__ == "__main__":
-    main()
diff --git a/scripts/store-agent-creds.py b/scripts/store-agent-creds.py
deleted file mode 100755
index 7f00dfa..0000000
--- a/scripts/store-agent-creds.py
+++ /dev/null
@@ -1,206 +0,0 @@
-#!/usr/bin/env python3
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-import json
-import os
-import platform
-import subprocess
-import tempfile
-from typing import Optional, Tuple
-
-import boto3
-import click
-import requests
-from botocore.exceptions import NoCredentialsError
-
-
[email protected]()
[email protected](
-    "--runner-version",
-    default="2.275.1",
-    help="Runner version to register with",
-    metavar="VER",
-)
[email protected]("--repo", default="apache/airflow")
[email protected]("--store-as", default="apache/airflow")
[email protected]("--runnergroup")
[email protected]("--token", help="GitHub runner registration token", 
required=False)
[email protected]("--index", type=int, required=False)
-def main(
-    token, runner_version, store_as: Optional[str], repo, runnergroup: 
Optional[str], index: Optional[int]
-):
-    check_aws_config()
-    dir = make_runner_dir(runner_version)
-
-    if not token:
-        token = click.prompt("GitHub runner registration token")
-
-    if store_as is None:
-        store_as = repo
-
-    if index is None:
-        index = get_next_index(store_as)
-    click.echo(f"Registering as runner {index}")
-
-    register_runner(dir.name, token, repo, runnergroup, store_as, index)
-
-
-def check_aws_config():
-    click.echo("Checking AWS account credentials")
-    try:
-        whoami = boto3.client("sts").get_caller_identity()
-    except NoCredentialsError:
-        click.echo("No AWS credentials found -- maybe you need to set 
AWS_PROFILE?", err=True)
-        exit(1)
-
-    if whoami["Account"] != "827901512104":
-        click.echo("Wrong AWS account in use -- maybe you need to set 
AWS_PROFILE?", err=True)
-        exit(1)
-
-
-def make_runner_dir(version):
-    """Extract the runner tar to a temporary directory"""
-    dir = tempfile.TemporaryDirectory()
-
-    tar = _get_runner_tar(version)
-
-    subprocess.check_call(
-        ["tar", "-xzf", tar],
-        cwd=dir.name,
-    )
-
-    return dir
-
-
-def get_next_index(repo: str) -> int:
-    """Find the next available index to store the runner credentials in AWS 
SSM ParameterStore"""
-    paginator = boto3.client("ssm").get_paginator("describe_parameters")
-
-    path = os.path.join('/runners/', repo, '')
-
-    pages = paginator.paginate(ParameterFilters=[{"Key": "Path", "Option": 
"Recursive", "Values": [path]}])
-
-    seen = set()
-
-    for page in pages:
-        for param in page['Parameters']:
-            name = param['Name']
-
-            # '/runners/1/config' -> '1'
-            index = os.path.basename(os.path.dirname(name))
-            seen.add(int(index))
-
-    if not seen:
-        return 1
-
-    # Fill in any gaps too.
-    for n in range(1, max(seen) + 2):
-        if n not in seen:
-            return n
-
-
-def register_runner(dir: str, token: str, repo: str, runnergroup: 
Optional[str], store_as: str, index: int):
-    os.chdir(dir)
-
-    cmd = [
-        "./config.sh",
-        "--unattended",
-        "--url",
-        f"https://github.com/{repo}";,
-        "--token",
-        token,
-        "--name",
-        f"Airflow Runner {index}",
-    ]
-
-    if runnergroup:
-        cmd += ['--runnergroup', runnergroup]
-
-    res = subprocess.call(cmd)
-
-    if res != 0:
-        exit(res)
-    _put_runner_creds(store_as, index)
-
-
-def _put_runner_creds(repo: str, index: int):
-    client = boto3.client("ssm")
-
-    with open(".runner", encoding='utf-8-sig') as fh:
-        # We want to adjust the config before storing it!
-        config = json.load(fh)
-        config["pullRequestSecurity"] = {}
-
-        client.put_parameter(
-            Name=f"/runners/{repo}/{index}/config",
-            Type="String",
-            Value=json.dumps(config, indent=2),
-        )
-
-    with open(".credentials", encoding='utf-8-sig') as fh:
-        client.put_parameter(Name=f"/runners/{repo}/{index}/credentials", 
Type="String", Value=fh.read())
-
-    with open(".credentials_rsaparams", encoding='utf-8-sig') as fh:
-        client.put_parameter(Name=f"/runners/{repo}/{index}/rsaparams", 
Type="SecureString", Value=fh.read())
-
-
-def _get_system_arch() -> Tuple[str, str]:
-    uname = platform.uname()
-    if uname.system == "Linux":
-        system = "linux"
-    elif uname.system == "Darwin":
-        system = "osx"
-    else:
-        raise RuntimeError("Un-supported platform")
-
-    if uname.machine == "x86_64":
-        arch = "x64"
-    else:
-        raise RuntimeError("Un-supported architecture")
-
-    return system, arch
-
-
-def _get_runner_tar(version) -> str:
-    system, arch = _get_system_arch()
-
-    cache = os.path.abspath(".cache")
-
-    try:
-        os.mkdir(cache)
-    except FileExistsError:
-        pass
-
-    fname = f"actions-runner-{system}-{arch}-{version}.tar.gz"
-    local_file = os.path.join(cache, fname)
-
-    if os.path.exists(local_file):
-        return local_file
-
-    url = 
f"https://github.com/actions/runner/releases/download/v{version}/{fname}";
-    click.echo(f"Getting {url}")
-    resp = requests.get(url, stream=True)
-    resp.raise_for_status()
-    with open(local_file, "wb") as fh, 
click.progressbar(length=int(resp.headers["content-length"])) as bar:
-        for chunk in resp.iter_content(chunk_size=40960):
-            fh.write(chunk)
-            bar.update(len(chunk))
-    return local_file
-
-
-if __name__ == "__main__":
-    main()
diff --git a/tests/conftest.py b/tests/conftest.py
deleted file mode 100644
index 13a8339..0000000
--- a/tests/conftest.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
diff --git a/tests/lambdas/scale_out_runner/conftest.py 
b/tests/lambdas/scale_out_runner/conftest.py
deleted file mode 100644
index 378e130..0000000
--- a/tests/lambdas/scale_out_runner/conftest.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import os
-import sys
-
-import pytest
-from chalice.test import Client
-
-path = os.path.dirname(__file__)
-idx = path.rfind('/tests/')
-path = path[:idx] + path[idx + 6 :]
-sys.path.append(path)
-
-
[email protected]
-def client(request):
-    app = getattr(request.module, "app")
-
-    with Client(app) as client:
-        yield client
diff --git a/tests/lambdas/scale_out_runner/test_app.py 
b/tests/lambdas/scale_out_runner/test_app.py
deleted file mode 100644
index 52f8e99..0000000
--- a/tests/lambdas/scale_out_runner/test_app.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-import json
-
-import pytest
-from app import app  # noqa
-
-
[email protected](autouse=True)
-def no_requests(monkeypatch):
-    monkeypatch.setenv("GH_WEBHOOK_TOKEN", "abc")
-
-
-def test_no_auth(client):
-    response = client.http.post('/', body=json.dumps({'hello': 'world'}))
-    assert response.status_code == 400
-
-
[email protected](
-    "sig",
-    [
-        "md5=",
-        # Valid, but not prefixed
-        "160156e060356c9444613b224fc5613a0a25315b7898fd5d8c7656bd8a6654af",
-    ],
-)
-def test_bad_auth(sig, client):
-    response = client.http.post(
-        '/',
-        headers={
-            'X-Hub-Signature-256': sig,
-        },
-        body=json.dumps({'hello': 'world'}),
-    )
-    assert response.status_code == 400
-
-
-def test_auth(client):
-    response = client.http.post(
-        '/',
-        headers={
-            'X-Hub-Signature-256': 
'sha256=160156e060356c9444613b224fc5613a0a25315b7898fd5d8c7656bd8a6654af'
-        },
-        body=json.dumps({'hello': 'world'}),
-    )
-    assert response.status_code == 200

Reply via email to