Merge ~larsks/cloud-init:feature/move-to-git into cloud-init:master
- Git
- lp:~larsks/cloud-init
- feature/move-to-git
- Merge into master
Proposed by
Lars Kellogg-Stedman
Status: | Merged |
---|---|
Merged at revision: | 72d6adcb2e4cb5911f7809b89835965d4bf04476 |
Proposed branch: | ~larsks/cloud-init:feature/move-to-git |
Merge into: | cloud-init:master |
Diff against target: |
746 lines (+228/-275) 9 files modified
.gitignore (+5/-0) HACKING.rst (+46/-22) MANIFEST.in (+2/-0) dev/null (+0/-21) packages/brpm (+123/-171) packages/redhat/cloud-init.spec.in (+6/-14) packages/suse/cloud-init.spec.in (+3/-11) tools/make-tarball (+22/-30) tools/read-dependencies (+21/-6) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Joshua Harlow | Pending | ||
Review via email: mp+301310@code.launchpad.net |
Commit message
Description of the change
Update build tools to work with git
- Update HACKING.rst to include git instructions
- update MANIFEST.in and .gitignore to ignore git-related things
- replaced tarball generation scripts with git-based script
- have the spec files correctly identify themselves as cheetah templates
- make brpm work with git
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/.gitignore b/.gitignore | |||
2 | 0 | new file mode 100644 | 0 | new file mode 100644 |
3 | index 0000000..f8b0f3e | |||
4 | --- /dev/null | |||
5 | +++ b/.gitignore | |||
6 | @@ -0,0 +1,5 @@ | |||
7 | 1 | .tox | ||
8 | 2 | dist | ||
9 | 3 | cloud_init.egg-info | ||
10 | 4 | __pycache__ | ||
11 | 5 | build | ||
12 | diff --git a/HACKING.rst b/HACKING.rst | |||
13 | index 6bfe4b4..63a5bde 100644 | |||
14 | --- a/HACKING.rst | |||
15 | +++ b/HACKING.rst | |||
16 | @@ -2,47 +2,71 @@ | |||
17 | 2 | Hacking on cloud-init | 2 | Hacking on cloud-init |
18 | 3 | ===================== | 3 | ===================== |
19 | 4 | 4 | ||
21 | 5 | To get changes into cloud-init, the process to follow is: | 5 | This document describes how to contribute changes to cloud-init. |
22 | 6 | |||
23 | 7 | Do these things once | ||
24 | 8 | -------------------- | ||
25 | 6 | 9 | ||
26 | 7 | * If you have not already, be sure to sign the CCA: | 10 | * If you have not already, be sure to sign the CCA: |
27 | 8 | 11 | ||
28 | 9 | - `Canonical Contributor Agreement`_ | 12 | - `Canonical Contributor Agreement`_ |
29 | 10 | 13 | ||
32 | 11 | * Get your changes into a local bzr branch. | 14 | * Clone the `LaunchPad`_ repository: |
33 | 12 | Initialize a repo, and checkout trunk (init repo is to share bzr info across multiple checkouts, its different than git): | 15 | |
34 | 16 | git clone YOUR_USERNAME@git.launchpad.net:cloud-init | ||
35 | 17 | cd cloud-init | ||
36 | 18 | |||
37 | 19 | If you would prefer a bzr style `git clone lp:cloud-init`, see | ||
38 | 20 | the `Instructions on LaunchPad`_ for more information. | ||
39 | 13 | 21 | ||
43 | 14 | - ``bzr init-repo cloud-init`` | 22 | * Create a new remote pointing to your personal LaunchPad |
44 | 15 | - ``bzr branch lp:cloud-init trunk.dist`` | 23 | repository:: |
45 | 16 | - ``bzr branch trunk.dist my-topic-branch`` | 24 | |
46 | 25 | git remote add YOUR_USERNAME YOUR_USERNAME@git.launchpad.net:~YOUR_USERNAME/cloud-init | ||
47 | 26 | |||
48 | 27 | .. _Canonical Contributor Agreement: http://www.canonical.com/contributors | ||
49 | 17 | 28 | ||
51 | 18 | * Commit your changes (note, you can make multiple commits, fixes, more commits.): | 29 | Do these things for each feature or bug |
52 | 30 | --------------------------------------- | ||
53 | 19 | 31 | ||
55 | 20 | - ``bzr commit`` | 32 | * Create a new topic branch for your work:: |
56 | 21 | 33 | ||
58 | 22 | * Check pep8 and test, and address any issues: | 34 | git checkout -b my-topic-branch |
59 | 23 | 35 | ||
61 | 24 | - ``make test pep8`` | 36 | .. _Instructions on launchpad: https://help.launchpad.net/Code/Git |
62 | 25 | 37 | ||
64 | 26 | * Push to launchpad to a personal branch: | 38 | * Make and commit your changes (note, you can make multiple commits, |
65 | 39 | fixes, more commits.):: | ||
66 | 27 | 40 | ||
68 | 28 | - ``bzr push lp:~<YOUR_USERNAME>/cloud-init/<BRANCH_NAME>`` | 41 | git commit |
69 | 29 | 42 | ||
71 | 30 | * Propose that for a merge into lp:cloud-init via web browser. | 43 | * Check pep8 and test, and address any issues:: |
72 | 31 | 44 | ||
74 | 32 | - Open the branch in `Launchpad`_ | 45 | make test pep8 |
75 | 33 | 46 | ||
78 | 34 | - It will typically be at ``https://code.launchpad.net/<YOUR_USERNAME>/<PROJECT>/<BRANCH_NAME>`` | 47 | * Push your changes to your personal LaunchPad repository:: |
77 | 35 | - ie. https://code.launchpad.net/~smoser/cloud-init/mybranch | ||
79 | 36 | 48 | ||
82 | 37 | * Click 'Propose for merging' | 49 | git push -u YOUR_USERNAME my-topic-branch |
81 | 38 | * Select 'lp:cloud-init' as the target branch | ||
83 | 39 | 50 | ||
86 | 40 | Then, someone on cloud-init-dev (currently `Scott Moser`_ and `Joshua Harlow`_) will | 51 | * Use your browser to create a merge request: |
85 | 41 | review your changes and follow up in the merge request. | ||
87 | 42 | 52 | ||
89 | 43 | Feel free to ping and/or join #cloud-init on freenode (irc) if you have any questions. | 53 | - Open the branch on `LaunchPad`_ |
90 | 54 | |||
91 | 55 | - It will typically be at | ||
92 | 56 | ``https://code.launchpad.net/~YOUR_USERNAME/cloud-init/+git/cloud-init/+ref/BRANCHNAME`` | ||
93 | 57 | for example | ||
94 | 58 | https://code.launchpad.net/~larsks/cloud-init/+git/cloud-init/+ref/feature/move-to-git | ||
95 | 59 | |||
96 | 60 | - Click 'Propose for merging` | ||
97 | 61 | - Select ``cloud-init`` as the target repository | ||
98 | 62 | - Select ``master`` as the target reference path | ||
99 | 63 | |||
100 | 64 | Then, someone on cloud-init-dev (currently `Scott Moser`_ and `Joshua | ||
101 | 65 | Harlow`_) will review your changes and follow up in the merge request. | ||
102 | 66 | |||
103 | 67 | Feel free to ping and/or join ``#cloud-init`` on freenode (irc) if you | ||
104 | 68 | have any questions. | ||
105 | 44 | 69 | ||
106 | 45 | .. _Launchpad: https://launchpad.net | 70 | .. _Launchpad: https://launchpad.net |
107 | 46 | .. _Canonical Contributor Agreement: http://www.canonical.com/contributors | ||
108 | 47 | .. _Scott Moser: https://launchpad.net/~smoser | 71 | .. _Scott Moser: https://launchpad.net/~smoser |
109 | 48 | .. _Joshua Harlow: https://launchpad.net/~harlowja | 72 | .. _Joshua Harlow: https://launchpad.net/~harlowja |
110 | diff --git a/MANIFEST.in b/MANIFEST.in | |||
111 | index 90f6c7d..9426464 100644 | |||
112 | --- a/MANIFEST.in | |||
113 | +++ b/MANIFEST.in | |||
114 | @@ -4,5 +4,7 @@ graft tools | |||
115 | 4 | prune build | 4 | prune build |
116 | 5 | prune dist | 5 | prune dist |
117 | 6 | prune .tox | 6 | prune .tox |
118 | 7 | prune .git | ||
119 | 7 | prune .bzr | 8 | prune .bzr |
120 | 9 | exclude .gitignore | ||
121 | 8 | exclude .bzrignore | 10 | exclude .bzrignore |
122 | diff --git a/packages/brpm b/packages/brpm | |||
123 | index 45e4761..5d16eb7 100755 | |||
124 | --- a/packages/brpm | |||
125 | +++ b/packages/brpm | |||
126 | @@ -1,27 +1,24 @@ | |||
128 | 1 | #!/usr/bin/python | 1 | #!/usr/bin/env python |
129 | 2 | 2 | ||
130 | 3 | import argparse | 3 | import argparse |
131 | 4 | import contextlib | ||
132 | 5 | import glob | 4 | import glob |
133 | 6 | import os | 5 | import os |
134 | 7 | import shutil | 6 | import shutil |
135 | 8 | import subprocess | ||
136 | 9 | import sys | 7 | import sys |
137 | 10 | import tempfile | 8 | import tempfile |
141 | 11 | import re | 9 | import time |
139 | 12 | |||
140 | 13 | from datetime import datetime | ||
142 | 14 | 10 | ||
143 | 15 | 11 | ||
144 | 16 | def find_root(): | 12 | def find_root(): |
145 | 17 | # expected path is in <top_dir>/packages/ | 13 | # expected path is in <top_dir>/packages/ |
146 | 18 | top_dir = os.environ.get("CLOUD_INIT_TOP_D", None) | 14 | top_dir = os.environ.get("CLOUD_INIT_TOP_D", None) |
147 | 19 | if top_dir is None: | 15 | if top_dir is None: |
149 | 20 | top_dir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) | 16 | top_dir = os.path.dirname( |
150 | 17 | os.path.dirname(os.path.abspath(sys.argv[0]))) | ||
151 | 21 | if os.path.isfile(os.path.join(top_dir, 'setup.py')): | 18 | if os.path.isfile(os.path.join(top_dir, 'setup.py')): |
152 | 22 | return os.path.abspath(top_dir) | 19 | return os.path.abspath(top_dir) |
153 | 23 | raise OSError(("Unable to determine where your cloud-init topdir is." | 20 | raise OSError(("Unable to determine where your cloud-init topdir is." |
155 | 24 | " set CLOUD_INIT_TOP_D?")) | 21 | " set CLOUD_INIT_TOP_D?")) |
156 | 25 | 22 | ||
157 | 26 | 23 | ||
158 | 27 | # Use the util functions from cloudinit | 24 | # Use the util functions from cloudinit |
159 | @@ -30,34 +27,15 @@ sys.path.insert(0, find_root()) | |||
160 | 30 | from cloudinit import templater | 27 | from cloudinit import templater |
161 | 31 | from cloudinit import util | 28 | from cloudinit import util |
162 | 32 | 29 | ||
167 | 33 | # Mapping of expected packages to there full name... | 30 | # Map python requirements to package names. If a match isn't found |
168 | 34 | # this is a translation of the 'requires' | 31 | # here, we assume 'python-<pypi_name>'. |
169 | 35 | # file pypi package name to a redhat/fedora package name. | 32 | PACKAGE_MAP = { |
166 | 36 | PKG_MP = { | ||
170 | 37 | 'redhat': { | 33 | 'redhat': { |
171 | 38 | 'argparse': 'python-argparse', | ||
172 | 39 | 'cheetah': 'python-cheetah', | ||
173 | 40 | 'jinja2': 'python-jinja2', | ||
174 | 41 | 'configobj': 'python-configobj', | ||
175 | 42 | 'jsonpatch': 'python-jsonpatch', | ||
176 | 43 | 'oauthlib': 'python-oauthlib', | ||
177 | 44 | 'prettytable': 'python-prettytable', | ||
178 | 45 | 'pyserial': 'pyserial', | 34 | 'pyserial': 'pyserial', |
179 | 46 | 'pyyaml': 'PyYAML', | 35 | 'pyyaml': 'PyYAML', |
180 | 47 | 'requests': 'python-requests', | ||
181 | 48 | 'six': 'python-six', | ||
182 | 49 | }, | 36 | }, |
183 | 50 | 'suse': { | 37 | 'suse': { |
184 | 51 | 'argparse': 'python-argparse', | ||
185 | 52 | 'cheetah': 'python-cheetah', | ||
186 | 53 | 'configobj': 'python-configobj', | ||
187 | 54 | 'jsonpatch': 'python-jsonpatch', | ||
188 | 55 | 'oauthlib': 'python-oauthlib', | ||
189 | 56 | 'prettytable': 'python-prettytable', | ||
190 | 57 | 'pyserial': 'python-pyserial', | ||
191 | 58 | 'pyyaml': 'python-yaml', | 38 | 'pyyaml': 'python-yaml', |
192 | 59 | 'requests': 'python-requests', | ||
193 | 60 | 'six': 'python-six', | ||
194 | 61 | } | 39 | } |
195 | 62 | } | 40 | } |
196 | 63 | 41 | ||
197 | @@ -65,113 +43,79 @@ PKG_MP = { | |||
198 | 65 | RPM_BUILD_SUBDIRS = ['BUILD', 'RPMS', 'SOURCES', 'SPECS', 'SRPMS'] | 43 | RPM_BUILD_SUBDIRS = ['BUILD', 'RPMS', 'SOURCES', 'SPECS', 'SRPMS'] |
199 | 66 | 44 | ||
200 | 67 | 45 | ||
216 | 68 | def get_log_header(version): | 46 | def read_dependencies(): |
217 | 69 | # Try to find the version in the tags output | 47 | '''Returns the Python depedencies from requirements.txt. This explicitly |
218 | 70 | cmd = ['bzr', 'tags'] | 48 | removes 'argparse' from the list of requirements for python >= 2.7, |
219 | 71 | (stdout, _stderr) = util.subp(cmd) | 49 | because with 2.7 argparse became part of the standard library.''' |
220 | 72 | a_rev = None | 50 | cmd = [util.abs_join(find_root(), 'tools', 'read-dependencies')] |
206 | 73 | for t in stdout.splitlines(): | ||
207 | 74 | ver, rev = t.split(None) | ||
208 | 75 | if ver == version: | ||
209 | 76 | a_rev = rev | ||
210 | 77 | break | ||
211 | 78 | if not a_rev: | ||
212 | 79 | return None | ||
213 | 80 | |||
214 | 81 | # Extract who made that tag as the header | ||
215 | 82 | cmd = ['bzr', 'log', '-r%s' % (a_rev), '--timezone=utc'] | ||
221 | 83 | (stdout, _stderr) = util.subp(cmd) | 51 | (stdout, _stderr) = util.subp(cmd) |
225 | 84 | kvs = { | 52 | return [p.lower().strip() for p in stdout.splitlines() |
226 | 85 | 'comment': version, | 53 | if p != 'argparse' or (p == 'argparse' |
227 | 86 | } | 54 | and sys.version_info[0:2] < (2, 7))] |
228 | 87 | 55 | ||
229 | 88 | for line in stdout.splitlines(): | ||
230 | 89 | if line.startswith('committer:'): | ||
231 | 90 | kvs['who'] = line[len('committer:'):].strip() | ||
232 | 91 | if line.startswith('timestamp:'): | ||
233 | 92 | ts = line[len('timestamp:'):] | ||
234 | 93 | ts = ts.strip() | ||
235 | 94 | # http://bugs.python.org/issue6641 | ||
236 | 95 | ts = ts.replace("+0000", '').strip() | ||
237 | 96 | ds = datetime.strptime(ts, '%a %Y-%m-%d %H:%M:%S') | ||
238 | 97 | kvs['ds'] = ds | ||
239 | 98 | 56 | ||
241 | 99 | return format_change_line(**kvs) | 57 | def translate_dependencies(deps, distro): |
242 | 58 | '''Maps python requirements into package names. We assume | ||
243 | 59 | python-<pypi_name> for packages not listed explicitly in | ||
244 | 60 | PACKAGE_MAP.''' | ||
245 | 61 | return [PACKAGE_MAP[distro][req] | ||
246 | 62 | if req in PACKAGE_MAP[distro] else 'python-%s' % req | ||
247 | 63 | for req in deps] | ||
248 | 100 | 64 | ||
249 | 101 | 65 | ||
261 | 102 | def format_change_line(ds, who, comment=None): | 66 | def read_version(): |
262 | 103 | # Rpmbuild seems to be pretty strict about the date format | 67 | '''Read version information. We parse the version itself from |
263 | 104 | d = ds.strftime("%a %b %d %Y") | 68 | the changelog, and then ask git for the commit id and distance |
264 | 105 | d += " - %s" % (who) | 69 | from the last tag.''' |
254 | 106 | if comment: | ||
255 | 107 | d += " - %s" % (comment) | ||
256 | 108 | return "* %s" % (d) | ||
257 | 109 | |||
258 | 110 | |||
259 | 111 | def generate_spec_contents(args, tmpl_fn, top_dir, arc_fn): | ||
260 | 112 | |||
265 | 113 | # Figure out the version and revno | 70 | # Figure out the version and revno |
266 | 114 | cmd = [util.abs_join(find_root(), 'tools', 'read-version')] | 71 | cmd = [util.abs_join(find_root(), 'tools', 'read-version')] |
267 | 115 | (stdout, _stderr) = util.subp(cmd) | 72 | (stdout, _stderr) = util.subp(cmd) |
268 | 116 | version = stdout.strip() | 73 | version = stdout.strip() |
271 | 117 | 74 | ||
272 | 118 | cmd = ['bzr', 'revno'] | 75 | cmd = ['git', 'describe', '--tags'] |
273 | 119 | (stdout, _stderr) = util.subp(cmd) | 76 | (stdout, _stderr) = util.subp(cmd) |
275 | 120 | revno = stdout.strip() | 77 | git_version = stdout.strip() |
276 | 78 | |||
277 | 79 | try: | ||
278 | 80 | _version, distance, revno = git_version.split('-') | ||
279 | 81 | except ValueError: | ||
280 | 82 | distance = None | ||
281 | 83 | revno = None | ||
282 | 84 | |||
283 | 85 | return (version, distance, revno) | ||
284 | 86 | |||
285 | 87 | |||
286 | 88 | def generate_spec_contents(args, tmpl_fn, top_dir, arc_fn): | ||
287 | 89 | |||
288 | 90 | # This will get us something like ('0.7.6', None, None) for a | ||
289 | 91 | # tagged commit, and something like ('0.7.6', '1026', 'gd1d5796') | ||
290 | 92 | # for an untagged commited. | ||
291 | 93 | version, distance, revno = read_version() | ||
292 | 121 | 94 | ||
293 | 122 | # Tmpl params | 95 | # Tmpl params |
294 | 123 | subs = {} | 96 | subs = {} |
295 | 124 | subs['version'] = version | 97 | subs['version'] = version |
296 | 125 | subs['revno'] = revno | 98 | subs['revno'] = revno |
298 | 126 | subs['release'] = "bzr%s" % (revno) | 99 | subs['distance'] = distance |
299 | 100 | |||
300 | 101 | if distance is not None: | ||
301 | 102 | now = time.strftime('%Y%m%d', time.localtime()) | ||
302 | 103 | release = '.%sgit%s' % (now, revno) | ||
303 | 104 | else: | ||
304 | 105 | release = '' | ||
305 | 106 | |||
306 | 127 | if args.sub_release is not None: | 107 | if args.sub_release is not None: |
308 | 128 | subs['subrelease'] = "." + str(args.sub_release) | 108 | subs['subrelease'] = release + "." + str(args.sub_release) |
309 | 129 | else: | 109 | else: |
312 | 130 | subs['subrelease'] = '' | 110 | subs['subrelease'] = release |
311 | 131 | subs['archive_name'] = arc_fn | ||
313 | 132 | 111 | ||
317 | 133 | cmd = [util.abs_join(find_root(), 'tools', 'read-dependencies')] | 112 | subs['archive_name'] = arc_fn |
318 | 134 | (stdout, _stderr) = util.subp(cmd) | 113 | subs['source_name'] = os.path.basename(arc_fn).replace('.tar.gz', '') |
316 | 135 | pkgs = [p.lower().strip() for p in stdout.splitlines()] | ||
319 | 136 | 114 | ||
320 | 137 | # Map to known packages | 115 | # Map to known packages |
358 | 138 | requires = [] | 116 | python_deps = read_dependencies() |
359 | 139 | for p in pkgs: | 117 | package_deps = translate_dependencies(python_deps, args.distro) |
360 | 140 | if p == 'argparse' and sys.version_info[0:2] >= (2, 7): | 118 | subs['requires'] = package_deps |
324 | 141 | # Not needed on anything but 2.6 or older. | ||
325 | 142 | continue | ||
326 | 143 | tgt_pkg = PKG_MP[args.distro].get(p) | ||
327 | 144 | if not tgt_pkg: | ||
328 | 145 | raise RuntimeError(("Do not know how to translate pypi dependency" | ||
329 | 146 | " %r to a known package") % (p)) | ||
330 | 147 | else: | ||
331 | 148 | requires.append(tgt_pkg) | ||
332 | 149 | subs['requires'] = requires | ||
333 | 150 | |||
334 | 151 | # Format a nice changelog (as best as we can) | ||
335 | 152 | changelog = util.load_file(util.abs_join(find_root(), 'ChangeLog')) | ||
336 | 153 | changelog_lines = [] | ||
337 | 154 | missing_versions = 0 | ||
338 | 155 | for line in changelog.splitlines(): | ||
339 | 156 | if not line.strip(): | ||
340 | 157 | continue | ||
341 | 158 | if re.match(r"^\s*[\d][.][\d][.][\d]:\s*", line): | ||
342 | 159 | line = line.strip(":") | ||
343 | 160 | header = get_log_header(line) | ||
344 | 161 | if not header: | ||
345 | 162 | missing_versions += 1 | ||
346 | 163 | if missing_versions == 1: | ||
347 | 164 | # Must be using a new 'dev'/'trunk' release | ||
348 | 165 | changelog_lines.append(format_change_line(datetime.now(), | ||
349 | 166 | '??')) | ||
350 | 167 | else: | ||
351 | 168 | sys.stderr.write(("Changelog version line %s does not " | ||
352 | 169 | "have a corresponding tag!\n") % (line)) | ||
353 | 170 | else: | ||
354 | 171 | changelog_lines.append(header) | ||
355 | 172 | else: | ||
356 | 173 | changelog_lines.append(line) | ||
357 | 174 | subs['changelog'] = "\n".join(changelog_lines) | ||
361 | 175 | 119 | ||
362 | 176 | if args.boot == 'sysvinit': | 120 | if args.boot == 'sysvinit': |
363 | 177 | subs['sysvinit'] = True | 121 | subs['sysvinit'] = True |
364 | @@ -183,21 +127,23 @@ def generate_spec_contents(args, tmpl_fn, top_dir, arc_fn): | |||
365 | 183 | else: | 127 | else: |
366 | 184 | subs['systemd'] = False | 128 | subs['systemd'] = False |
367 | 185 | 129 | ||
368 | 186 | subs['defines'] = ["_topdir %s" % (top_dir)] | ||
369 | 187 | subs['init_sys'] = args.boot | 130 | subs['init_sys'] = args.boot |
370 | 188 | subs['patches'] = [os.path.basename(p) for p in args.patches] | 131 | subs['patches'] = [os.path.basename(p) for p in args.patches] |
371 | 189 | return templater.render_from_file(tmpl_fn, params=subs) | 132 | return templater.render_from_file(tmpl_fn, params=subs) |
372 | 190 | 133 | ||
373 | 191 | 134 | ||
374 | 192 | def main(): | 135 | def main(): |
376 | 193 | 136 | ||
377 | 194 | parser = argparse.ArgumentParser() | 137 | parser = argparse.ArgumentParser() |
378 | 195 | parser.add_argument("-d", "--distro", dest="distro", | 138 | parser.add_argument("-d", "--distro", dest="distro", |
379 | 196 | help="select distro (default: %(default)s)", | 139 | help="select distro (default: %(default)s)", |
380 | 197 | metavar="DISTRO", default='redhat', | 140 | metavar="DISTRO", default='redhat', |
381 | 198 | choices=('redhat', 'suse')) | 141 | choices=('redhat', 'suse')) |
382 | 142 | parser.add_argument('--srpm', | ||
383 | 143 | help='Produce a source rpm', | ||
384 | 144 | action='store_true') | ||
385 | 199 | parser.add_argument("-b", "--boot", dest="boot", | 145 | parser.add_argument("-b", "--boot", dest="boot", |
387 | 200 | help="select boot type (default: %(default)s)", | 146 | help="select boot type (default: %(default)s)", |
388 | 201 | metavar="TYPE", default='sysvinit', | 147 | metavar="TYPE", default='sysvinit', |
389 | 202 | choices=('sysvinit', 'systemd')) | 148 | choices=('sysvinit', 'systemd')) |
390 | 203 | parser.add_argument("-v", "--verbose", dest="verbose", | 149 | parser.add_argument("-v", "--verbose", dest="verbose", |
391 | @@ -221,57 +167,63 @@ def main(): | |||
392 | 221 | if args.verbose: | 167 | if args.verbose: |
393 | 222 | capture = False | 168 | capture = False |
394 | 223 | 169 | ||
446 | 224 | # Clean out the root dir and make sure the dirs we want are in place | 170 | workdir = None |
447 | 225 | root_dir = os.path.expanduser("~/rpmbuild") | 171 | try: |
448 | 226 | if os.path.isdir(root_dir): | 172 | workdir = tempfile.mkdtemp(prefix='rpmbuild') |
449 | 227 | shutil.rmtree(root_dir) | 173 | os.environ['HOME'] = workdir |
450 | 228 | 174 | topdir = os.path.join(workdir, 'rpmbuild') | |
451 | 229 | arc_dir = util.abs_join(root_dir, 'SOURCES') | 175 | build_dirs = [os.path.join(topdir, dir) |
452 | 230 | build_dirs = [root_dir, arc_dir] | 176 | for dir in RPM_BUILD_SUBDIRS] |
453 | 231 | for dname in RPM_BUILD_SUBDIRS: | 177 | util.ensure_dirs(build_dirs) |
454 | 232 | build_dirs.append(util.abs_join(root_dir, dname)) | 178 | |
455 | 233 | build_dirs.sort() | 179 | # Archive the code |
456 | 234 | util.ensure_dirs(build_dirs) | 180 | cmd = [util.abs_join(find_root(), 'tools', 'make-tarball')] |
457 | 235 | 181 | (stdout, _stderr) = util.subp(cmd) | |
458 | 236 | # Archive the code | 182 | archive_fn = stdout.strip() |
459 | 237 | cmd = [util.abs_join(find_root(), 'tools', 'make-tarball')] | 183 | print "Archived source as %s" % archive_fn |
460 | 238 | (stdout, _stderr) = util.subp(cmd) | 184 | real_archive_fn = os.path.join(topdir, 'SOURCES', |
461 | 239 | archive_fn = stdout.strip() | 185 | os.path.basename(archive_fn)) |
462 | 240 | real_archive_fn = os.path.join(arc_dir, os.path.basename(archive_fn)) | 186 | shutil.move(archive_fn, real_archive_fn) |
463 | 241 | shutil.move(archive_fn, real_archive_fn) | 187 | print("Archived the code in %r" % (real_archive_fn)) |
464 | 242 | print("Archived the code in %r" % (real_archive_fn)) | 188 | |
465 | 243 | 189 | # Form the spec file to be used | |
466 | 244 | # Form the spec file to be used | 190 | tmpl_fn = util.abs_join(find_root(), 'packages', |
467 | 245 | tmpl_fn = util.abs_join(find_root(), 'packages', | 191 | args.distro, 'cloud-init.spec.in') |
468 | 246 | args.distro, 'cloud-init.spec.in') | 192 | contents = generate_spec_contents(args, tmpl_fn, topdir, |
469 | 247 | contents = generate_spec_contents(args, tmpl_fn, root_dir, | 193 | os.path.basename(archive_fn)) |
470 | 248 | os.path.basename(archive_fn)) | 194 | spec_fn = util.abs_join(topdir, 'SPECS', 'cloud-init.spec') |
471 | 249 | spec_fn = util.abs_join(root_dir, 'cloud-init.spec') | 195 | util.write_file(spec_fn, contents) |
472 | 250 | util.write_file(spec_fn, contents) | 196 | print("Created spec file at %r" % (spec_fn)) |
473 | 251 | print("Created spec file at %r" % (spec_fn)) | 197 | for p in args.patches: |
474 | 252 | print(contents) | 198 | util.copy(p, util.abs_join(topdir, 'SOURCES', os.path.basename(p))) |
475 | 253 | for p in args.patches: | 199 | |
476 | 254 | util.copy(p, util.abs_join(arc_dir, os.path.basename(p))) | 200 | # Now build it! |
477 | 255 | 201 | print("Running 'rpmbuild' in %r" % (topdir)) | |
478 | 256 | # Now build it! | 202 | |
479 | 257 | print("Running 'rpmbuild' in %r" % (root_dir)) | 203 | if args.srpm: |
480 | 258 | cmd = ['rpmbuild', '-ba', spec_fn] | 204 | cmd = ['rpmbuild', '-bs', '--nodeps', spec_fn] |
481 | 259 | util.subp(cmd, capture=capture) | 205 | else: |
482 | 260 | 206 | cmd = ['rpmbuild', '-ba', spec_fn] | |
483 | 261 | # Copy the items built to our local dir | 207 | |
484 | 262 | globs = [] | 208 | util.subp(cmd, capture=capture) |
485 | 263 | globs.extend(glob.glob("%s/*.rpm" % | 209 | |
486 | 264 | (util.abs_join(root_dir, 'RPMS', 'noarch')))) | 210 | # Copy the items built to our local dir |
487 | 265 | globs.extend(glob.glob("%s/*.rpm" % | 211 | globs = [] |
488 | 266 | (util.abs_join(root_dir, 'RPMS', 'x86_64')))) | 212 | globs.extend(glob.glob("%s/*.rpm" % |
489 | 267 | globs.extend(glob.glob("%s/*.rpm" % | 213 | (util.abs_join(topdir, 'RPMS', 'noarch')))) |
490 | 268 | (util.abs_join(root_dir, 'RPMS')))) | 214 | globs.extend(glob.glob("%s/*.rpm" % |
491 | 269 | globs.extend(glob.glob("%s/*.rpm" % | 215 | (util.abs_join(topdir, 'RPMS', 'x86_64')))) |
492 | 270 | (util.abs_join(root_dir, 'SRPMS')))) | 216 | globs.extend(glob.glob("%s/*.rpm" % |
493 | 271 | for rpm_fn in globs: | 217 | (util.abs_join(topdir, 'RPMS')))) |
494 | 272 | tgt_fn = util.abs_join(os.getcwd(), os.path.basename(rpm_fn)) | 218 | globs.extend(glob.glob("%s/*.rpm" % |
495 | 273 | shutil.move(rpm_fn, tgt_fn) | 219 | (util.abs_join(topdir, 'SRPMS')))) |
496 | 274 | print("Wrote out %s package %r" % (args.distro, tgt_fn)) | 220 | for rpm_fn in globs: |
497 | 221 | tgt_fn = util.abs_join(os.getcwd(), os.path.basename(rpm_fn)) | ||
498 | 222 | shutil.move(rpm_fn, tgt_fn) | ||
499 | 223 | print("Wrote out %s package %r" % (args.distro, tgt_fn)) | ||
500 | 224 | finally: | ||
501 | 225 | if workdir is not None: | ||
502 | 226 | shutil.rmtree(workdir) | ||
503 | 275 | 227 | ||
504 | 276 | return 0 | 228 | return 0 |
505 | 277 | 229 | ||
506 | diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in | |||
507 | index 254d209..c30d33c 100644 | |||
508 | --- a/packages/redhat/cloud-init.spec.in | |||
509 | +++ b/packages/redhat/cloud-init.spec.in | |||
510 | @@ -1,17 +1,13 @@ | |||
512 | 1 | ## This is a cheetah template | 1 | ## template: cheetah |
513 | 2 | %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} | 2 | %{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} |
514 | 3 | 3 | ||
515 | 4 | # See: http://www.zarb.org/~jasonc/macros.php | 4 | # See: http://www.zarb.org/~jasonc/macros.php |
516 | 5 | # Or: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets | 5 | # Or: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets |
517 | 6 | # Or: http://www.rpm.org/max-rpm/ch-rpm-inside.html | 6 | # Or: http://www.rpm.org/max-rpm/ch-rpm-inside.html |
518 | 7 | 7 | ||
519 | 8 | #for $d in $defines | ||
520 | 9 | %define ${d} | ||
521 | 10 | #end for | ||
522 | 11 | |||
523 | 12 | Name: cloud-init | 8 | Name: cloud-init |
524 | 13 | Version: ${version} | 9 | Version: ${version} |
526 | 14 | Release: ${release}${subrelease}%{?dist} | 10 | Release: 1${subrelease}%{?dist} |
527 | 15 | Summary: Cloud instance init scripts | 11 | Summary: Cloud instance init scripts |
528 | 16 | 12 | ||
529 | 17 | Group: System Environment/Base | 13 | Group: System Environment/Base |
530 | @@ -22,9 +18,9 @@ Source0: ${archive_name} | |||
531 | 22 | BuildArch: noarch | 18 | BuildArch: noarch |
532 | 23 | BuildRoot: %{_tmppath} | 19 | BuildRoot: %{_tmppath} |
533 | 24 | 20 | ||
537 | 25 | BuildRequires: python-devel | 21 | BuildRequires: python-devel |
538 | 26 | BuildRequires: python-setuptools | 22 | BuildRequires: python-setuptools |
539 | 27 | BuildRequires: python-cheetah | 23 | BuildRequires: python-cheetah |
540 | 28 | 24 | ||
541 | 29 | # System util packages needed | 25 | # System util packages needed |
542 | 30 | Requires: shadow-utils | 26 | Requires: shadow-utils |
543 | @@ -68,7 +64,7 @@ need special scripts to run during initialization to retrieve and install | |||
544 | 68 | ssh keys and to let the user run various scripts. | 64 | ssh keys and to let the user run various scripts. |
545 | 69 | 65 | ||
546 | 70 | %prep | 66 | %prep |
548 | 71 | %setup -q -n %{name}-%{version}~${release} | 67 | %setup -q -n ${source_name} |
549 | 72 | 68 | ||
550 | 73 | # Custom patches activation | 69 | # Custom patches activation |
551 | 74 | #set $size = 0 | 70 | #set $size = 0 |
552 | @@ -198,7 +194,3 @@ fi | |||
553 | 198 | 194 | ||
554 | 199 | # Python code is here... | 195 | # Python code is here... |
555 | 200 | %{python_sitelib}/* | 196 | %{python_sitelib}/* |
556 | 201 | |||
557 | 202 | %changelog | ||
558 | 203 | |||
559 | 204 | ${changelog} | ||
560 | diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in | |||
561 | index 53e6ad1..f994a0c 100644 | |||
562 | --- a/packages/suse/cloud-init.spec.in | |||
563 | +++ b/packages/suse/cloud-init.spec.in | |||
564 | @@ -1,16 +1,12 @@ | |||
566 | 1 | ## This is a cheetah template | 1 | ## template: cheetah |
567 | 2 | 2 | ||
568 | 3 | # See: http://www.zarb.org/~jasonc/macros.php | 3 | # See: http://www.zarb.org/~jasonc/macros.php |
569 | 4 | # Or: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets | 4 | # Or: http://fedoraproject.org/wiki/Packaging:ScriptletSnippets |
570 | 5 | # Or: http://www.rpm.org/max-rpm/ch-rpm-inside.html | 5 | # Or: http://www.rpm.org/max-rpm/ch-rpm-inside.html |
571 | 6 | 6 | ||
572 | 7 | #for $d in $defines | ||
573 | 8 | %define ${d} | ||
574 | 9 | #end for | ||
575 | 10 | |||
576 | 11 | Name: cloud-init | 7 | Name: cloud-init |
577 | 12 | Version: ${version} | 8 | Version: ${version} |
579 | 13 | Release: ${release}${subrelease}%{?dist} | 9 | Release: 1${subrelease}%{?dist} |
580 | 14 | Summary: Cloud instance init scripts | 10 | Summary: Cloud instance init scripts |
581 | 15 | 11 | ||
582 | 16 | Group: System/Management | 12 | Group: System/Management |
583 | @@ -63,7 +59,7 @@ need special scripts to run during initialization to retrieve and install | |||
584 | 63 | ssh keys and to let the user run various scripts. | 59 | ssh keys and to let the user run various scripts. |
585 | 64 | 60 | ||
586 | 65 | %prep | 61 | %prep |
588 | 66 | %setup -q -n %{name}-%{version}~${release} | 62 | %setup -q -n ${source_name} |
589 | 67 | 63 | ||
590 | 68 | # Custom patches activation | 64 | # Custom patches activation |
591 | 69 | #set $size = 0 | 65 | #set $size = 0 |
592 | @@ -157,7 +153,3 @@ mkdir -p %{buildroot}/var/lib/cloud | |||
593 | 157 | %{python_sitelib}/* | 153 | %{python_sitelib}/* |
594 | 158 | 154 | ||
595 | 159 | /var/lib/cloud | 155 | /var/lib/cloud |
596 | 160 | |||
597 | 161 | %changelog | ||
598 | 162 | |||
599 | 163 | ${changelog} | ||
600 | diff --git a/tools/make-dist-tarball b/tools/make-dist-tarball | |||
601 | 164 | deleted file mode 100755 | 156 | deleted file mode 100755 |
602 | index 5b07851..0000000 | |||
603 | --- a/tools/make-dist-tarball | |||
604 | +++ /dev/null | |||
605 | @@ -1,21 +0,0 @@ | |||
606 | 1 | #!/bin/sh | ||
607 | 2 | |||
608 | 3 | Usage() { | ||
609 | 4 | cat <<EOF | ||
610 | 5 | Usage: ${0##*/} version | ||
611 | 6 | make a tarball of 'version' | ||
612 | 7 | must be in a bzr directory, and 'version' must be a tag | ||
613 | 8 | |||
614 | 9 | EOF | ||
615 | 10 | } | ||
616 | 11 | |||
617 | 12 | topdir="$PWD" | ||
618 | 13 | tag="$1" | ||
619 | 14 | |||
620 | 15 | [ -n "$tag" ] || { Usage 1>&2 ; exit 1; } | ||
621 | 16 | |||
622 | 17 | out="${topdir}/cloud-init-${tag}.tar.gz" | ||
623 | 18 | |||
624 | 19 | bzr export --format=tgz --root="cloud-init-$tag" \ | ||
625 | 20 | "--revision=tag:${tag}" "$out" "$topdir" && | ||
626 | 21 | echo "Wrote ${out}" | ||
627 | diff --git a/tools/make-tarball b/tools/make-tarball | |||
628 | index b703915..25d6f93 100755 | |||
629 | --- a/tools/make-tarball | |||
630 | +++ b/tools/make-tarball | |||
631 | @@ -1,39 +1,31 @@ | |||
632 | 1 | #!/bin/sh | 1 | #!/bin/sh |
633 | 2 | set -e | 2 | set -e |
634 | 3 | 3 | ||
656 | 4 | find_root() { | 4 | rev=${1:-HEAD} |
657 | 5 | local topd | 5 | if [ "$rev" = HEAD ]; then |
658 | 6 | if [ -z "${CLOUD_INIT_TOP_D}" ]; then | 6 | revname=$(git describe --tags) |
638 | 7 | topd=$(cd "$(dirname "${0}")" && cd .. && pwd) | ||
639 | 8 | else | ||
640 | 9 | topd=$(cd "${CLOUD_INIT_TOP_D}" && pwd) | ||
641 | 10 | fi | ||
642 | 11 | [ $? -eq 0 -a -f "${topd}/setup.py" ] || return | ||
643 | 12 | ROOT_DIR="$topd" | ||
644 | 13 | } | ||
645 | 14 | |||
646 | 15 | if ! find_root; then | ||
647 | 16 | echo "Unable to locate 'setup.py' file that should" \ | ||
648 | 17 | "exist in the cloud-init root directory." 1>&2 | ||
649 | 18 | exit 1; | ||
650 | 19 | fi | ||
651 | 20 | |||
652 | 21 | REVNO=$(bzr revno "$ROOT_DIR") | ||
653 | 22 | |||
654 | 23 | if [ ! -z "$1" ]; then | ||
655 | 24 | ARCHIVE_FN="$1" | ||
659 | 25 | else | 7 | else |
662 | 26 | VERSION=$("$ROOT_DIR/tools/read-version") | 8 | revname="$rev" |
661 | 27 | ARCHIVE_FN="$PWD/cloud-init-$VERSION~bzr$REVNO.tar.gz" | ||
663 | 28 | fi | 9 | fi |
664 | 29 | 10 | ||
668 | 30 | export_uncommitted="" | 11 | archive_base="cloud-init-$revname" |
669 | 31 | if [ "${UNCOMMITTED:-0}" != "0" ]; then | 12 | |
670 | 32 | export_uncommitted="--uncommitted" | 13 | # when building an archiving from HEAD, ensure that there aren't any |
671 | 14 | # uncomitted changes in the working directory (because these would not | ||
672 | 15 | # end up in the archive). | ||
673 | 16 | if [ "$rev" = HEAD ] && ! git diff-index --quiet HEAD --; then | ||
674 | 17 | if [ -z "$SKIP_UNCOMITTED_CHANGES_CHECK" ]; then | ||
675 | 18 | echo "ERROR: There are uncommitted changes in your working directory." >&2 | ||
676 | 19 | exit 1 | ||
677 | 20 | else | ||
678 | 21 | echo "WARNING: There are uncommitted changes in your working directory." >&2 | ||
679 | 22 | echo " This changes will not be included in the archive." >&2 | ||
680 | 23 | fi | ||
681 | 33 | fi | 24 | fi |
682 | 34 | 25 | ||
686 | 35 | bzr export ${export_uncommitted} \ | 26 | git archive \ |
687 | 36 | --format=tgz --root="cloud-init-$VERSION~bzr$REVNO" \ | 27 | --format=tar \ |
688 | 37 | "--revision=${REVNO}" "${ARCHIVE_FN}" "$ROOT_DIR" | 28 | --prefix "$archive_base/" $rev > "$archive_base.tar" |
689 | 29 | gzip -f9 ${archive_base}.tar | ||
690 | 38 | 30 | ||
692 | 39 | echo "$ARCHIVE_FN" | 31 | echo ${archive_base}.tar.gz |
693 | diff --git a/tools/read-dependencies b/tools/read-dependencies | |||
694 | index 6a6f3e1..c8a5d23 100755 | |||
695 | --- a/tools/read-dependencies | |||
696 | +++ b/tools/read-dependencies | |||
697 | @@ -1,13 +1,21 @@ | |||
698 | 1 | #!/usr/bin/env python | 1 | #!/usr/bin/env python |
699 | 2 | 2 | ||
700 | 3 | # You might be tempted to rewrite this as a shell script, but you | ||
701 | 4 | # would be surprised to discover that things like 'egrep' or 'sed' may | ||
702 | 5 | # differ between Linux and *BSD. | ||
703 | 6 | |||
704 | 3 | import os | 7 | import os |
705 | 4 | import re | 8 | import re |
706 | 5 | import sys | 9 | import sys |
707 | 10 | import subprocess | ||
708 | 6 | 11 | ||
709 | 7 | if 'CLOUD_INIT_TOP_D' in os.environ: | 12 | if 'CLOUD_INIT_TOP_D' in os.environ: |
710 | 8 | topd = os.path.realpath(os.environ.get('CLOUD_INIT_TOP_D')) | 13 | topd = os.path.realpath(os.environ.get('CLOUD_INIT_TOP_D')) |
711 | 9 | else: | 14 | else: |
713 | 10 | topd = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) | 15 | p = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], |
714 | 16 | stdout=subprocess.PIPE) | ||
715 | 17 | out, err = p.communicate() | ||
716 | 18 | topd = out.splitlines()[0] | ||
717 | 11 | 19 | ||
718 | 12 | for fname in ("setup.py", "requirements.txt"): | 20 | for fname in ("setup.py", "requirements.txt"): |
719 | 13 | if not os.path.isfile(os.path.join(topd, fname)): | 21 | if not os.path.isfile(os.path.join(topd, fname)): |
720 | @@ -16,14 +24,21 @@ for fname in ("setup.py", "requirements.txt"): | |||
721 | 16 | sys.exit(1) | 24 | sys.exit(1) |
722 | 17 | 25 | ||
723 | 18 | if len(sys.argv) > 1: | 26 | if len(sys.argv) > 1: |
725 | 19 | reqfile = sys.argv[1] | 27 | reqfile = sys.argv[1] |
726 | 20 | else: | 28 | else: |
729 | 21 | reqfile = "requirements.txt" | 29 | reqfile = "requirements.txt" |
730 | 22 | 30 | ||
731 | 23 | with open(os.path.join(topd, reqfile), "r") as fp: | 31 | with open(os.path.join(topd, reqfile), "r") as fp: |
732 | 24 | for line in fp: | 32 | for line in fp: |
734 | 25 | if not line.strip() or line.startswith("#"): | 33 | line = line.strip() |
735 | 34 | if not line or line.startswith("#"): | ||
736 | 26 | continue | 35 | continue |
738 | 27 | sys.stdout.write(re.split("[>=.<]*", line)[0].strip() + "\n") | 36 | |
739 | 37 | # remove pip-style markers | ||
740 | 38 | dep = line.split(';')[0] | ||
741 | 39 | |||
742 | 40 | # remove version requirements | ||
743 | 41 | dep = re.split("[>=.<]*", dep)[0].strip() | ||
744 | 42 | print dep | ||
745 | 28 | 43 | ||
746 | 29 | sys.exit(0) | 44 | sys.exit(0) |