3 ##############################################################################
4 # Copyright (c) 2016 Daniel Farrell and Others. All rights reserved.
6 # This program and the accompanying materials are made available under the
7 # terms of the Eclipse Public License v1.0 which accompanies this distribution,
8 # and is available at http://www.eclipse.org/legal/epl-v10.html
9 ##############################################################################
16 from urllib2 import urlopen
19 from bs4 import BeautifulSoup
21 from requests.exceptions import HTTPError
24 sys.stderr.write("We recommend using our included Vagrant env.\n")
25 sys.stderr.write("Else, do `pip install -r requirements.txt` in a venv.\n")
29 def extract_version(url):
30 """Determine ODL version information from the ODL tarball build URL
32 :arg str url: URL of the ODL tarball build for building RPMs
35 if "autorelease" in url:
36 # Autorelease URL does not include a date and hence date extraction
37 # logic is needed for RPM versioning.
39 # https://wiki.opendaylight.org/view/Integration/Packaging/Versioning
40 # Substitute the part of the build URL not required with empty string
41 date_url = re.sub('distribution-karaf-.*\.tar\.gz$', '', url)
42 # Set date_url as an environment variable for it to be used in
44 os.environ["date_url"] = date_url
45 # Extract ODL artifact's date by scraping data from the build URL
46 odl_date = subprocess.Popen(
47 "curl -s $date_url | grep tar.gz -A1 | tail -n1 |"
48 "sed \"s/<td>//g\" | sed \"s/\\n//g\" | awk '{print $3,$2,$6}' ",
49 shell=True, stdout=subprocess.PIPE,
50 stdin=subprocess.PIPE).stdout.read().rstrip().strip("</td>")
51 date = datetime.datetime.strptime(odl_date, "%d %b %Y").strftime(
53 # Search the ODL autorelease build URL to match the Build ID that
54 # follows "autorelease-". eg:
55 # https://nexus.opendaylight.org/content/repositories/autorelease-1533/
56 # org/opendaylight/integration/distribution-karaf/0.4.4-Beryllium-SR4/
58 build_id = re.search(r'\/(autorelease)-([0-9]+)\/', url).group(2)
59 pkg_version = "0.1." + date + "rel" + build_id
60 elif "snapshot" in url:
61 # Search the ODL snapshot build URL to match the date and the Build ID
62 # that are between "distribution-karaf" and ".tar.gz".
63 # eg: https://nexus.opendaylight.org/content/repositories/
64 # opendaylight.snapshot/org/opendaylight/integration/
65 # distribution-karaf/0.6.0-SNAPSHOT/
66 # distribution-karaf-0.6.0-20161201.031047-2242.tar.gz
70 r'\/(distribution-karaf)-'
71 r'([0-9]\.[0-9]\.[0-9])-([0-9]+)\.([0-9]+)-([0-9]+)\.(tar\.gz)',
73 pkg_version = "0.1." + odl_rpm.group(3) + "snap" + odl_rpm.group(5)
74 elif "public" or "opendaylight.release" in url:
77 raise ValueError("Unrecognized URL {}".format(url))
80 # Search the ODL build URL to match 0.major.minor-codename-SR and extract
81 # version information. eg: release:
82 # https://nexus.opendaylight.org/content/repositories/public/org/
83 # opendaylight/integration/distribution-karaf/0.3.3-Lithium-SR3/
84 # distribution-karaf-0.3.3-Lithium-SR3.tar.gz
85 # match: 0.3.3-Lithium-SR3
86 odl_version = re.search(r'\/(\d)\.(\d)\.(\d).(.*)\/', url)
87 version["version_major"] = odl_version.group(2)
88 version["version_minor"] = odl_version.group(3)
89 version["version_patch"] = "0"
90 version["pkg_version"] = pkg_version
91 version["codename"] = odl_version.group(4)
95 def get_snap_url(version_major, version_minor):
96 """Fetches tarball url for snapshot releases using version information
98 :arg str version_major: Major version for snapshot build
99 :arg str version_minor: Minor version for snapshot build(optional)
100 :return arg snapshot_url: URL of the snapshot release
102 parent_dir = "https://nexus.opendaylight.org/content/repositories/" \
103 "opendaylight.snapshot/org/opendaylight/integration/"\
104 "distribution-karaf/"
106 # If the minor verison is given, get the sub-directory directly
107 # else, find the latest sub-directory
111 sub_dir = '0.' + version_major + '.' + version_minor + '-SNAPSHOT/'
112 snapshot_dir = parent_dir + sub_dir
114 subdir_url = urlopen(parent_dir)
115 content = subdir_url.read().decode('utf-8')
116 all_dirs = BeautifulSoup(content, 'html.parser')
118 # Loops through all the sub-directories present and stores the
119 # latest sub directory as sub-directories are already sorted
120 # in early to late order.
121 for tag in all_dirs.find_all('a', href=True):
122 # Checks if the sub-directory name is of the form
123 # '0.<major_version>.<minor_version>-SNAPSHOT'.
124 dir = re.search(r'\/(\d)\.(\d)\.(\d).(.*)\/', tag['href'])
125 # If the major version matches the argument provided
126 # store the minor version, else ignore.
128 if dir.group(2) == version_major:
129 snapshot_dir = tag['href']
130 version_minor = dir.group(3)
133 req = requests.get(snapshot_dir)
134 req.raise_for_status()
136 print "Could not find the snapshot directory"
138 urlpath = urlopen(snapshot_dir)
139 content = urlpath.read().decode('utf-8')
140 html_content = BeautifulSoup(content, 'html.parser')
141 # Loops through all the files present in `snapshot_dir`
142 # and stores the url of latest tarball because files are
143 # already sorted in early to late order.
144 for tag in html_content.find_all('a', href=True):
145 if tag['href'].endswith('tar.gz'):
146 snapshot_url = tag['href']
150 def get_sysd_commit():
151 """Get latest Int/Pack repo commit hash"""
153 int_pack_repo = "https://github.com/opendaylight/integration-packaging.git"
154 # Get the commit hash at the tip of the master branch
155 args_git = ['git', 'ls-remote', int_pack_repo, "HEAD"]
156 args_awk = ['awk', '{print $1}']
157 references = subprocess.Popen(args_git, stdout=subprocess.PIPE,
159 sysd_commit = subprocess.check_output(args_awk, stdin=references.stdout,
165 def get_java_version(version_major):
166 """Get the java_version dependency for ODL builds
168 :arg str version_major: OpenDaylight major version number
169 :return int java_version: Java version required by given ODL version
171 if version_major < 5:
178 def get_changelog_date(pkg_type):
179 """Get the changelog datetime formatted for the given package type
181 :arg str pkg_type: Type of datetime formatting (rpm, deb)
182 :return int changelog_date: Date or datetime formatted for given pkg_type
184 if pkg_type == "rpm":
185 # RPMs require a date of the format "Day Month Date Year". For example:
187 return datetime.date.today().strftime("%a %b %d %Y")
188 elif pkg_type == "deb":
189 # Debs require both a date and time.
190 # Date must be of the format "Day, Date Month Year". For example:
192 date = datetime.date.today().strftime("%a, %d %b %Y")
193 # Time must be of the format "HH:MM:SS +HHMM". For example:
195 time = datetime.datetime.now(tzlocal.get_localzone()).\
196 strftime("%H:%M:%S %z")
197 return "{} {}".format(date, time)
199 raise ValueError("Unknown package type: {}".format(pkg_type))