Browse Source
Factor some bits out of redeploy.py, so that they can be used in a deployment script suitable for riot.im/app.pull/2974/head
2 changed files with 182 additions and 83 deletions
@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env python |
||||
# |
||||
# download and unpack a riot-web tarball. |
||||
# |
||||
# Allows `bundles` to be extracted to a common directory, and a link to |
||||
# config.json to be added. |
||||
|
||||
from __future__ import print_function |
||||
|
||||
import argparse |
||||
import os |
||||
import os.path |
||||
import tarfile |
||||
import urllib |
||||
|
||||
class DeployException(Exception): |
||||
pass |
||||
|
||||
def create_relative_symlink(linkname, target): |
||||
relpath = os.path.relpath(target, os.path.dirname(linkname)) |
||||
print ("Symlink %s -> %s" % (linkname, relpath)) |
||||
os.symlink(relpath, linkname) |
||||
|
||||
|
||||
def move_bundles(source, dest): |
||||
"""Move the contents of the 'bundles' directory to a common dir |
||||
|
||||
We check that we will not be overwriting anything before we proceed. |
||||
|
||||
Args: |
||||
source (str): path to 'bundles' within the extracted tarball |
||||
dest (str): target common directory |
||||
""" |
||||
|
||||
if not os.path.isdir(dest): |
||||
os.mkdir(dest) |
||||
|
||||
# build a map from source to destination, checking for non-existence as we go. |
||||
renames = {} |
||||
for f in os.listdir(source): |
||||
dst = os.path.join(dest, f) |
||||
if os.path.exists(dst): |
||||
raise DeployException( |
||||
"Not deploying. The bundle includes '%s' which we have previously deployed." |
||||
% f |
||||
) |
||||
renames[os.path.join(source, f)] = dst |
||||
|
||||
for (src, dst) in renames.iteritems(): |
||||
print ("Move %s -> %s" % (src, dst)) |
||||
os.rename(src, dst) |
||||
|
||||
class Deployer: |
||||
def __init__(self): |
||||
self.packages_path = "." |
||||
self.bundles_path = None |
||||
self.should_clean = False |
||||
self.config_location = None |
||||
|
||||
def deploy(self, tarball, extract_path): |
||||
"""Download a tarball if necessary, and unpack it |
||||
|
||||
Returns: |
||||
(str) the path to the unpacked deployment |
||||
""" |
||||
print("Deploying %s to %s" % (tarball, extract_path)) |
||||
|
||||
downloaded = False |
||||
if tarball.startswith("http://") or tarball.startswith("https://"): |
||||
tarball = self.download_file(tarball) |
||||
print("Downloaded file: %s" % tarball) |
||||
downloaded = True |
||||
|
||||
try: |
||||
with tarfile.open(tarball) as tar: |
||||
tar.extractall(extract_path) |
||||
finally: |
||||
if self.should_clean and downloaded: |
||||
os.remove(tarball) |
||||
|
||||
name_str = os.path.basename(tarball).replace(".tar.gz", "") |
||||
extracted_dir = os.path.join(extract_path, name_str) |
||||
print ("Extracted into: %s" % extracted_dir) |
||||
|
||||
if self.config_location: |
||||
create_relative_symlink( |
||||
target=self.config_location, |
||||
linkname=os.path.join(extracted_dir, 'config.json') |
||||
) |
||||
|
||||
if self.bundles_path: |
||||
extracted_bundles = os.path.join(extracted_dir, 'bundles') |
||||
move_bundles(source=extracted_bundles, dest=self.bundles_path) |
||||
|
||||
# replace the (hopefully now empty) extracted_bundles dir with a |
||||
# symlink to the common dir. |
||||
os.rmdir(extracted_bundles) |
||||
create_relative_symlink( |
||||
target=self.bundles_path, |
||||
linkname=extracted_bundles, |
||||
) |
||||
return extracted_dir |
||||
|
||||
def download_file(self, url): |
||||
if not os.path.isdir(self.packages_path): |
||||
os.mkdir(self.packages_path) |
||||
local_filename = os.path.join(self.packages_path, |
||||
url.split('/')[-1]) |
||||
urllib.urlretrieve(url, local_filename) |
||||
return local_filename |
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser("Deploy a Riot build on a web server.") |
||||
parser.add_argument( |
||||
"-p", "--packages-dir", default="./packages", help=( |
||||
"The directory to download the tarball into. (Default: '%(default)s')" |
||||
) |
||||
) |
||||
parser.add_argument( |
||||
"-e", "--extract-path", default="./deploys", help=( |
||||
"The location to extract .tar.gz files to. (Default: '%(default)s')" |
||||
) |
||||
) |
||||
parser.add_argument( |
||||
"-b", "--bundles-dir", nargs='?', default="./bundles", help=( |
||||
"A directory to move the contents of the 'bundles' directory to. A \ |
||||
symlink to the bundles directory will also be written inside the \ |
||||
extracted tarball. Example: './bundles'. \ |
||||
(Default: '%(default)s')" |
||||
) |
||||
) |
||||
parser.add_argument( |
||||
"-c", "--clean", action="store_true", default=False, help=( |
||||
"Remove .tar.gz files after they have been downloaded and extracted. \ |
||||
(Default: %(default)s)" |
||||
) |
||||
) |
||||
parser.add_argument( |
||||
"--config", nargs='?', default='./config.json', help=( |
||||
"Write a symlink at config.json in the extracted tarball to this \ |
||||
location. (Default: '%(default)s')" |
||||
) |
||||
) |
||||
parser.add_argument( |
||||
"tarball", help=( |
||||
"filename of tarball, or URL to download." |
||||
), |
||||
) |
||||
|
||||
args = parser.parse_args() |
||||
|
||||
deployer = Deployer() |
||||
deployer.packages_path = args.packages_dir |
||||
deployer.bundles_path = args.bundles_dir |
||||
deployer.should_clean = args.clean |
||||
deployer.config_location = args.config |
||||
|
||||
deployer.deploy(args.tarball, args.extract_path) |
Loading…
Reference in new issue