Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: modules/adblockplus/files/web/static/deploy_script.py

Issue 29777652: #6145 - Introduce deploy script for websites (Closed)
Patch Set: Created May 10, 2018, 11:21 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2
3 import argparse
4 from contextlib import closing
5 from filecmp import dircmp
6 import hashlib
7 import os
8 import sys
9 import shutil
10 import tarfile
11 import urllib2
12
13
14 def download(url):
15 file_name = url.split('/')[-1]
16 abs_file_name = os.path.join(os.path.dirname(os.path.realpath(__file__)),
Vasily Kuznetsov 2018/05/15 18:09:37 It seems that you are using the directory of this
f.lopez 2018/05/21 22:23:41 Acknowledged.
17 file_name)
18 print 'Downloading: ' + file_name
19 try:
20 with closing(urllib2.urlopen(url)) as page:
Vasily Kuznetsov 2018/05/15 18:09:37 This code is more or less doing `urllib.urlretriev
f.lopez 2018/05/21 22:23:41 Acknowledged.
21 block_sz = 8912
22 with open(abs_file_name, 'wb') as f:
23 while True:
24 buffer = page.read(block_sz)
25 if not buffer:
26 break
27 f.write(buffer)
28 return abs_file_name
29 except urllib2.HTTPError as e:
30 if e.code == 404:
31 sys.exit("File not found on remote source")
Vasily Kuznetsov 2018/05/15 18:09:37 We have a rule for selecting the type of quotes in
f.lopez 2018/05/21 22:23:41 Acknowledged.
32 except Exception as e:
33 sys.exit(e)
34
35
36 def calculate_md5(file):
37 with open(file) as f:
38 data = f.read()
39 md5_result = hashlib.md5(data).hexdigest()
40 return md5_result.strip()
41
42
43 def read_md5(file):
44 with open(file) as f:
45 md5_result = f.readline()
46 return md5_result.strip()
47
48
49 def untar(tar_file):
50 if tarfile.is_tarfile(tar_file):
51 with tarfile.open(tar_file, 'r:gz') as tar:
52 tar.extractall(os.path.dirname(os.path.realpath(tar_file)))
53 print 'Extracted in current directory'
54 return os.path.dirname(os.path.abspath(__file__))
55
56
57 def remove_tree(to_remove):
58 if os.path.exists(to_remove):
59 if os.path.isdir(to_remove):
60 shutil.rmtree(to_remove)
61 else:
62 os.remove(to_remove)
63
64
65 def clean(hash):
66 print "cleaning directory"
67 cwd = os.path.dirname(os.path.abspath(__file__))
68 [remove_tree(os.path.join(cwd, x)) for x in os.listdir(cwd)
69 if x.startswith(hash)]
70
71
72 def deploy_files(dcmp):
73 for name in dcmp.diff_files:
74 copytree(dcmp.right, dcmp.left)
75 for name in dcmp.left_only:
76 remove_tree(dcmp.left + "/" + name)
77 for name in dcmp.right_only:
78 copytree(dcmp.right, dcmp.left)
79 for sub_dcmp in dcmp.subdirs.values():
80 deploy_files(sub_dcmp)
81
82
83 def copytree(src, dst):
84 if not os.path.exists(dst):
85 os.makedirs(dst)
86 shutil.copystat(src, dst)
87 lst = os.listdir(src)
88 for item in lst:
89 s = os.path.join(src, item)
90 d = os.path.join(dst, item)
91 if os.path.isdir(s):
92 copytree(s, d)
93 else:
94 shutil.copy2(s, d)
95
96
97 if __name__ == '__main__':
98 parser = argparse.ArgumentParser(
99 description='''Fetch a compressed archive in the form of $HASH.tar.gz an d
Vasily Kuznetsov 2018/05/15 18:09:37 "Fetch" and "deploys" is inconsistent. It should b
Vasily Kuznetsov 2018/05/15 18:09:37 It's nicer to be consistent with the type of quote
f.lopez 2018/05/21 22:23:41 Acknowledged.
f.lopez 2018/05/21 22:23:41 Acknowledged.
100 deploys it to /var/www/$WEBSITE folder''',
101 epilog="""--hash must be provided in order to fetch the files,
102 expected files to be fetched are $HASH.tar.gz and $HASH.md5 in order to
Vasily Kuznetsov 2018/05/15 18:09:37 This indentation is a bit hard to follow. Perhaps
f.lopez 2018/05/21 22:23:42 Acknowledged.
103 compare the hashes.
104 --url and --domain are mutually exclusive, if url is provided
105 the files will be downloaded from $url/$HASH, otherwise the default
106 value will be fetched from $domain.eyeofiles.com/$HASH""",
107 )
108 parser.add_argument('--hash', action='store', type=str, nargs='?',
Vasily Kuznetsov 2018/05/15 18:09:37 'store' is the default action, so you don't really
f.lopez 2018/05/21 22:23:41 I know this is the default action, but I think it
Vasily Kuznetsov 2018/05/22 16:38:36 Acknowledged.
109 help='Hash of the commit to deploy')
110 parser.add_argument('--url', action='store', type=str,
111 help='URL where files will be downloaded')
112 parser.add_argument('--domain', action='store', type=str, nargs='?',
113 help='''The domain to prepend
114 [eg. https://$domain.eyeofiles.com]''')
115 parser.add_argument('--website', action='store', type=str, nargs='?',
116 help='The name of the website [e.g. help.eyeo.com]')
117 args = parser.parse_args()
118 hash = args.hash
119 domain = args.domain
120 if args.url:
121 url_file = '{0}/{1}.tar.gz'.format(args.url, hash)
122 url_md5 = '{0}/{1}.md5'.format(args.url, hash)
123 else:
124 url_file = 'https://{0}.eyeofiles.com/{1}.tar.gz'.format(domain, hash)
Vasily Kuznetsov 2018/05/15 18:09:37 What if --domain is not provided?
f.lopez 2018/05/21 22:23:41 You are right, I think it's better if I only provi
Vasily Kuznetsov 2018/05/22 16:38:36 Acknowledged.
125 url_md5 = 'https://{0}.eyeofiles.com/{1}.md5'.format(domain, hash)
126 down_file = download(url_file)
127 down_md5 = download(url_md5)
128 if calculate_md5(down_file) == read_md5(down_md5):
129 tar_directory = untar(down_file)
130 hash_directory = os.path.join(tar_directory, hash)
131 destination = '/var/www/' + args.website
132 dcmp = dircmp(destination, hash_directory)
133 deploy_files(dcmp)
134 clean(hash)
Vasily Kuznetsov 2018/05/15 18:09:37 `clean()` won't be called in cases of errors -- is
f.lopez 2018/05/21 22:23:42 Acknowledged.
135 else:
136 sys.exit("Hashes don't match")
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld