Bazel support for ONOS applications and OAR files
Change-Id: Ic938dded82a68aa75d5f5df18363f3127a36d1ef
diff --git a/tools/build/bazel/onos_app.bzl b/tools/build/bazel/onos_app.bzl
new file mode 100644
index 0000000..aec244d
--- /dev/null
+++ b/tools/build/bazel/onos_app.bzl
@@ -0,0 +1,304 @@
+"""
+ Copyright 2018-present Open Networking Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+"""
+
+load("//tools/build/bazel:generate_workspace.bzl", "maven_coordinates")
+load(
+ "//tools/build/bazel:variables.bzl",
+ "APP_PREFIX",
+ "DEFAULT_APP_CATEGORY",
+ "ONOS_ARTIFACT_BASE",
+ "ONOS_GROUP_ID",
+ "ONOS_ORIGIN",
+ "ONOS_VERSION",
+)
+
+# Implementation of the rule to build an ONOS application OAR file
+def _onos_oar_impl(ctx):
+ app_xml_file = ctx.attr.app_xml.files.to_list()[0]
+ feature_xml_file = ctx.attr.feature_xml.files.to_list()[0]
+ feature_xml_coords = ctx.attr.feature_xml_coords
+ jar_file = ctx.attr.jar_file.files.to_list()[0]
+ arguments = [
+ ctx.outputs.app_oar.path,
+ feature_xml_file.path,
+ feature_xml_coords,
+ app_xml_file.path,
+ "NONE",
+ jar_file.path,
+ feature_xml_coords,
+ ]
+
+ ctx.actions.run(
+ inputs = [app_xml_file, feature_xml_file, jar_file],
+ outputs = [ctx.outputs.app_oar],
+ arguments = arguments,
+ progress_message = "Running oar file generator: %s" % ctx.attr.name,
+ executable = ctx.executable._onos_app_oar_exe,
+ )
+
+# Implementation of the rule to build an app.xml or features file for an application
+def _onos_app_xml_impl(ctx):
+ output = ctx.outputs.app_xml.path
+ app_name = ctx.attr.app_name
+ origin = ctx.attr.origin
+ version = ctx.attr.version
+ title = ctx.attr.title
+ category = ctx.attr.category
+ url = ctx.attr.url
+ mode = ctx.attr.mode
+ feature_coords = ctx.attr.feature_coords
+ description = ctx.attr.description
+ apps = ctx.attr.apps
+ included_bundles = ctx.attr.included_bundles
+ excluded_bundles = ctx.attr.excluded_bundles
+ required_features = ctx.attr.required_features
+ security = ctx.attr.security
+ artifacts_args = []
+
+ # call the app.xml generator
+ arguments = [
+ "-O",
+ output,
+ "-n",
+ feature_coords,
+ "-a",
+ app_name,
+ "-o",
+ origin,
+ "-c",
+ category,
+ "-u",
+ url,
+ "-v",
+ version,
+ "-t",
+ title,
+ "-D",
+ description,
+ mode,
+ ]
+
+ for bundle in included_bundles:
+ arguments += ["-b", maven_coordinates(bundle.label)]
+ for bundle in excluded_bundles:
+ arguments += ["-e", maven_coordinates(bundle.label)]
+ for feature in required_features:
+ arguments += ["-f", feature]
+
+ if security != "":
+ arguments += ["-s", security]
+
+ ctx.actions.run(
+ inputs = [],
+ outputs = [ctx.outputs.app_xml],
+ arguments = arguments,
+ progress_message = "Running app xml generator: %s" % ctx.attr.name,
+ executable = ctx.executable._onos_app_writer_exe,
+ )
+
+# OAR file rule
+_onos_oar = rule(
+ attrs = {
+ "deps": attr.label_list(),
+ "version": attr.string(),
+ "package_name_root": attr.string(),
+ "source": attr.label(),
+ "app_xml": attr.label(),
+ "feature_xml": attr.label(),
+ "feature_xml_coords": attr.string(),
+ "jar_file": attr.label(),
+ "_onos_app_oar_exe": attr.label(
+ executable = True,
+ cfg = "host",
+ allow_files = True,
+ default = Label("//tools/build/bazel:onos_app_oar"),
+ ),
+ },
+ outputs = {
+ "app_oar": "%{name}.oar",
+ },
+ implementation = _onos_oar_impl,
+)
+
+# app.xml rule
+_onos_app_xml = rule(
+ attrs = {
+ "app_name": attr.string(),
+ "origin": attr.string(),
+ "version": attr.string(),
+ "title": attr.string(),
+ "category": attr.string(),
+ "url": attr.string(),
+ "feature_coords": attr.string(),
+ "description": attr.string(),
+ "apps": attr.label_list(),
+ "included_bundles": attr.label_list(),
+ "excluded_bundles": attr.label_list(),
+ "required_features": attr.string_list(),
+ "security": attr.string(),
+ "mode": attr.string(),
+ "_onos_app_writer_exe": attr.label(
+ executable = True,
+ cfg = "host",
+ allow_files = True,
+ default = Label("//tools/build/bazel:onos_app_writer"),
+ ),
+ },
+ outputs = {
+ "app_xml": "%{name}.xml",
+ },
+ implementation = _onos_app_xml_impl,
+)
+
+# feature.xml rule
+_onos_feature_xml = rule(
+ attrs = {
+ "app_name": attr.string(),
+ "origin": attr.string(),
+ "version": attr.string(),
+ "title": attr.string(),
+ "category": attr.string(),
+ "url": attr.string(),
+ "feature_coords": attr.string(),
+ "description": attr.string(),
+ "apps": attr.label_list(),
+ "included_bundles": attr.label_list(),
+ "excluded_bundles": attr.label_list(),
+ "required_features": attr.string_list(),
+ "security": attr.string(),
+ "mode": attr.string(),
+ "_onos_app_writer_exe": attr.label(
+ executable = True,
+ cfg = "host",
+ allow_files = True,
+ default = Label("//tools/build/bazel:onos_app_writer"),
+ ),
+ },
+ outputs = {
+ "app_xml": "%{name}.xml",
+ },
+ implementation = _onos_app_xml_impl,
+)
+
+def _basename(path):
+ paths = path.split("/")
+ return paths[len(paths) - 1]
+
+def _get_base_path():
+ return native.package_name()
+
+def _get_name():
+ base_path = _get_base_path()
+ return ONOS_ARTIFACT_BASE + base_path.replace("/", "-")
+
+def _get_app_name():
+ base_path = _get_base_path()
+ return APP_PREFIX + _basename(base_path)
+
+def _local_label(name, suffix):
+ base_label_name = "//" + native.package_name() + ":"
+ return base_label_name + name + suffix
+
+# Rule to build an ONOS application OAR file
+def onos_app(
+ app_name = None,
+ name = None,
+ title = None,
+ version = ONOS_VERSION,
+ origin = ONOS_ORIGIN,
+ category = DEFAULT_APP_CATEGORY,
+ url = None,
+ description = None,
+ feature_coords = None,
+ required_features = ["onos-api"],
+ required_apps = [],
+ included_bundles = None,
+ excluded_bundles = [],
+ visibility = ["//visibility:public"],
+ security = None,
+ **kwargs):
+ if name == None:
+ name = _get_name()
+
+ if app_name == None:
+ app_name = _get_app_name()
+
+ maven_coords = "%s:%s:oar:%s" % (ONOS_GROUP_ID, name, ONOS_VERSION)
+ feature_xml_coords = "%s:%s:xml:features:%s" % (ONOS_GROUP_ID, name, ONOS_VERSION)
+
+ if title == None:
+ print("Missing title for %s" % _get_name())
+ title = _get_app_name()
+
+ if included_bundles == None:
+ target = ":" + name
+ included_bundles = [target]
+
+ # TODO - have to implement this eventually
+ #if not feature_coords and len(included_bundles) == 1:
+ # feature_coords = '$(maven_coords %s)' % included_bundles[0]
+
+ if not feature_coords:
+ feature_coords = "%s:%s:%s" % (ONOS_GROUP_ID, name, ONOS_VERSION)
+
+ # TODO - intra app dependecies
+ apps = []
+
+ # rule that generates the app.xml
+ _onos_app_xml(
+ name = name + "-app-xml",
+ app_name = app_name,
+ origin = origin,
+ version = version,
+ title = title,
+ category = category,
+ url = url,
+ feature_coords = feature_coords,
+ description = description,
+ apps = apps,
+ included_bundles = included_bundles,
+ excluded_bundles = excluded_bundles,
+ mode = "-A",
+ )
+
+ # rule that generates the features.xml
+ # TODO - rename this
+ _onos_app_xml(
+ name = name + "-feature-xml",
+ app_name = app_name,
+ origin = origin,
+ version = version,
+ title = title,
+ category = category,
+ url = url,
+ feature_coords = feature_coords,
+ description = description,
+ apps = apps,
+ included_bundles = included_bundles,
+ excluded_bundles = excluded_bundles,
+ required_features = required_features,
+ mode = "-F",
+ )
+
+ # rule to generate the OAR file based on the app.xml, features.xml, and app jar file
+ _onos_oar(
+ name = name + "-oar",
+ jar_file = Label(_local_label(name, "-osgi")),
+ app_xml = Label(_local_label(name, "-app-xml")),
+ feature_xml = Label(_local_label(name, "-feature-xml")),
+ feature_xml_coords = feature_xml_coords,
+ visibility = visibility,
+ )
diff --git a/tools/build/bazel/onos_app.py b/tools/build/bazel/onos_app.py
index ebb6bb7..87cd3f6 100755
--- a/tools/build/bazel/onos_app.py
+++ b/tools/build/bazel/onos_app.py
@@ -14,7 +14,7 @@
EXISTING_FEATURE = ' <feature>%s</feature>\n'
BUNDLE = ' <bundle>%s</bundle>\n'
FEATURE_FOOTER = ' </feature>\n'
-FEATURES_FOOTER = '</features>'
+FEATURES_FOOTER = '</features>\n'
##### Templates for app.xml
APP_HEADER = '''\
@@ -30,7 +30,7 @@
<security>
%s
</security>\n'''
-APP_FOOTER = '</app>'
+APP_FOOTER = '</app>\n'
NON_OSGI_TAG = 'NON-OSGI'
@@ -212,6 +212,9 @@
features=options.features,
**values)
+ sys.stderr.write("In onos_app.py - output is:" + options.output)
+ sys.stderr.flush()
+
if options.write_feature:
write(options.output, feature)
diff --git a/tools/build/bazel/onos_oar.py b/tools/build/bazel/onos_oar.py
index 30f70f5..4a82b62 100755
--- a/tools/build/bazel/onos_oar.py
+++ b/tools/build/bazel/onos_oar.py
@@ -9,7 +9,10 @@
for file, mvnCoords in files:
filename = file.split('/')[-1]
if mvnCoords == 'NONE':
- dest = filename
+ if 'app-xml.xml' in filename:
+ dest = 'app.xml'
+ else:
+ dest = filename
else:
parts = mvnCoords.split(':')
if len(parts) > 3:
@@ -19,7 +22,7 @@
extension = filename.split('.')[-1]
if extension == 'jar':
filename = '%s-%s.jar' % ( artifactId, version )
- elif 'features.xml' in filename:
+ elif 'feature-xml' in filename:
filename = '%s-%s-features.xml' % ( artifactId, version )
dest = 'm2/%s/%s/%s/%s' % ( groupId, artifactId, version, filename )
zip.write(file, dest)
diff --git a/tools/build/bazel/variables.bzl b/tools/build/bazel/variables.bzl
index ee80f7a..a164970 100644
--- a/tools/build/bazel/variables.bzl
+++ b/tools/build/bazel/variables.bzl
@@ -1,2 +1,6 @@
-ONOS_VERSION = "1.14.0-SNAPSHOT"
-ONOS_GROUP_ID = "org.onosproject"
+ONOS_ORIGIN = 'ONOS Community'
+ONOS_GROUP_ID = 'org.onosproject'
+ONOS_VERSION = '1.14.0-SNAPSHOT'
+DEFAULT_APP_CATEGORY = 'Utility'
+ONOS_ARTIFACT_BASE = 'onos-'
+APP_PREFIX = ONOS_GROUP_ID + '.'
\ No newline at end of file
diff --git a/tools/build_rules/prelude_bazel b/tools/build_rules/prelude_bazel
index 11451e0..8695c9a 100644
--- a/tools/build_rules/prelude_bazel
+++ b/tools/build_rules/prelude_bazel
@@ -13,5 +13,6 @@
"generated_java_libraries",
)
load("//tools/build/bazel:osgi_java_library.bzl", "osgi_jar", "osgi_jar_with_tests")
+load("//tools/build/bazel:onos_app.bzl", "onos_app")
generated_java_libraries()