2 # Copyright 2010-2013 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
12 from urllib.parse import urlparse
14 from urlparse import urlparse
16 from os import path as osp
17 pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
18 sys.path.insert(0, pym_path)
20 portage._internal_caller = True
23 prog_name = os.path.basename(argv[0])
24 usage = prog_name + ' [options] ' + \
25 '<src_pkg_dir> <snapshot_dir> <snapshot_uri> <binhost_dir>'
27 prog_desc = "This program will copy src_pkg_dir to snapshot_dir " + \
28 "and inside binhost_dir it will create a Packages index file " + \
29 "which refers to snapshot_uri. This is intended to solve race " + \
30 "conditions on binhosts as described at http://crosbug.com/3225."
33 for line in textwrap.wrap(prog_desc, 70):
37 usage += "Required Arguments:\n\n"
38 usage += " src_pkg_dir - the source $PKGDIR\n"
39 usage += " snapshot_dir - destination snapshot " + \
40 "directory (must not exist)\n"
41 usage += " snapshot_uri - URI which refers to " + \
42 "snapshot_dir from the\n" + \
44 usage += " binhost_dir - directory in which to " + \
45 "write Packages index with\n" + \
48 parser = optparse.OptionParser(usage=usage)
49 parser.add_option('--hardlinks', help='create hardlinks (y or n, default is y)',
51 parser.set_defaults(hardlinks='y')
52 options, args = parser.parse_args(argv[1:])
55 parser.error("Required 4 arguments, got %d" % (len(args),))
57 return parser, options, args
60 parser, options, args = parse_args(argv)
62 src_pkg_dir, snapshot_dir, snapshot_uri, binhost_dir = args
63 src_pkgs_index = os.path.join(src_pkg_dir, 'Packages')
65 if not os.path.isdir(src_pkg_dir):
66 parser.error("src_pkg_dir is not a directory: '%s'" % (src_pkg_dir,))
68 if not os.path.isfile(src_pkgs_index):
69 parser.error("src_pkg_dir does not contain a " + \
70 "'Packages' index: '%s'" % (src_pkg_dir,))
72 parse_result = urlparse(snapshot_uri)
73 if not (parse_result.scheme and parse_result.netloc and parse_result.path):
74 parser.error("snapshot_uri is not a valid URI: '%s'" % (snapshot_uri,))
76 if os.path.isdir(snapshot_dir):
77 parser.error("snapshot_dir already exists: '%s'" % snapshot_dir)
80 os.makedirs(os.path.dirname(snapshot_dir))
83 if not os.path.isdir(os.path.dirname(snapshot_dir)):
84 parser.error("snapshot_dir parent could not be created: '%s'" % \
85 os.path.dirname(snapshot_dir))
88 os.makedirs(binhost_dir)
91 if not os.path.isdir(binhost_dir):
92 parser.error("binhost_dir could not be created: '%s'" % binhost_dir)
95 if options.hardlinks == 'n':
100 cp_cmd = 'cp -%s %s %s' % (
102 portage._shell_quote(src_pkg_dir),
103 portage._shell_quote(snapshot_dir)
106 ret = os.system(cp_cmd)
107 if not (os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == os.EX_OK):
110 infile = io.open(portage._unicode_encode(src_pkgs_index,
111 encoding=portage._encodings['fs'], errors='strict'),
112 mode='r', encoding=portage._encodings['repo.content'],
115 outfile = portage.util.atomic_ofstream(
116 os.path.join(binhost_dir, "Packages"),
117 encoding=portage._encodings['repo.content'],
121 if line[:4] == 'URI:':
122 # skip existing URI line
127 outfile.write("URI: %s\n\n" % snapshot_uri)
139 if __name__ == "__main__":
140 sys.exit(main(sys.argv))