LoginSignup
3
2

More than 5 years have passed since last update.

Bigtopと戯れる その1の続きです。ひたすら戯れましたが、課題が残ってしまったので続きを書くかもしれません。

目標

  • 最新版のHadoopのRPMファイルを作ること
  • 自分でパッチを当てたHadoopのRPMファイルを作ること

両方ともこの記事で達成します。

最新版のHadoopのRPMファイルを作る

2015/12/22時点のmasterだと、BigtopでインストールするHadoopのバージョンは2.7.1になる。

bigtop.bom
    'hadoop' {
      name    = 'hadoop'
      relNotes = 'Apache Hadoop'
      version { base = '2.7.1'; pkg = base; release = 1 }
      tarball { destination = "${name}-${version.base}.tar.gz"
                source      = "${name}-${version.base}-src.tar.gz" }
      url     { download_path = "/$name/common/$name-${version.base}"
                site = "${apache.APACHE_MIRROR}/${download_path}"
                archive = "${apache.APACHE_ARCHIVE}/${download_path}" }
    }

現状、Apache Hadoopの最新リリースは2.7.1なので、単にビルドするだけでHadoop 2.7.1のRPMが完成するのですが、バージョンを変更したい場合はbaseを2.7.1から変更します。例えば、Hadoop 2.6.3のRPMを作成したい場合は以下のように修正します。

bigtop.bom
    'hadoop' {
      name    = 'hadoop'
      relNotes = 'Apache Hadoop'
      version { base = '2.6.3'; pkg = base; release = 1 }
      tarball { destination = "${name}-${version.base}.tar.gz"
                source      = "${name}-${version.base}-src.tar.gz" }
      url     { download_path = "/$name/common/$name-${version.base}"
                site = "${apache.APACHE_MIRROR}/${download_path}"
                archive = "${apache.APACHE_ARCHIVE}/${download_path}" }
    }

ただし、このままgradle hadoop-rpmを実行しても、hadoop-2.6.3は既にダウンロード済だと言われて、ビルドが実行されない。ビルドするためには、dl/hadoop-2.7.1-src.tar.gzを消す必要がある。
消してから再実行すると、既にBigtopでHadoop 2.7.1のために提供されているパッチをHadoop 2.6.3に適用しようとして失敗する。

Patch #0 (patch0.diff):
patching file hadoop-common-project/hadoop-common/pom.xml
Hunk #1 FAILED at 238.
1 out of 1 hunk FAILED -- saving rejects to file hadoop-common-project/hadoop-common/pom.xml.rej

パッチを消して、buildディレクトリも消去すればよい。

$ rm bigtop-packages/src/common/hadoop/patch0.diff
$ rm -rf build
$ gradle hadoop-rpm
(snip)
Wrote: /home/azureuser/git/bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-hdfs-fuse-2.6.3-1.el6.x86_64.rpm
Wrote: /home/azureuser/git/bigtop/build/hadoop/rpm/RPMS/x86_64/hadoop-debuginfo-2.6.3-1.el6.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.C4ymKd
+ umask 022
+ cd /home/azureuser/git/bigtop/build/hadoop/rpm//BUILD
+ cd hadoop-2.6.3-src
+ /bin/rm -rf /home/azureuser/git/bigtop/build/hadoop/rpm/BUILDROOT/hadoop-2.6.3-1.el6.x86_64
+ exit 0
Executing(--clean): /bin/sh -e /var/tmp/rpm-tmp.C0a7C8
+ umask 022
+ cd /home/azureuser/git/bigtop/build/hadoop/rpm//BUILD
+ rm -rf hadoop-2.6.3-src
+ exit 0

BUILD SUCCESSFUL

Total time: 25 mins 41.469 secs

自分でパッチを当てたHadoopのRPMファイルを作る

Hadoop 2.6.3にいくつかパッチを当てたHadoopのRPMを作ってみます。

パッチ適用のために新規ブランチを作成

$ git clone https://github.com/apache/hadoop.git
$ cd hadoop
$ git checkout release-2.6.3
HEAD is now at cc865b4... Set release date for 2.6.3
$ git checkout -b myrelease-2.6.3

