diff --git a/README.md b/README.md index fccb99f..5e8c097 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,35 @@ So you may skip them in command line invocation in case you have aws config. * `--sign` - /(optional) sign package metadata * `path` - specify list of path to scan for repositories +## Environment variables reference + +`GPG_SIGN_KEY` - the name of the key that will be used to sign package metadata. + +
Tips for working with GPG keys + + * Create a new key: + ``` bash + gpg --full-generate-key + ``` + * To view all your keys, you can use: + ``` bash + gpg --list-secret-keys --keyid-format LONG + ``` + * Scripts can use something like this to get the Key ID: + ``` bash + export GPG_SIGN_KEY="$(gpg --list-secret-keys --with-colons | grep ^sec: | cut -d: -f5)" + ``` + * Export the key in ASCII armored format: + ``` bash + gpg --armor --export-secret-keys MYKEYID > mykeys.asc + ``` + * Import the key: + ``` bash + cat mykeys.asc | gpg --batch --import + ``` + +
+ ## How it works `mkrepo` searches the supplied path for either `Packages` or `pool` subdir. If diff --git a/debrepo.py b/debrepo.py index b173f62..c288d48 100755 --- a/debrepo.py +++ b/debrepo.py @@ -45,6 +45,18 @@ def bz2_bytes(data): def gpg_sign_string(data, keyname=None, inline=False): + """Signing data according to the specified options. + + Keyword arguments: + data - data for sign (Unicode string). + keyname - name of the gpg key that will be used to sign the + data (string, default: None). + inline - option specifies whether to use a cleartext + signature (bool, default: False). + + Return signed data in binary format. + """ + cmd = "gpg --armor --digest-algo SHA256" if inline: @@ -53,14 +65,14 @@ def gpg_sign_string(data, keyname=None, inline=False): cmd += " --detach-sign" if keyname is not None: - cmd += " --default-key='%s'" % keyname + cmd += " --local-user '%s'" % keyname proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout = proc.communicate(input=data)[0] + stdout = proc.communicate(input=data.encode('utf-8'))[0] if proc.returncode != 0: raise RuntimeError("Failed to sign file: %s" % stdout) @@ -431,9 +443,8 @@ def update_repo(storage, sign, tempdir): release_str.encode('utf-8')) if sign: - release_str_signature = gpg_sign_string(release_str) - release_str_inline = gpg_sign_string(release_str, inline=True) - storage.write_file('dists/%s/Release.gpg' % dist, - release_str_signature.encode('utf-8')) - storage.write_file('dists/%s/InRelease' % dist, - release_str_inline.encode('utf-8')) + keyname = os.getenv('GPG_SIGN_KEY') + release_signature = gpg_sign_string(release_str, keyname) + release_inline = gpg_sign_string(release_str, keyname, True) + storage.write_file('dists/%s/Release.gpg' % dist, release_signature) + storage.write_file('dists/%s/InRelease' % dist, release_inline) diff --git a/rpmrepo.py b/rpmrepo.py index 3490c0e..a0ad6c2 100755 --- a/rpmrepo.py +++ b/rpmrepo.py @@ -58,6 +58,18 @@ def bytes_checksum(data, checksum_type): def gpg_sign_string(data, keyname=None, inline=False): + """Signing data according to the specified options. + + Keyword arguments: + data - data for sign (Unicode string). + keyname - name of the gpg key that will be used to sign the + data (string, default: None). + inline - option specifies whether to use a cleartext + signature (bool, default: False). + + Return signed data in binary format. + """ + cmd = "gpg --armor --digest-algo SHA256" if inline: @@ -66,14 +78,14 @@ def gpg_sign_string(data, keyname=None, inline=False): cmd += " --detach-sign" if keyname is not None: - cmd += " --default-key='%s'" % keyname + cmd += " --local-user '%s'" % keyname proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout = proc.communicate(input=data)[0] + stdout = proc.communicate(input=data.encode('utf-8'))[0] if proc.returncode != 0: raise RuntimeError("Failed to sign file: %s" % stdout) @@ -836,9 +848,9 @@ def update_repo(storage, sign, tempdir): storage.delete_file(initial_primary) if sign: - repomd_str_signed = gpg_sign_string(repomd_str) - storage.write_file('repodata/repomd.xml.asc', - repomd_str_signed.encode('utf-8')) + keyname = os.getenv('GPG_SIGN_KEY') + repomd_signed = gpg_sign_string(repomd_str, keyname) + storage.write_file('repodata/repomd.xml.asc', repomd_signed) def main():