1 From: Florin Dumitrascu <florin.dumitrascu@enea.com>
2 Date: Thu, 17 Mar 2016 18:15:42 +0100
3 Subject: [PATCH] ODL leveldb, leveldbjni: Enable arm64 support.
5 ODL depends on a native library (leveldb).
7 ODL Beryllium and Boron versions are still using a native x86 version
8 of this library (wrapped in leveldbjni).
10 There is no upstream version of leveldbjni supporting arm64 leveldb,
11 so we need to compile it when deploying ODL.
12 This is done when running odl-install puppet manifest.
14 For more info about this ODL limitation, see [1].
16 [1] https://bugs.opendaylight.org/show_bug.cgi?id=3973
18 [ Alexandru.Avadanii@enea.com ]
19 Remove JAVA8 changes after upstream rework.
21 Signed-off-by: Florin Dumitrascu <florin.dumitrascu@enea.com>
22 Signed-off-by: Stanislaw Kardach <stanislaw.kardach@cavium.com>
23 Signed-off-by: Alexandru Avadanii <Alexandru.Avadanii@enea.com>
25 .../modules/opendaylight/files/leveldb-arm64.patch | 35 +++++
26 .../opendaylight/files/leveldbjni-native.patch | 23 ++++
27 .../puppet/modules/opendaylight/manifests/init.pp | 8 ++
28 .../modules/opendaylight/manifests/install.pp | 12 +-
29 .../modules/opendaylight/manifests/leveldbjni.pp | 150 +++++++++++++++++++++
30 deployment_tasks.yaml | 2 +-
31 6 files changed, 227 insertions(+), 3 deletions(-)
32 create mode 100644 deployment_scripts/puppet/modules/opendaylight/files/leveldb-arm64.patch
33 create mode 100644 deployment_scripts/puppet/modules/opendaylight/files/leveldbjni-native.patch
34 create mode 100644 deployment_scripts/puppet/modules/opendaylight/manifests/leveldbjni.pp
36 diff --git a/deployment_scripts/puppet/modules/opendaylight/files/leveldb-arm64.patch b/deployment_scripts/puppet/modules/opendaylight/files/leveldb-arm64.patch
38 index 0000000..e0824ca
40 +++ b/deployment_scripts/puppet/modules/opendaylight/files/leveldb-arm64.patch
42 +diff --git a/port/atomic_pointer.h b/port/atomic_pointer.h
43 +index e17bf43..78cb6b3 100644
44 +--- a/port/atomic_pointer.h
45 ++++ b/port/atomic_pointer.h
47 + #define ARCH_CPU_X86_FAMILY 1
48 + #elif defined(__ARMEL__)
49 + #define ARCH_CPU_ARM_FAMILY 1
50 ++#elif defined(__aarch64__)
51 ++#define ARCH_CPU_ARM64_FAMILY 1
52 + #elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__)
53 + #define ARCH_CPU_PPC_FAMILY 1
55 +@@ -93,6 +95,13 @@ inline void MemoryBarrier() {
57 + #define LEVELDB_HAVE_MEMORY_BARRIER
60 ++#elif defined(ARCH_CPU_ARM64_FAMILY)
61 ++inline void MemoryBarrier() {
62 ++ asm volatile("dmb sy" : : : "memory");
64 ++#define LEVELDB_HAVE_MEMORY_BARRIER
67 + #elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__)
68 + inline void MemoryBarrier() {
69 +@@ -216,6 +225,7 @@ class AtomicPointer {
70 + #undef LEVELDB_HAVE_MEMORY_BARRIER
71 + #undef ARCH_CPU_X86_FAMILY
72 + #undef ARCH_CPU_ARM_FAMILY
73 ++#undef ARCH_CPU_ARM64_FAMILY
74 + #undef ARCH_CPU_PPC_FAMILY
77 diff --git a/deployment_scripts/puppet/modules/opendaylight/files/leveldbjni-native.patch b/deployment_scripts/puppet/modules/opendaylight/files/leveldbjni-native.patch
79 index 0000000..08a528b
81 +++ b/deployment_scripts/puppet/modules/opendaylight/files/leveldbjni-native.patch
83 +diff --git a/leveldbjni-all/pom.xml b/leveldbjni-all/pom.xml
84 +index 426f2a6..c4a2a16 100755
85 +--- a/leveldbjni-all/pom.xml
86 ++++ b/leveldbjni-all/pom.xml
89 + <groupId>org.fusesource.leveldbjni</groupId>
90 + <artifactId>leveldbjni-all</artifactId>
91 +- <version>1.8</version>
92 ++ <version>1.8-odl</version>
93 + <packaging>bundle</packaging>
95 + <name>${project.artifactId}</name>
97 + META-INF/native/osx/libleveldbjni.jnilib;osname=macosx;processor=x86,
98 + META-INF/native/osx/libleveldbjni.jnilib;osname=macosx;processor=x86-64,
99 + META-INF/native/linux32/libleveldbjni.so;osname=Linux;processor=x86,
100 +- META-INF/native/linux64/libleveldbjni.so;osname=Linux;processor=x86-64
101 ++ META-INF/native/linux64/libleveldbjni.so;osname=Linux;processor=x86-64,
102 ++ META-INF/native/linux64/libleveldbjni.so;osname=Linux;processor=aarch64
103 + </Bundle-NativeCode>
106 diff --git a/deployment_scripts/puppet/modules/opendaylight/manifests/init.pp b/deployment_scripts/puppet/modules/opendaylight/manifests/init.pp
107 index a322f70..f71bfc8 100644
108 --- a/deployment_scripts/puppet/modules/opendaylight/manifests/init.pp
109 +++ b/deployment_scripts/puppet/modules/opendaylight/manifests/init.pp
110 @@ -10,4 +10,12 @@ class opendaylight {
111 $odl_mgmt_ips = values($odl_mgmt_ips_hash)
112 $odl_nodes_names = keys($odl_mgmt_ips_hash)
113 $node_internal_address = $odl_mgmt_ips_hash["node-${node_uid}"]
115 + $arch = $::architecture ? {
116 + 'aarch64' => $::osfamily ? {
117 + 'Debian' => 'arm64',
118 + default => 'aarch64',
120 + default => $::architecture,
123 diff --git a/deployment_scripts/puppet/modules/opendaylight/manifests/install.pp b/deployment_scripts/puppet/modules/opendaylight/manifests/install.pp
124 index 924a840..d55a311 100644
125 --- a/deployment_scripts/puppet/modules/opendaylight/manifests/install.pp
126 +++ b/deployment_scripts/puppet/modules/opendaylight/manifests/install.pp
127 @@ -17,6 +17,12 @@ class opendaylight::install (
131 + if ($::osfamily == 'Debian' and $::opendaylight::arch == 'arm64') {
132 + class { 'opendaylight::leveldbjni':
133 + require => Package[$odl_package],
138 class { 'opendaylight::quagga':
139 before => Service['opendaylight']
140 @@ -35,7 +41,8 @@ class opendaylight::install (
142 debug("Set odl rest api port to ${rest_port}")
144 - file { "${conf_dir}/jetty.xml":
145 + file { 'jetty.xml':
146 + path => "${conf_dir}/jetty.xml",
149 content => template('opendaylight/jetty.xml.erb')
150 @@ -71,6 +78,7 @@ class opendaylight::install (
151 Package[$odl_package] ->
155 + File['jetty.xml'] ->
156 + Class['opendaylight::leveldbjni'] ->
157 Service['opendaylight']
159 diff --git a/deployment_scripts/puppet/modules/opendaylight/manifests/leveldbjni.pp b/deployment_scripts/puppet/modules/opendaylight/manifests/leveldbjni.pp
161 index 0000000..5125fc7
163 +++ b/deployment_scripts/puppet/modules/opendaylight/manifests/leveldbjni.pp
165 +# == Class opendaylight::leveldbjni
167 +# Manages compilation of JNI for leveldb.
169 +# It compiles the leveldbjni from sources and patches it so that it's properly
170 +# detected by maven on arm64 system.
172 +class opendaylight::leveldbjni(
173 + $target = '/opt/opendaylight',
175 + $branch = 'leveldbjni-1.8',
178 + 'Debian', 'Ubuntu': {}
180 + fail('Not supported on OS other than Debian based.')
184 + $libsnappy_dir = '/usr/lib'
185 + $leveldb_dir = "${target}/leveldb"
186 + $leveldbjni_dir = "${target}/leveldbjni"
187 + $environment = ["SNAPPY_HOME=${libsnappy_dir}", "LEVELDB_HOME=${leveldb_dir}", "LEVELDBJNI_HOME=${leveldbjni_dir}", "LIBRARY_PATH=${libsnappy_dir}", "C_INCLUDE_PATH=${libsnappy_dir}", "CPLUS_INCLUDE_PATH=${libsnappy_dir}","JAVA_HOME=/usr/lib/jvm/java-8-openjdk-${::opendaylight::arch}"]
188 + $parallel_jobs = ($processorcount + 1)/2
190 + if ! defined(Package['git']) {
192 + ensure => 'present',
195 + if ! defined(Package['build-essential']) {
196 + package { 'build-essential':
197 + ensure => 'present',
200 + if ! defined(Package['automake']) {
201 + package { 'automake':
202 + ensure => 'present',
205 + if ! defined(Package['make']) {
207 + ensure => 'present',
210 + if ! defined(Package['libsnappy-dev']) {
211 + package { 'libsnappy-dev':
212 + ensure => 'present',
215 + if ! defined(Package['patch']) {
217 + ensure => 'present',
220 + if ! defined(Package['maven']) {
222 + ensure => 'present',
225 + if ! defined(Package['openjdk-8-jdk']) {
226 + package { 'openjdk-8-jdk':
227 + ensure => 'present',
231 + exec { 'leveldb-fetch':
232 + path => ['/usr/bin'],
233 + command => "git clone git://github.com/chirino/leveldb.git ${leveldb_dir}",
234 + creates => "${leveldb_dir}/.git",
236 + require => [Package['git']],
238 + exec { 'leveldbjni-fetch':
239 + path => ['/usr/bin'],
240 + command => "git clone https://github.com/fusesource/leveldbjni.git -b ${branch} ${leveldbjni_dir}",
241 + creates => "${leveldbjni_dir}/.git",
243 + require => [Package['git']],
245 + exec { 'leveldb-merge-google':
246 + path => ['/usr/bin', '/bin'],
247 + command => "git config user.name odl && git config user.email 'o@d.l' && git remote add google https://github.com/google/leveldb.git && git fetch google master && git fetch --tags google && git merge --no-edit v1.18",
248 + unless => "git remote | grep google",
249 + cwd => $leveldb_dir,
251 + require => [Package['git']],
253 + exec { 'leveldb-patch':
254 + path => ['/usr/bin'],
255 + command => "patch -p1 < ${leveldbjni_dir}/leveldb.patch",
256 + unless => "patch -p1 -R -N --dry-run < ${leveldbjni_dir}/leveldb.patch",
257 + cwd => $leveldb_dir,
259 + require => [Package['patch']],
261 + file { "${leveldb_dir}/leveldb-arm64.patch":
263 + source => "puppet:///modules/opendaylight/leveldb-arm64.patch",
266 + exec { 'leveldb-patch-for-arm64':
267 + path => ['/usr/bin'],
268 + command => "patch -p1 < ${leveldb_dir}/leveldb-arm64.patch",
269 + unless => "patch -p1 -R -N --dry-run < ${leveldb_dir}/leveldb-arm64.patch",
270 + cwd => $leveldb_dir,
272 + require => [Package['patch']],
274 + exec { 'leveldb-build':
275 + command => "/usr/bin/make libleveldb.a -j${parallel_jobs}",
276 + creates => "${leveldb_dir}/libleveldb.a",
277 + environment => $environment,
278 + cwd => $leveldb_dir,
280 + require => [Package['git'], Package['make'], Package['build-essential']],
282 + file { "${leveldbjni_dir}/leveldbjni.patch":
284 + source => "puppet:///modules/opendaylight/leveldbjni-native.patch",
287 + exec { 'leveldbjni-patch':
288 + path => ['/usr/bin'],
289 + command => "patch -p1 < ${leveldbjni_dir}/leveldbjni.patch",
290 + unless => "patch -p1 -R -N --dry-run < ${leveldbjni_dir}/leveldbjni.patch",
291 + cwd => $leveldbjni_dir,
293 + require => [Package['patch']],
295 + exec { 'leveldbjni-build':
296 + command => "/usr/bin/mvn clean install -P download -P linux64 -P all",
297 + # Creates requires a fully qualified path which we don't have
298 + unless => "/usr/bin/test -d ~${user}/.m2/repository/org/fusesource/leveldbjni/leveldbjni-all",
299 + environment => $environment,
300 + cwd => $leveldbjni_dir,
303 + require => [Package['maven']],
305 + # Can't do this with 'file' type because we need to purge existing package
306 + # and at the same time don't perform the copy if we've already copied our
308 + exec { 'leveldbjni-copy':
310 + command => "rm -rf ${target}/system/org/fusesource/leveldbjni && cp -r ~${user}/.m2/repository/org/fusesource/leveldbjni $target/system/org/fusesource/",
311 + creates => "${target}/system/org/fusesource/leveldbjni/leveldbjni-linux64",
315 diff --git a/deployment_tasks.yaml b/deployment_tasks.yaml
316 index 3706678..841bfee 100644
317 --- a/deployment_tasks.yaml
318 +++ b/deployment_tasks.yaml
321 puppet_manifest: puppet/manifests/odl-install.pp
322 puppet_modules: puppet/modules:/etc/puppet/modules