パッチを適用する

以下のパッチを適用してみる。

$ wget https://issues.apache.org/jira/secure/attachment/12667105/HADOOP-8989.patch
$ git apply -p0 HADOOP-8989.patch --whitespace=fix
../patch/HADOOP-8989.patch:966: trailing whitespace.
   * 
../patch/HADOOP-8989.patch:1132: trailing whitespace.
   * 
../patch/HADOOP-8989.patch:1142: trailing whitespace.
   * 
../patch/HADOOP-8989.patch:1183: trailing whitespace.
   * 
../patch/HADOOP-8989.patch:2549: trailing whitespace.

warning: squelched 7 whitespace errors
warning: 12 lines applied after fixing whitespace errors.

# 良い感じにコミットする
$ git add -A
$ git commit -a
$ git log | head -5
commit 345e583734f3bce0b1d8d8a64060c8a6a139e37e
Author: Akira Ajisaka <aajisaka@apache.org>
Date:   Tue Dec 22 15:47:49 2015 +0900

    HADOOP-8989 hadoop fs -find feature.

$ wget https://issues.apache.org/jira/secure/attachment/12681196/HADOOP-7984-branch-2.3.patch
$ git apply -p0 HADOOP-7984-branch-2.3.patch
$ git commit -a
$ git log | head -5
commit f965e1501720b3b218bd448b0da0d908f46d4572
Author: Akira Ajisaka <aajisaka@apache.org>
Date:   Tue Dec 22 16:20:21 2015 +0900

    HADOOP-7984. Add hadoop --loglevel option to change log level.

ちなみに、パッチによってgit applyするときに-p0--whitespace=fix--binaryが必要かどうかが異なる。(あまり統一感がない)

Bigtop用のパッチを作る

git format-patchコマンドを使うとパッチが生成される。

$ git format-patch -p release-2.6.3
0001-HADOOP-8989-hadoop-fs-find-feature.patch
0002-HADOOP-7984.-Add-hadoop-loglevel-option-to-change-lo.patch

ただし、Bigtopでパッチを適用するには、これらをpatch*.diffにrenameしてpatch -p1コマンドで当てられるようにしないといけない。だがしかし、HADOOP-7984のパッチがpatchコマンドで当てられない(CR/LF問題)。この問題が発生するたびに手でパッチの中身をいじるのは、とてもつらい。

パッチを諦めたい

そもそも、ソースコードをパッチ適用済のものに差し替えればよいのではないか!

  • source tarballの作成
$ mvn package -Psrc -Dtar -DskipTests
(snip)
$ ls -l hadoop-dist/target/hadoop-2.6.3-src.tar.gz 
-rw-r--r--  1 aajisaka  staff  45689815 Dec 22 18:19 hadoop-dist/target/hadoop-2.6.3-src.tar.gz

以下の手順でソースコードを差し替えてRPMを作成できました。

  1. dl/hadoop-2.6.3.tar.gzを差し替え
  2. build/を削除
  3. gradle hadoop-rpm

RPMのバージョンを変えたい

先ほどの方法で自作RPMは完成するのですが、バージョンが同一だとupdateができません。バージョンを上げてみましょう。まずは、specファイルを確認します。

bigtop-packages/src/rpm/hadoop/SPECS/hadoop.spec
(snip)
Name: %{hadoop_name}
Version: %{hadoop_version}
Release: %{hadoop_release}
Summary: Hadoop is a software platform for processing vast amounts of data
License: ASL 2.0
(snip)

以下、VersionとReleaseに分けて紹介します。

Versionを上げる

これは、Hadoop側でも対応する必要があります。pom.xmlを編集して、再ビルドしましょう。

$ git diff
diff --git a/pom.xml b/pom.xml
index a5b3ce0..686e384 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
   <modelVersion>4.0.0</modelVersion>
   <groupId>org.apache.hadoop</groupId>
   <artifactId>hadoop-main</artifactId>
-  <version>2.6.3</version>
+  <version>2.6.3+2.ajisaka0.1.0</version>
   <description>Apache Hadoop Main</description>
   <name>Apache Hadoop Main</name>
   <packaging>pom</packaging>

