File update.py of Package mullvadvpn
#!/usr/bin/env python
import os
import re
import git
import sys
import shutil
import tarfile
import tempfile
import urllib
import requests
import subprocess
repo_name = "mullvad/mullvadvpn-app"
rpm_url = "https://mullvad.net/download/app/rpm/latest"
rpm_sig_url = "https://mullvad.net/download/app/rpm/latest/signature"
current_dir = os.path.dirname(os.path.realpath(__file__))
def get_current_release():
files = list(filter(lambda x: x.endswith(".rpm"), os.listdir(current_dir)))
assert len(files) == 1, f"Found more than 1 rpm file: {files}"
reg = ".*-(.*)_x86_64.rpm"
ver = re.match(reg, files[0]).groups()[0]
return ver
def get_latest_release(repo):
github_api = f"https://api.github.com/repos/{repo}/releases/latest"
response = requests.get(github_api)
obj = response.json()
tag_name = obj["tag_name"]
tarball_url = obj["tarball_url"]
return tag_name, tarball_url
def get_url_file(url, filename):
target_path = os.path.join(current_dir, filename)
urllib.request.urlretrieve(url, target_path)
def verify_rpm(rpm, rpm_asc):
subprocess.check_call(["gpg", "--verify", rpm_asc, rpm],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def compress_tar(dpath, basedir, fname, fbasedir):
target_tar_path = os.path.join(fbasedir, fname)
subprocess.check_call(["tar", "czf", target_tar_path, dpath],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
cwd=basedir)
return os.path.join(fbasedir, fname)
def rename_directory(oldname, newname):
os.rename(oldname, newname)
def delete_directory(dirpath):
shutil.rmtree(dirpath)
def update_spec_version(old_tag, new_tag):
def replace_version(line):
if not line.startswith("Version: "):
return line
else:
return line.replace(old_tag, new_tag)
with open("mullvadvpn.spec", "r") as spec_file:
spec_lines = spec_file.readlines()
new_spec_lines = list(map(lambda x: replace_version(x), spec_lines))
with open("mullvadvpn.spec", "w") as spec_file:
spec_file.write("".join(new_spec_lines))
def move_file(filepath, newdir, newname):
os.rename(filepath, os.path.join(newdir, newname))
def vendor_go(basedir):
go_dir = os.path.join(basedir, "wireguard", "libwg")
subprocess.check_call(["go", "mod", "vendor"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
cwd=go_dir)
return go_dir, "vendor"
def vendor_rust(basedir):
subprocess.check_call(["cargo", "vendor"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
cwd=basedir)
return basedir, "vendor"
def gen_api_ip_address(srcdir, fname):
with open(fname, "w") as fp:
subprocess.check_call(["cargo", "run", "--bin", "address_cache", "--release"],
stdout=fp, cwd=srcdir, stderr=subprocess.DEVNULL)
def gen_relay(srcdir, fname):
with open(fname, "w") as fp:
subprocess.check_call(["cargo", "run", "--bin", "relay_list", "--release"],
stdout=fp, cwd=srcdir, stderr=subprocess.DEVNULL)
def process_tarball(tmppath, tar_fname, tag_name):
decompress_tar_path = "mullvad-vpn-tarfile"
newtar_dirname = f"mullvadvpn-app-{tag_name}"
decompress_tar_parentdir = os.path.join(tmppath, decompress_tar_path)
t = tarfile.open(os.path.join(tmppath, tar_fname))
t.extractall(path=decompress_tar_parentdir)
t.close()
l = os.listdir(decompress_tar_parentdir)
assert len(l) == 1, f"The tarfile contains more than 1 member {l}. Exit."
decompress_tar_fullpath = os.path.join(decompress_tar_parentdir, l[0])
newtar_fullpath = os.path.join(decompress_tar_parentdir, newtar_dirname)
rename_directory(decompress_tar_fullpath, newtar_fullpath)
# compress
tname = f"{newtar_dirname}.tar.gz"
tpath = compress_tar(dpath=newtar_dirname, basedir=decompress_tar_parentdir,
fname=tname, fbasedir=os.environ["PWD"])
# vendor go
print("Vendoring wireguard-go deps...", end="", flush=True)
go_vendor_dir, go_vendor_path = vendor_go(newtar_fullpath)
tname = "wireguard-vendor.tar.gz"
tpath = compress_tar(dpath=go_vendor_path, basedir=go_vendor_dir,
fname=tname, fbasedir=os.environ["PWD"])
print("OK")
# vendor rust
print("Vendoring rust deps...", end="", flush=True)
rust_vendor_dir, rust_vendor_path = vendor_rust(newtar_fullpath)
tname = "mullvadvpn-app-vendor.tar.gz"
tpath = compress_tar(dpath=rust_vendor_path, basedir=rust_vendor_dir,
fname=tname, fbasedir=os.environ["PWD"])
print("OK")
# generate relay
print("Generating relays.json...", end="", flush=True)
gen_relay(newtar_fullpath, "relays.json")
print("OK")
# generate api ip address
# print("Generating api-ip-address.txt...", end="", flush=True)
# gen_api_ip_address(newtar_fullpath, "api-ip-address.txt")
# print("OK")
if __name__ == "__main__":
old_tag = get_current_release()
tempdir = tempfile.mkdtemp(prefix="mullvad-packager")
tag_name, tarball_url = get_latest_release(repo_name)
tar_fname = f"mullvadvpn-app-{tag_name}.tar.gz"
rpm_fname = f"MullvadVPN-{tag_name}_x86_64.rpm"
rpm_asc_fname = f"{rpm_fname}.asc"
print(f"work dir: {tempdir}, getting tag name: {tag_name}")
print(f"downloading tarball {tar_fname} ...", end="", flush=True)
get_url_file(tarball_url, os.path.join(tempdir, tar_fname))
print("OK")
print(f"downloading rpm {rpm_fname} ...", end="", flush=True)
get_url_file(rpm_url, os.path.join(os.environ["PWD"], rpm_fname))
print("OK")
print(f"downloading rpm sig {rpm_asc_fname} ...", end="", flush=True)
get_url_file(rpm_sig_url, os.path.join(os.environ["PWD"], rpm_asc_fname))
print("OK")
process_tarball(tempdir, tar_fname, tag_name)
print(f"removing tmp path {tempdir} ...", end="", flush=True)
delete_directory(tempdir)
print("OK")
print(f"updating spec file: {old_tag}, {tag_name}")
update_spec_version(old_tag, tag_name)
print("done")