2 """Build OpenDaylight's .debs using YAML build configs and Jinja2 templates."""
7 from string import Template
11 import cache.cache as cache
12 import templates.build_debianfiles as build_debfiles
17 sys.stderr.write("We recommend using our included Vagrant env.\n")
18 sys.stderr.write("Else, install the Python libs it installs.\n")
22 # Common paths used in this script
23 # This file is assumed to be in the root of the .deb build logic's dir
25 project_root = os.path.dirname(os.path.abspath(__file__))
27 # Cache directory for OpenDaylight's release tarball
28 cache_dir = os.path.join(project_root, "cache")
30 # Debian templates directory
31 templates_dir = os.path.join(project_root, "templates")
33 # Specialized opendaylight directory for each build
34 odl_dir_template = Template("opendaylight/opendaylight-$version_major.$version_minor."
35 "$version_patch-$pkg_version/")
36 odl_deb_template = Template("opendaylight/opendaylight_$version_major.$version_minor."
37 "$version_patch-${pkg_version}_all.deb")
41 """Build the .deb described by the given build description.
43 :param build: Description of a debian build, typically from build_vars.yaml
47 # Specialize a series of name templates for the given build
48 odl_dir_name = odl_dir_template.substitute(build)
49 odl_dir_path = os.path.join(templates_dir, os.pardir, odl_dir_name)
50 odl_deb = odl_deb_template.substitute(build)
52 # Call helper script to build the required debian files
53 build_debfiles.build_debfiles(build)
55 # Call a helper function to cache the artifacts required for each build
56 odl_tarball_path = cache.cache_build(build)
58 # Move ODL's tarball to the specialized OpenDaylight directory
59 shutil.copy(odl_tarball_path, odl_dir_path)
61 # Build debian package
62 os.chdir(odl_dir_path)
63 subprocess.call(["dpkg-buildpackage", "-us -uc -b",
64 odl_dir_path], shell=True)
66 # Install opendaylight's dependencies
67 control_file_path = os.path.join(odl_dir_path, "debian/control")
68 subprocess.call(["sudo mk-build-deps -i " + control_file_path], shell=True)
70 os.chdir(project_root)
72 # Copy the .debs from their output dir to the cache dir
73 shutil.copy(odl_deb, cache_dir)
76 # When run as a script, accept a set of builds and execute them
77 if __name__ == "__main__":
78 # Load .deb build variables from a YAML config file
79 build_vars_path = os.path.join(project_root, "build_vars.yaml")
80 with open(build_vars_path) as deb_var_file:
81 build_vars = yaml.load(deb_var_file)
83 # Accept the version(s) of the build(s) to perform as args
84 parser = argparse.ArgumentParser()
85 existing_build_group = parser.add_argument_group("Existing build")
86 existing_build_group.add_argument(
87 "-v", "--version", action="append", metavar="major minor patch deb",
88 nargs="*", help="Deb version(s) to build"
90 new_build_group = parser.add_argument_group("New build")
91 new_build_group.add_argument(
92 "--major", help="Major (element) version to build")
93 new_build_group.add_argument("--minor", help="Minor (SR) version to build")
94 new_build_group.add_argument("--patch", help="Patch version to build")
95 new_build_group.add_argument("--deb", help="Deb version to build")
96 new_build_group.add_argument(
97 "--sysd_commit", help="Version of ODL unitfile to package")
98 new_build_group.add_argument("--codename", help="Codename for ODL version")
99 new_build_group.add_argument(
100 "--download_url", help="Tarball to repackage into .deb")
101 new_build_group.add_argument(
102 "--java_version", help="Java dependency for the ODL release")
103 new_build_group.add_argument(
104 "--changelog_date", help="Date this .deb was defined")
105 new_build_group.add_argument(
106 "--changelog_time", help="Time this .deb was defined")
107 new_build_group.add_argument(
108 "--changelog_name", help="Name of person who defined .deb")
109 new_build_group.add_argument(
110 "--changelog_email", help="Email of person who defined .deb")
112 # Print help if no arguments are given
113 if len(sys.argv) == 1:
117 # Parse the given args
118 args = parser.parse_args()
120 # Build list of .deb builds to perform
123 # Build a list of requested versions as dicts of version components
125 version_keys = ["version_major", "version_minor", "version_patch",
127 # For each version arg, match all version components to build_vars name
128 for version in args.version:
129 versions.append(dict(zip(version_keys, version)))
131 # Find every .deb build that matches any version argument
132 # A passed version "matches" a build when the provided version
133 # components are a subset of the version components of a build. Any
134 # version components that aren't passed are simply not checked, so
135 # they can't fail the match, effectively wild-carding them.
136 for build in build_vars["builds"]:
137 for version in versions:
138 # Converts both dicts' key:value pairs to lists of tuples and
139 # checks that each tuple in the version list is present in the
141 if all(item in build.items() for item in version.items()):
144 builds.append({"version_major": args.major,
145 "version_minor": args.minor,
146 "version_patch": args.patch,
147 "pkg_version": args.deb,
148 "sysd_commit": args.sysd_commit,
149 "codename": args.codename,
150 "download_url": args.download_url,
151 "java_version": args.java_version,
152 "changelog_date": args.changelog_date,
153 "changelog_time": args.changelog_time,
154 "changelog_name": args.changelog_name,
155 "changelog_email": args.changelog_email})