mvn package -Psrc -Dtar -DskipTestsを実行すると、いつもと違う名前のtarballが出来上がりました。

$ ls hadoop-dist/target/
antrun                  maven-archiver
hadoop-2.6.3+2.ajisaka0.1.0-src.tar.gz  test-dir
hadoop-dist-2.6.3.jar

このtarballを使ってBigtopでビルドしてみます。

  1. dl/にtarballを配置する
  2. bigtop.bomを修正する
bigtop.bom
     'hadoop' {
       name    = 'hadoop'
       relNotes = 'Apache Hadoop'
release = 1 }
       version { base = '2.6.3+2.ajisaka0.1.0'; pkg = base; release = 1 }
       tarball { destination = "${name}-${version.base}.tar.gz"
                 source      = "${name}-${version.base}-src.tar.gz" }
       url     { download_path = "/$name/common/$name-${version.base}"

これで、gradle hadoop-rpmを実行すると、なんと失敗しました。

:hadoop-download
    File /home/azureuser/git/bigtop/dl/hadoop-2.6.3+2.ajisaka0.1.0-src.tar.gz appears to be already downloaded. Exiting...
:hadoop-tar
Copy /home/azureuser/git/bigtop/dl/hadoop-2.6.3+2.ajisaka0.1.0-src.tar.gz to /home/azureuser/git/bigtop/build/hadoop/tar/hadoop-2.6.3+2.ajisaka0.1.0.tar.gz
:hadoop-srpm
error: File /home/azureuser/git/bigtop/build/hadoop/rpm/SOURCES/hadoop-2.6.3+2.ajisaka0.1.0.tar.gz: No such file or directory
:hadoop-srpm FAILED

FAILURE: Build failed with an exception.

* Where:
Script '/home/azureuser/git/bigtop/packages.gradle' line: 511

* What went wrong:
Execution failed for task ':hadoop-srpm'.
> Process 'command 'rpmbuild'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 9.564 secs

ログを見てもさっぱりわからない...

とりあえずVersionから+2を外してみると、かなり進みました。+がエスケープできてないのはBigtopのバグっぽい。CDHっぽく適用したパッチ数を+2として表してみたかったけど、何か直す必要がありそうです。

そして、エラーログ

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-site-plugin:3.3:site (default-site) on project hadoop-main: Error during page generation: Error rendering Maven report: Unable to find artifact:groupId = 'org.apache.hadoop'
[ERROR] artifactId = 'hadoop-annotations'
[ERROR] version = '2.6.3.ajisaka0.1.0': Failure to find org.apache.hadoop:hadoop-annotations:pom:2.6.3.ajisaka0.1.0 in https://repository.apache.org/content/repositories/snapshots was cached in the local repository, resolution will not be reattempted until the update interval of apache.snapshots.https has elapsed or updates are forced
[ERROR] 
[ERROR] org.apache.hadoop:hadoop-annotations:pom:2.6.3.ajisaka0.1.0

pomを用意して、専用のrepositoryに置く必要がありそうです。CDHでいうところのrepository.cloudera.comのようなところ。

今後の課題です。

Releaseを上げる

Releaseを上げるには、%{hadoop_release}をいじればよさそうです。おそらく、rpmbuildコマンドを叩くときに定義しているはずです。雑に探します。

$ find . -type f | xargs grep rpmbuild
./bigtop-packages/src/common/hue/install_hue.sh:# remove RECORD files since it contains "real" paths confusing rpmbuild
./src/site/xdoc/release-notes.xml:                  ] - Add normal rpmbuild options for make rpm
./build/hadoop/rpm/BUILD/hadoop-2.6.3-src/hadoop-common-project/hadoop-common/CHANGES.txt:    HADOOP-9611 mvn-rpmbuild against google-guice > 3.0 yields missing cglib
grep: ./build/hadoop/rpm/BUILD/hadoop-2.6.3-src/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/resources/webapps/static/dt-1.9.4/images/Sorting: No such file or directory
grep: icons.psd: No such file or directory
./packages.gradle:    def RELEASE_DIST = "rpmbuild --eval '%{?dist}' 2>/dev/null".execute().text.trim().replaceAll("'",'')
./packages.gradle:      executable 'rpmbuild'
./packages.gradle:      executable 'rpmbuild'
./packages.gradle:    def RELEASE_DIST = "rpmbuild --eval '%{?dist}' 2>/dev/null".execute().text.trim().replaceAll("'",'')
./CHANGES.txt:  - [BIGTOP-60] - Add normal rpmbuild options for make rpm

