88 them to be in an uploadable state.
99 2. Upload these packages to a storage in a format that apt and yum expect.
1010"""
11- from subprocess import Popen , PIPE
12- import os
1311import argparse
1412import base64
15- from pathlib import Path
1613import logging
14+ import os
1715import shutil
1816from hashlib import sha256
17+ from pathlib import Path
18+ from subprocess import Popen , PIPE
1919
20- import gnupg
2120import boto3
21+ import gnupg
2222from botocore .client import Config
2323from botocore .exceptions import ClientError
2424
2525# The front facing R2 URL to access assets from.
2626R2_ASSET_URL = 'https://demo-r2-worker.cloudflare-tunnel.workers.dev/'
2727
28+
2829class PkgUploader :
2930 def __init__ (self , account_id , bucket_name , client_id , client_secret ):
3031 self .account_id = account_id
@@ -35,14 +36,14 @@ def __init__(self, account_id, bucket_name, client_id, client_secret):
3536 def upload_pkg_to_r2 (self , filename , upload_file_path ):
3637 endpoint_url = f"https://{ self .account_id } .r2.cloudflarestorage.com"
3738 token_secret_hash = sha256 (self .client_secret .encode ()).hexdigest ()
38-
39+
3940 config = Config (
40- region_name = 'auto' ,
41+ region_name = 'auto' ,
4142 s3 = {
4243 "addressing_style" : "path" ,
4344 }
4445 )
45-
46+
4647 r2 = boto3 .client (
4748 "s3" ,
4849 endpoint_url = endpoint_url ,
@@ -57,7 +58,7 @@ def upload_pkg_to_r2(self, filename, upload_file_path):
5758 except ClientError as e :
5859 raise e
5960
60-
61+
6162class PkgCreator :
6263 """
6364 The distribution conf is what dictates to reprepro, the debian packaging building
@@ -72,15 +73,16 @@ class PkgCreator:
7273 description - (String)
7374 gpg_key_id - gpg key id of what you want to use to sign the packages.(String)
7475 """
75- def create_distribution_conf (self ,
76- file_path ,
77- origin ,
78- label ,
79- releases ,
80- archs ,
81- components ,
82- description ,
83- gpg_key_id ):
76+
77+ def create_distribution_conf (self ,
78+ file_path ,
79+ origin ,
80+ label ,
81+ releases ,
82+ archs ,
83+ components ,
84+ description ,
85+ gpg_key_id ):
8486 with open (file_path , "w+" ) as distributions_file :
8587 for release in releases :
8688 distributions_file .write (f"Origin: { origin } \n " )
@@ -102,6 +104,7 @@ def create_distribution_conf(self,
102104 db and pool contain information and metadata about builds. We can ignore these.
103105 dist: contains all the pkgs and signed releases that are necessary for an apt download.
104106 """
107+
105108 def create_deb_pkgs (self , release , deb_file ):
106109 print (f"creating deb pkgs: { release } : { deb_file } " )
107110 p = Popen (["reprepro" , "includedeb" , release , deb_file ], stdout = PIPE , stderr = PIPE )
@@ -130,8 +133,9 @@ def create_rpm_pkgs(self, artifacts_path, gpg_key_name):
130133 gpgcheck=1
131134 gpgkey=https://pkg.cloudflare.com/cloudflare-main.gpg
132135 """
136+
133137 def create_repo_file (self , file_path , binary_name , baseurl , gpgkey_url ):
134- with open (file_path , "w+" ) as repo_file :
138+ with open (os . path . join ( file_path , binary_name + '.repo' ) , "w+" ) as repo_file :
135139 repo_file .write (f"[{ binary_name } -stable]" )
136140 repo_file .write (f"{ binary_name } -stable" )
137141 repo_file .write (f"baseurl={ baseurl } /rpm" )
@@ -141,19 +145,19 @@ def create_repo_file(self, file_path, binary_name, baseurl, gpgkey_url):
141145 repo_file .write (f"gpgkey={ gpgkey_url } " )
142146
143147 def _sign_rpms (self , file_path ):
144- p = Popen (["rpm" , "--define" , f"_gpg_name { gpg_key_name } " , "--addsign" , file_path ], stdout = PIPE , stderr = PIPE )
148+ p = Popen (["rpm" , "--define" , f"_gpg_name { gpg_key_name } " , "--addsign" , file_path ], stdout = PIPE , stderr = PIPE )
145149 out , err = p .communicate ()
146150 if p .returncode != 0 :
147151 print (f"rpm sign result result => { out } , { err } " )
148152 raise
149153
150154 def _sign_repomd (self ):
151- p = Popen (["gpg" , "--batch" , "--detach-sign" , "--armor" , "./rpm/repodata/repomd.xml" ], stdout = PIPE , stderr = PIPE )
155+ p = Popen (["gpg" , "--batch" , "--detach-sign" , "--armor" , "./rpm/repodata/repomd.xml" ], stdout = PIPE , stderr = PIPE )
152156 out , err = p .communicate ()
153157 if p .returncode != 0 :
154158 print (f"sign repomd result => { out } , { err } " )
155159 raise
156-
160+
157161 """
158162 sets up and signs the RPM directories in the following format:
159163 - rpm
@@ -163,9 +167,10 @@ def _sign_repomd(self):
163167
164168 this assumes the assets are in the format <prefix>-<aarch64/x86_64/386>.rpm
165169 """
170+
166171 def _setup_rpm_pkg_directories (self , artifacts_path , gpg_key_name , archs = ["aarch64" , "x86_64" , "386" ]):
167172 for arch in archs :
168- for root , _ , files in os .walk (artifacts_path ):
173+ for root , _ , files in os .walk (artifacts_path ):
169174 for file in files :
170175 if file .endswith (f"{ arch } .rpm" ):
171176 new_dir = f"./rpm/{ arch } "
@@ -174,11 +179,12 @@ def _setup_rpm_pkg_directories(self, artifacts_path, gpg_key_name, archs=["aarch
174179 new_path = os .path .join (new_dir , file )
175180 shutil .copyfile (old_path , new_path )
176181 self ._sign_rpms (new_path )
177-
182+
178183 """
179184 imports gpg keys into the system so reprepro and createrepo can use it to sign packages.
180185 it returns the GPG ID after a successful import
181186 """
187+
182188 def import_gpg_keys (self , private_key , public_key ):
183189 gpg = gnupg .GPG ()
184190 private_key = base64 .b64decode (private_key )
@@ -192,12 +198,13 @@ def import_gpg_keys(self, private_key, public_key):
192198 basically rpm --import <key_file>
193199 This enables us to sign rpms.
194200 """
201+
195202 def import_rpm_key (self , public_key ):
196203 file_name = "pb.key"
197204 with open (file_name , "wb" ) as f :
198205 public_key = base64 .b64decode (public_key )
199206 f .write (public_key )
200-
207+
201208 p = Popen (["rpm" , "--import" , file_name ], stdout = PIPE , stderr = PIPE )
202209 out , err = p .communicate ()
203210 if p .returncode != 0 :
@@ -212,18 +219,21 @@ def import_rpm_key(self, public_key):
212219 and the release will be uploaded to the default path.
213220 binary: name of the binary to upload
214221"""
222+
223+
215224def upload_from_directories (pkg_uploader , directory , release , binary ):
216- for root , _ , files in os .walk (directory ):
225+ for root , _ , files in os .walk (directory ):
217226 for file in files :
218227 upload_file_name = os .path .join (binary , root , file )
219228 if release :
220229 upload_file_name = os .path .join (release , upload_file_name )
221- filename = os .path .join (root ,file )
222- try :
230+ filename = os .path .join (root , file )
231+ try :
223232 pkg_uploader .upload_pkg_to_r2 (filename , upload_file_name )
224233 except ClientError as e :
225234 logging .error (e )
226- return
235+ return
236+
227237
228238"""
229239 1. looks into a built_artifacts folder for cloudflared debs
@@ -237,19 +247,22 @@ def upload_from_directories(pkg_uploader, directory, release, binary):
237247
238248 release_version: is the cloudflared release version. Only provide this if you want a permanent backup.
239249"""
240- def create_deb_packaging (pkg_creator , pkg_uploader , releases , gpg_key_id , binary_name , archs , package_component , release_version ):
250+
251+
252+ def create_deb_packaging (pkg_creator , pkg_uploader , releases , gpg_key_id , binary_name , archs , package_component ,
253+ release_version ):
241254 # set configuration for package creation.
242255 print (f"initialising configuration for { binary_name } , { archs } " )
243256 Path ("./conf" ).mkdir (parents = True , exist_ok = True )
244257 pkg_creator .create_distribution_conf (
245- "./conf/distributions" ,
246- binary_name ,
247- binary_name ,
248- releases ,
249- archs ,
250- package_component ,
251- f"apt repository for { binary_name } " ,
252- gpg_key_id )
258+ "./conf/distributions" ,
259+ binary_name ,
260+ binary_name ,
261+ releases ,
262+ archs ,
263+ package_component ,
264+ f"apt repository for { binary_name } " ,
265+ gpg_key_id )
253266
254267 # create deb pkgs
255268 for release in releases :
@@ -266,6 +279,7 @@ def create_deb_packaging(pkg_creator, pkg_uploader, releases, gpg_key_id, binary
266279 upload_from_directories (pkg_uploader , "dists" , release_version , binary_name )
267280 upload_from_directories (pkg_uploader , "pool" , release_version , binary_name )
268281
282+
269283def create_rpm_packaging (
270284 pkg_creator ,
271285 pkg_uploader ,
@@ -294,60 +308,61 @@ def parse_args():
294308 )
295309
296310 parser .add_argument (
297- "--bucket" , default = os .environ .get ("R2_BUCKET" ), help = "R2 Bucket name"
311+ "--bucket" , default = os .environ .get ("R2_BUCKET" ), help = "R2 Bucket name"
298312 )
299313 parser .add_argument (
300- "--id" , default = os .environ .get ("R2_CLIENT_ID" ), help = "R2 Client ID"
314+ "--id" , default = os .environ .get ("R2_CLIENT_ID" ), help = "R2 Client ID"
301315 )
302316 parser .add_argument (
303- "--secret" , default = os .environ .get ("R2_CLIENT_SECRET" ), help = "R2 Client Secret"
317+ "--secret" , default = os .environ .get ("R2_CLIENT_SECRET" ), help = "R2 Client Secret"
304318 )
305319 parser .add_argument (
306- "--account" , default = os .environ .get ("R2_ACCOUNT_ID" ), help = "R2 Account Tag"
320+ "--account" , default = os .environ .get ("R2_ACCOUNT_ID" ), help = "R2 Account Tag"
307321 )
308322 parser .add_argument (
309- "--release-tag" , default = os .environ .get ("RELEASE_VERSION" ), help = "Release version you want your pkgs to be\
323+ "--release-tag" , default = os .environ .get ("RELEASE_VERSION" ), help = "Release version you want your pkgs to be\
310324 prefixed with. Leave empty if you don't want tagged release versions backed up to R2."
311325 )
312326
313327 parser .add_argument (
314- "--binary" , default = os .environ .get ("BINARY_NAME" ), help = "The name of the binary the packages are for"
328+ "--binary" , default = os .environ .get ("BINARY_NAME" ), help = "The name of the binary the packages are for"
315329 )
316330
317331 parser .add_argument (
318- "--gpg-private-key" , default = os .environ .get ("LINUX_SIGNING_PRIVATE_KEY" ), help = "GPG private key to sign the\
332+ "--gpg-private-key" , default = os .environ .get ("LINUX_SIGNING_PRIVATE_KEY" ), help = "GPG private key to sign the\
319333 packages"
320334 )
321335
322336 parser .add_argument (
323- "--gpg-public-key" , default = os .environ .get ("LINUX_SIGNING_PUBLIC_KEY" ), help = "GPG public key used for\
337+ "--gpg-public-key" , default = os .environ .get ("LINUX_SIGNING_PUBLIC_KEY" ), help = "GPG public key used for\
324338 signing packages"
325339 )
326340
327341 parser .add_argument (
328- "--gpg-public-key-url" , default = os .environ .get ("GPG_PUBLIC_KEY_URL" ), help = "GPG public key url that\
342+ "--gpg-public-key-url" , default = os .environ .get ("GPG_PUBLIC_KEY_URL" ), help = "GPG public key url that\
329343 downloaders can use to verify signing"
330344 )
331345
332346 parser .add_argument (
333- "--pkg-upload-url" , default = os .environ .get ("PKG_URL" ), help = "URL to be used by downloaders"
347+ "--pkg-upload-url" , default = os .environ .get ("PKG_URL" ), help = "URL to be used by downloaders"
334348 )
335349
336350 parser .add_argument (
337- "--deb-based-releases" , default = ["bookworm" , "bullseye" , "buster" , "jammy" , "impish" , "focal" , "bionic" ,
338- "xenial" , "trusty" ],
339- help = "list of debian based releases that need to be packaged for"
351+ "--deb-based-releases" , default = ["bookworm" , "bullseye" , "buster" , "jammy" , "impish" , "focal" , "bionic" ,
352+ "xenial" , "trusty" ],
353+ help = "list of debian based releases that need to be packaged for"
340354 )
341355
342356 parser .add_argument (
343- "--archs" , default = ["amd64" , "386" , "arm64" , "arm" ], help = "list of architectures we want to package for. Note that\
357+ "--archs" , default = ["amd64" , "386" , "arm64" , "arm" ], help = "list of architectures we want to package for. Note that\
344358 it is the caller's responsiblity to ensure that these debs are already present in a directory. This script\
345359 will not build binaries or create their debs."
346- )
360+ )
347361 args = parser .parse_args ()
348362
349363 return args
350364
365+
351366if __name__ == "__main__" :
352367 try :
353368 args = parse_args ()
@@ -362,15 +377,15 @@ def parse_args():
362377 pkg_uploader = PkgUploader (args .account , args .bucket , args .id , args .secret )
363378 print (f"signing with gpg_key: { gpg_key_id } " )
364379 create_deb_packaging (pkg_creator , pkg_uploader , args .deb_based_releases , gpg_key_id , args .binary , args .archs ,
365- "main" , args .release_tag )
366-
380+ "main" , args .release_tag )
381+
367382 create_rpm_packaging (
368- pkg_creator ,
369- pkg_uploader ,
370- "./built_artifacts" ,
371- args .release_tag ,
372- args .binary ,
373- gpg_key_name ,
374- args .gpg_public_key_url ,
375- args .pkg_upload_url ,
376- )
383+ pkg_creator ,
384+ pkg_uploader ,
385+ "./built_artifacts" ,
386+ args .release_tag ,
387+ args .binary ,
388+ gpg_key_name ,
389+ args .gpg_public_key_url ,
390+ args .pkg_upload_url ,
391+ )
0 commit comments