Skip to content

Commit 2cf43ab

Browse files
TUN-6175: Simply debian packaging by structural upload
The way apt works is: 1. It looks at the release file based on the `deb` added to sources.list. 2. It uses this release file to find the relative location of Packages or Packages.gz 3. It uses the pool information from packages to find the relative location of where the .deb file is located and then downloads and installs it. This PR seeks to take advantage of this information by simply arranging the files in a way apt expects thereby eliminating the need for an orchestrating endpoint.
1 parent 46c147a commit 2cf43ab

File tree

1 file changed

+30
-73
lines changed

1 file changed

+30
-73
lines changed

release_pkgs.py

Lines changed: 30 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,33 @@
66
1. Create deb and yum repositories from .deb and .rpm files.
77
This is also responsible for signing the packages and generally preparing
88
them to be in an uploadable state.
9-
2. Upload these packages to a storage and add metadata cross reference
10-
for these to be accessed.
9+
2. Upload these packages to a storage in a format that apt and yum expect.
1110
"""
12-
import requests
1311
import subprocess
1412
import os
15-
import io
16-
import shutil
1713
import logging
1814
from hashlib import sha256
1915

2016
import boto3
2117
from botocore.client import Config
2218
from botocore.exceptions import ClientError
2319

24-
BASE_KV_URL = 'https://api.cloudflare.com/client/v4/accounts/'
2520
# The front facing R2 URL to access assets from.
2621
R2_ASSET_URL = 'https://demo-r2-worker.cloudflare-tunnel.workers.dev/'
2722

2823
class PkgUploader:
29-
def __init__(self, kv_api_token, namespace, account_id, bucket_name, client_id, client_secret):
30-
self.kv_api_token = kv_api_token
31-
self.namespace = namespace
24+
def __init__(self, account_id, bucket_name, client_id, client_secret):
3225
self.account_id = account_id
3326
self.bucket_name = bucket_name
3427
self.client_id = client_id
3528
self.client_secret = client_secret
3629

37-
def send_to_kv(self, key, value):
38-
headers = {
39-
"Content-Type": "application/json",
40-
"Authorization": "Bearer " + self.kv_api_token,
41-
}
42-
43-
kv_url = f"{BASE_KV_URL}{self.account_id}/storage/kv/namespaces/{self.namespace}/values/{key}"
44-
response = requests.put(
45-
kv_url,
46-
headers=headers,
47-
data=value
48-
)
49-
50-
if response.status_code != 200:
51-
jsonResponse = response.json()
52-
errors = jsonResponse["errors"]
53-
if len(errors) > 0:
54-
raise Exception("failed to send to workers kv: {0}", errors[0])
55-
else:
56-
raise Exception("recieved error code: {0}", response.status_code)
57-
58-
59-
def send_pkg_info(self, binary, flavor, asset_name, arch, uploaded_package_location):
60-
key = f"pkg_{binary}_{flavor}_{arch}_{asset_name}"
61-
print(f"writing key:{key} , value: {uploaded_package_location}")
62-
self.send_to_kv(key, uploaded_package_location)
63-
64-
6530
def upload_pkg_to_r2(self, filename, upload_file_path):
6631
endpoint_url = f"https://{self.account_id}.r2.cloudflarestorage.com"
6732
token_secret_hash = sha256(self.client_secret.encode()).hexdigest()
6833

6934
config = Config(
35+
region_name = 'auto',
7036
s3={
7137
"addressing_style": "path",
7238
}
@@ -141,36 +107,30 @@ def create_deb_pkgs(self, flavor, deb_file):
141107
def _clean_build_resources(self):
142108
subprocess.call(("reprepro", "clearvanished"))
143109

144-
def upload_from_directories(pkg_uploader, directory, arch, release):
110+
"""
111+
Walks through a directory and uploads it's assets to R2.
112+
directory : root directory to walk through (String).
113+
release: release string. If this value is none, a specific release path will not be created
114+
and the release will be uploaded to the default path.
115+
binary: name of the binary to upload
116+
"""
117+
def upload_from_directories(pkg_uploader, directory, release, binary):
145118
for root, _ , files in os.walk(directory):
146119
for file in files:
147-
root_elements = root.split("/")
148-
upload_file_name = os.path.join(root, arch, release, file)
149-
flavor_prefix = root_elements[1]
150-
if root_elements[0] == "pool":
151-
upload_file_name = os.path.join(root, file)
152-
flavor_prefix = "deb"
120+
upload_file_name = os.path.join(binary, root, file)
121+
if release:
122+
upload_file_name = os.path.join(release, upload_file_name)
153123
filename = os.path.join(root,file)
154124
try:
155125
pkg_uploader.upload_pkg_to_r2(filename, upload_file_name)
156126
except ClientError as e:
157127
logging.error(e)
158128
return
159129

160-
# save to workers kv in the following formats
161-
# Example:
162-
# key : pkg_cloudflared_bullseye_InRelease,
163-
# value: https://r2.cloudflarestorage.com/dists/bullseye/amd64/2022_3_4/InRelease
164-
r2_asset_url = f"{R2_ASSET_URL}{upload_file_name}"
165-
pkg_uploader.send_pkg_info("cloudflared", flavor_prefix, upload_file_name, arch, r2_asset_url)
166-
167-
# TODO https://jira.cfops.it/browse/TUN-6163: Add a key for latest version.
168-
169130
"""
170131
1. looks into a built_artifacts folder for cloudflared debs
171132
2. creates Packages.gz, InRelease (signed) files
172-
3. uploads them to Cloudflare R2 and
173-
4. adds a Workers KV reference
133+
3. uploads them to Cloudflare R2
174134
175135
pkg_creator, pkg_uploader: are instantiations of the two classes above.
176136
@@ -179,32 +139,32 @@ def upload_from_directories(pkg_uploader, directory, arch, release):
179139
180140
release_version: is the cloudflared release version.
181141
"""
182-
def create_deb_packaging(pkg_creator, pkg_uploader, flavors, gpg_key_id, binary_name, arch, package_component, release_version):
142+
def create_deb_packaging(pkg_creator, pkg_uploader, flavors, gpg_key_id, binary_name, archs, package_component, release_version):
183143
# set configuration for package creation.
184-
print(f"initialising configuration for {binary_name} , {arch}")
144+
print(f"initialising configuration for {binary_name} , {archs}")
185145
pkg_creator.create_distribution_conf(
186146
"./conf/distributions",
187147
binary_name,
188148
binary_name,
189149
flavors,
190-
[arch],
150+
archs,
191151
package_component,
192152
f"apt repository for {binary_name}",
193153
gpg_key_id)
194154

195155
# create deb pkgs
196156
for flavor in flavors:
197-
print(f"creating deb pkgs for {flavor} and {arch}...")
198-
pkg_creator.create_deb_pkgs(flavor, f"./built_artifacts/cloudflared-linux-{arch}.deb")
157+
for arch in archs:
158+
print(f"creating deb pkgs for {flavor} and {arch}...")
159+
pkg_creator.create_deb_pkgs(flavor, f"./built_artifacts/cloudflared-linux-{arch}.deb")
199160

200-
print("uploading to r2...")
201-
upload_from_directories(pkg_uploader, "dists", arch, release_version)
202-
upload_from_directories(pkg_uploader, "pool", arch, release_version)
161+
print("uploading latest to r2...")
162+
upload_from_directories(pkg_uploader, "dists", None, binary_name)
163+
upload_from_directories(pkg_uploader, "pool", None, binary_name)
203164

204-
print("cleaning up directories...")
205-
shutil.rmtree("./dists")
206-
shutil.rmtree("./pool")
207-
shutil.rmtree("./db")
165+
print(f"uploading versioned release {release_version} to r2...")
166+
upload_from_directories(pkg_uploader, "dists", release_version, binary_name)
167+
upload_from_directories(pkg_uploader, "pool", release_version, binary_name)
208168

209169
#TODO: https://jira.cfops.it/browse/TUN-6146 will extract this into it's own command line script.
210170
if __name__ == "__main__":
@@ -215,15 +175,12 @@ def create_deb_packaging(pkg_creator, pkg_uploader, flavors, gpg_key_id, binary_
215175
bucket_name = os.getenv('R2_BUCKET_NAME')
216176
client_id = os.getenv('R2_CLIENT_ID')
217177
client_secret = os.getenv('R2_CLIENT_SECRET')
218-
tunnel_account_id = '5ab4e9dfbd435d24068829fda0077963'
219-
kv_namespace = os.getenv('KV_NAMESPACE')
220-
kv_api_token = os.getenv('KV_API_TOKEN')
178+
tunnel_account_id = os.getenv('R2_ACCOUNT_ID')
221179
release_version = os.getenv('RELEASE_VERSION')
222180
gpg_key_id = os.getenv('GPG_KEY_ID')
223181

224-
pkg_uploader = PkgUploader(kv_api_token, kv_namespace, tunnel_account_id, bucket_name, client_id, client_secret)
182+
pkg_uploader = PkgUploader(tunnel_account_id, bucket_name, client_id, client_secret)
225183

226184
archs = ["amd64", "386", "arm64"]
227185
flavors = ["bullseye", "buster", "bionic"]
228-
for arch in archs:
229-
create_deb_packaging(pkg_creator, pkg_uploader, flavors, gpg_key_id, "cloudflared", arch, "main", release_version)
186+
create_deb_packaging(pkg_creator, pkg_uploader, flavors, gpg_key_id, "cloudflared", archs, "main", release_version)

0 commit comments

Comments
 (0)