packages.gradleを読めば良さそうです。

packages.gradle
411     def command = [
412         '--define', "_topdir $PKG_BUILD_DIR/rpm/",
413         '--define', "${NAME}_base_version $BASE_VERSION",
414         '--define', "${NAME}_version ${PKG_VERSION}",
415         '--define', "${NAME}_release ${BIGTOP_BUILD_STAMP}%{?dist}",
416         '--rebuild', SRCRPM,
417     ]
418     exec {
419       workingDir BASE_DIR
420       executable 'rpmbuild'
421       args command
422     }

${BIGTOP_BUILD_STAMP}を修正すればよさそうです。設定している部分を探します。

packages.gradle
 48 config.bigtop.buildstamp = 1
 49 
 50 def bomVersions = []
 51 
 52 def final BASE_DIR = projectDir.absolutePath
 53 def final REPO_DIR = "$BASE_DIR/bigtop-repos"
 54 def final BUILD_DIR = config.bigtop.builddir
 55 def final OUTPUT_DIR = config.bigtop.outputdir
 56 def final DIST_DIR = config.bigtop.distdir
 57 def final DL_DIR = config.bigtop.dldir
 58 def final BIGTOP_BUILD_STAMP = System.getenv('BIGTOP_BUILD_STAMP') ?: config.bigtop.buildstamp

config.bigtop.buildstampを差し替えればOKです。試しに、2に設定してビルドし直してみます。すると、見事にReleaseが上がりました。

$ ls build/hadoop/rpm/RPMS/x86_64/
hadoop-2.6.3-2.el6.x86_64.rpm                         hadoop-hdfs-zkfc-2.6.3-2.el6.x86_64.rpm
hadoop-client-2.6.3-2.el6.x86_64.rpm                  hadoop-httpfs-2.6.3-2.el6.x86_64.rpm
hadoop-conf-pseudo-2.6.3-2.el6.x86_64.rpm             hadoop-libhdfs-2.6.3-2.el6.x86_64.rpm
hadoop-debuginfo-2.6.3-2.el6.x86_64.rpm               hadoop-libhdfs-devel-2.6.3-2.el6.x86_64.rpm
hadoop-doc-2.6.3-2.el6.x86_64.rpm                     hadoop-mapreduce-2.6.3-2.el6.x86_64.rpm
hadoop-hdfs-2.6.3-2.el6.x86_64.rpm                    hadoop-mapreduce-historyserver-2.6.3-2.el6.x86_64.rpm
hadoop-hdfs-datanode-2.6.3-2.el6.x86_64.rpm           hadoop-yarn-2.6.3-2.el6.x86_64.rpm
hadoop-hdfs-fuse-2.6.3-2.el6.x86_64.rpm               hadoop-yarn-nodemanager-2.6.3-2.el6.x86_64.rpm
hadoop-hdfs-journalnode-2.6.3-2.el6.x86_64.rpm        hadoop-yarn-proxyserver-2.6.3-2.el6.x86_64.rpm
hadoop-hdfs-namenode-2.6.3-2.el6.x86_64.rpm           hadoop-yarn-resourcemanager-2.6.3-2.el6.x86_64.rpm
hadoop-hdfs-secondarynamenode-2.6.3-2.el6.x86_64.rpm  hadoop-yarn-timelineserver-2.6.3-2.el6.x86_64.rpm

感想

  • Bigtopの仕組みでパッチを当てるのは大変。ソースコード自体を差し替えてしまったほうが楽。
  • ただし、差し替えるソースコード自体はgitで管理し、バージョンを変えるたびにtagを打つべき。
  • Versionをいじるのは、非常に手間がかかる
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2