インターネット接続環境のないAIX7.1にGitを導入し使えるようにするまで（YUMを使わずに）

# 経緯
サーバー側でソースコード管理がされておらず、いまだにhogehoge.c.20191017みたいなファイルが沢山。
これは。。。なんとかならんかね、と思ったのが発端です。しかし開発環境として使っているAIXが外にアクセスできないことが判明。`yum`やっても何も起こらなーい！  
なのでこちらの記事は力技でGitをインストールするまで、なんとか使えるようにするまでの道のりの日記みたいなもんです。
`yum`とは何？はこちらを参照[【yum入門】yumとは何か？Linuxにおけるyumとrpmの違い](https://uxmilk.jp/9715)

- 参考にさせて頂いた記事  
[インターネット接続の無い AIX で yum を利用する](https://qiita.com/shimauma999/items/9f5d3c2c51adc7933ab4)  
実はネット接続ができずとも`yum`は使えるそうです。こちらのほうが賢いやり方なのですが、記事を見つけたときはすでに遅し。。なので本記事は`yum`を使わないバージョンだと思ってもらえればよいです。  

- 必ず使うやつ  
[AIX Toolbox for Linux Applications](https://www.ibm.com/support/pages/aix-toolbox-linux-applications-downloads-alpha)  
ここからAIX用のGitやそのインストールに伴う必要なパッケージなどを取得します

**追記 (10/30/2019)**

- IBM公式ドキュメントにて、YUMレポジトリをローカルに作成するやり方が公開されていました。（英語）  
基本はこちらを参照し、やってみるのがオススメと思います。  
[Configuring YUM and creating local repositories on IBM AIX](https://developer.ibm.com/articles/configure-yum-on-aix/)

# やったこと
とりあえず本環境では、`rpm`コマンドはすでに使える状況でした。
ですのでとりあえず上記リンクからgitを落としてきて`rpm -ihv git-2.20.1-1.aix6.1.ppc.rpm`を行いました。すると、、

```
# rpm -ihv git-2.20.1-1.aix6.1.ppc.rpm
error: Failed dependencies:
        /opt/freeware/bin/perl is needed by git-2.20.1-1.ppc
        /usr/bin/bash is needed by git-2.20.1-1.ppc
        bash is needed by git-2.20.1-1.ppc
        expat >= 2.2.0 is needed by git-2.20.1-1.ppc
        gettext >= 0.19.8.1 is needed by git-2.20.1-1.ppc
        less is needed by git-2.20.1-1.ppc
        libcrypto.a(libcrypto.so.1.0.2) is needed by git-2.20.1-1.ppc
        libexpat.a(libexpat.so.1) is needed by git-2.20.1-1.ppc
        liblber.a(liblber-2.4.so.2) is needed by git-2.20.1-1.ppc
        libldap.a(libldap-2.4.so.2) is needed by git-2.20.1-1.ppc
        libssh2 >= 1.8.0-2 is needed by git-2.20.1-1.ppc
        libssh2.a(libssh2.so.1) is needed by git-2.20.1-1.ppc
        libssl.a(libssl.so.1.0.2) is needed by git-2.20.1-1.ppc
        openldap >= 2.4.45-3 is needed by git-2.20.1-1.ppc
        python >= 2.7.12 is needed by git-2.20.1-1.ppc
        rsync is needed by git-2.20.1-1.ppc
        zlib >= 1.2.11 is needed by git-2.20.1-1.ppc
```
なにこれ、、、このdependencyをひとつずつ直していくの、、？ **もうすでにここで心が折れそうになりました。**
とりあえず必要だと言われているパッケージをAIX Toolboxから落としてきて、1つずつインストールしていきました。

## AIX ToolBoxからとりあえず全部の.rpm 及び .noarch.rpmを落としてくるshやターゲットのAIXバージョンのみのファイルにしちゃうpyスクリプト(追記6/1)
- ダウンロード  
ひとつずつWebから該当ファイルを落としてくるほど面倒なことはないので、下記shを実行しておけば実行ディレクトリに`.rpm`ファイルがDLされます。（インターネットの速度によっては全部DLするのに12時間ほどかかります....）  

```sh:dl.sh
curl https://www.ibm.com/support/pages/node/883796 > a.html
cat a.html | tr "\"" "\n" | grep -e ppc.rpm -e noarch.rpm > filelist.txt
```

- ターゲットのAIXバージョン用だけのファイルにするpython   
引数にrpmファイルがごろごろあるpathを指定します。  
実は`.noarch.rpm`ファイルには複数AIXバージョンが存在するファイルが無かった。そこのロジックそもそも不要かもです  
適当に全探索してます。O(800^2) くらいなので1秒内には終わるはず...  

```py:remove.py
#coding:utf-8
import os
import sys
import glob

args = sys.argv
print(args[1])
path = args[1]
os.chdir(path)
nf = []
files = sorted(glob.glob('*.rpm'))
for f in files:
     if os.path.isfile(os.path.join(path, f)):
        #Create file list for brute force
        nf.append(f)

#Execute brute force
for f in files:
    for f2 in nf:
        #There was no duplicates of .noarch.rpm actually
        if(f[len(f)-11:] == '.noarch.rpm'):
            cutName1 = f[0:len(f)-11]
            cutName2 = f2[0:len(f2)-11]
            if((cutName1[len(cutName1)-7:] != cutName2[len(cutName2)-7:]) and
               (cutName1[0:len(cutName1)-7] == cutName2[0:len(cutName2)-7])):
                if(cutName1[len(cutName1)-7:] != '.aix7.1'):
                    print(f)
                    nf.remove(f)
                    os.remove(f)
        #for .ppc.rpm
        else:
            cutName1 = f[0:len(f)-8]
            cutName2 = f2[0:len(f2)-8]
            #i.e. compare cmake-3.16.0-1.aix6.1.ppc.rpm & cmake-3.16.0-1.aix7.1.ppc.rpm
            # 'make-3.16.0-1' is same but this portiton '.aix6.1' is different
            if((cutName1[len(cutName1)-7:] != cutName2[len(cutName2)-7:]) and
               (cutName1[0:len(cutName1)-7] == cutName2[0:len(cutName2)-7])):
               # Found duplicates, remove file its name does not contain '.aix7.1'
                if(cutName1[len(cutName1)-7:] != '.aix7.1'):
                    print(f)
                    nf.remove(f)
                    os.remove(f)

```

## OpenSSLのUpdate

```
 # rpm -ihv git-2.20.1-1.aix6.1.ppc.rpm
 error: Failed dependencies:
         /opt/freeware/bin/perl is needed by git-2.20.1-1.ppc
         gettext >= 0.19.8.1 is needed by git-2.20.1-1.ppc
         libcrypto.a(libcrypto.so.1.0.2) is needed by git-2.20.1-1.ppc
         liblber.a(liblber-2.4.so.2) is needed by git-2.20.1-1.ppc
         libldap.a(libldap-2.4.so.2) is needed by git-2.20.1-1.ppc
         libssh2 >= 1.8.0-2 is needed by git-2.20.1-1.ppc
         libssh2.a(libssh2.so.1) is needed by git-2.20.1-1.ppc
         libssl.a(libssl.so.1.0.2) is needed by git-2.20.1-1.ppc
         openldap >= 2.4.45-3 is needed by git-2.20.1-1.ppc
         python >= 2.7.12 is needed by git-2.20.1-1.ppc
```
お！結構減った！（しかしここから本番でした）
まず`libcrypto.a`とかはAIX Toolboxに無いし。。どうやったらいいの？と  

ググりまくったところ、`OpenSSL`をupdateしたらいいことがわかりました。  
現状の`OpenSSL`のバージョンを調べてみます。

```
$  lslpp -l openssl.base
  Fileset                      Level  State      Description         
  ----------------------------------------------------------------------------
Path: /usr/lib/objrepos
  openssl.base            1.0.2.1100  COMMITTED  Open Secure Socket Layer

Path: /etc/objrepos
  openssl.base            1.0.2.1100  COMMITTED  Open Secure Socket Layer
```
[ここ](https://www-01.ibm.com/marketing/iwm/iwm/web/dispatcher.do?source=aixbp)から、OpenSSLの最新をDLします。（IBMidが必要です）最新はどうやら**Level : 1.0.2.1801**のようです。
一応updateのinstructionは[ここ](https://www.ibm.com/support/pages/downloading-and-installing-or-upgrading-openssl-and-openssh)にありますが、なんかわかりにくい。
簡単にまとめると、
1. DLした.tar.Zファイルを置くディレクトリを`mkdir`して作っておく
2. FTPかSCPとかでその場所において、解凍する（tar.Zファイルだったらuncompress後にtar -xvf）
3. できればバックアップを取っておく
4. 解凍済のファイルがある場所で`smitty install_all`を行う
5. F4を押して上手く下記が読み込まれていることを確認し、F7で選択する
`openssl.base` `openssl.license` `openssl.man.en_US`
6. ACCEPT new license agreements?というところを`yes`に変更する

なんとかupdateできました。

```
# lslpp -l openssl.base    
  Fileset                      Level  State      Description         
  ----------------------------------------------------------------------------
Path: /usr/lib/objrepos
  openssl.base            1.0.2.1801  COMMITTED  Open Secure Socket Layer

Path: /etc/objrepos
  openssl.base            1.0.2.1801  COMMITTED  Open Secure Socket Layer
```
### 注意
ここで忘れてはならないのが、update後に`updtvpkg`コマンドを行うこと。
これを行わないと`libcypto.a`とかが更新されません。

## 振り返り
ここまできて、試行錯誤していくと、gitのインストールには下記パッケージが最低必要なことがわかった。（もしかしたら、不要なものも混ざっているかもです）


```
bash-5.0-1.aix6.1.ppc.rpm                    info-6.4-1.aix6.1.ppc.rpm                    openldap-2.4.46-2.aix6.1.ppc.rpm
bzip2-1.0.6-3.aix6.1.ppc.rpm                 krb5-libs-1.16.1-2.aix6.1.ppc.rpm            p11-kit-0.23.16-1.aix6.1.ppc.rpm
ca-certificates-2019.01.10-2.aix6.1.ppc.rpm  less-487-1.aix6.1.ppc.rpm                    p11-kit-tools-0.23.16-1.aix6.1.ppc.rpm
curl-7.65.1-1.aix6.1.ppc.rpm                 libffi-3.2.1-3.aix6.1.ppc.rpm                perl-5.28.1-1.aix6.1.ppc.rpm
cyrus-sasl-2.1.26-3.aix6.1.ppc.rpm           libgcc-6.3.0-2.aix7.1.ppc.rpm                python-2.7.16-1.aix6.1.ppc.rpm
db-6.2.32-2.aix6.1.ppc.rpm                   libgcrypt-1.8.2-1.aix6.1.ppc.rpm             python-devel-2.7.16-1.aix6.1.ppc.rpm
expat-2.2.6-1.aix6.1.ppc.rpm                 libgpg-error-1.29-1.aix6.1.ppc.rpm           python-tools-2.7.16-1.aix6.1.ppc.rpm
gdbm-1.18.1-1.aix6.1.ppc.rpm                 libiconv-1.14-2.aix6.1.ppc.rpm               readline-8.0-2.aix6.1.ppc.rpm
libssh2-1.8.2-1.aix6.1.ppc.rpm               rsync-3.1.3-2.aix6.1.ppc.rpm                 gettext-0.19.8.1-3.aix6.1.ppc.rpm            
libstdcplusplus-6.3.0-2.aix7.1.ppc.rpm       sqlite-3.28.0-1.aix6.1.ppc.rpm               ncurses-6.1-2.aix6.1.ppc.rpm                 
zlib-1.2.11-1.aix6.1.ppc.rpm                 nspr-4.17-1.aix6.1.ppc.rpm                   glib2-2.56.1-2.aix6.1.ppc.rpm                
nss-3.34.1-2.aix6.1.ppc.rpm
```
注意が必要なのは、`libstdcplusplus-6.3.0-2.aix7.1.ppc.rpm`などはAIXのバージョンによってDLするものが変わります。今回は7.1なので、それ用をDLしています。
また、Pythonのupdateに関しては`python-2.7.16-1.aix6.1.ppc.rpm`,`python-devel-2.7.16-1.aix6.1.ppc.rpm`,`python-tools-2.7.16-1.aix6.1.ppc.rpm`の3つを`rpm -U`で一度に指定しないといけません。

## 複数rpmファイルの-Uvh(追記6/1)
他サーバー上でやったらもっとひどいくらい依存関係が発掘されました。
localのYUMレポジトリを作ろうと頑張っていた最中ですが、ただ単にGitだけ入れたい場合は、大体下記のファイルをがっつり用意して、  

```
rpm -Uvh  $(ls libunistring-* info-* bash-5* libiconv-1* gettext-0.19.8.1-5* libxml2* python-2.7.17* python-devel-2.7.17* python-tools-2.7.17* gdbm-1.18* readline-8.0-2* sqlite-3.28*)
```
こんな感じで一斉に`-Uvh`しちゃえば個別に一つずつやっていくより遥かに楽です。  

## ようやく
これ以降は、地道に`rpm -U`で一つずつインストール、もしくはupdateしていきます。。
ちなみに、`rpm -U *`だとできないんですよね、なんで？ 楽はさせてくれません。
満を辞してgitをインストールします。

```
# rpm -Uvh git-2.20.1-1.aix6.1.ppc.rpm             

Preparing...                          ################################# [100%]
Updating / installing...
   1:git-2.20.1-1                     ################################# [100%]
```

**あ、できた**

高鳴る胸の鼓動、、、
ようやく`git --version`を叩く時が来たァ！

## Dependent module /usr/lib/libiconv.a(libiconv.so.2) could not be loaded.

```
# git --version

Could not load program git:
        Dependent module /usr/lib/libiconv.a(libiconv.so.2) could not be loaded.
        Member libiconv.so.2 is not found in archive
```


。。。
`libiconv.a`はインストールされているのになぁ
ちなみに、`--test`というパラメータをつけるとインストールの結果がわかります。エラーの場合はdependencyエラーで必要なパッケージがわかったりします

```
# rpm -Uvh --test libiconv-1.14-2.aix6.1.ppc.rpm 

Preparing...                          ################################# [100%]
        package libiconv-1.14-22.ppc (which is newer than libiconv-1.14-2.ppc) is already installed
```

上記も調べていくと、AIXに設定されている`LIBPATH`が原因とわかりました。（libiconv.aのある場所がLIBPATHで設定されていないのが原因。`LIBPATH`の値の確認は`env | grep LIBPATH`で確認）
とりあえずGitが動くのかどうかさっさと確認したいので、`unset LIBPATH`を行います
もしくは`export LIBPATH=xxx/.../xxx:$LIBPATH`で変えてもいいと思います
実際はちゃんと.profileの値を変えるべきですね。。

```
# unset LIBPATH
# git
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone      Clone a repository into a new directory
   init       Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add        Add file contents to the index
   mv         Move or rename a file, a directory, or a symlink
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index

examine the history and state (see also: git help revisions)
   bisect     Use binary search to find the commit that introduced a bug
   grep       Print lines matching a pattern
   log        Show commit logs
   show       Show various types of objects
   status     Show the working tree status

grow, mark and tweak your common history
   branch     List, create, or delete branches
   checkout    Switch branches or restore working tree files
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   merge      Join two or more development histories together
   rebase     Reapply commits on top of another base tip
   tag        Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch      Download objects and refs from another repository
   pull       Fetch from and integrate with another repository or a local branch
   push       Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
```

できました。ようやく。

# 最後に

まあこんな感じで手動でやっていく人は珍しいとは思うのですが、もし同じような環境で、
とりあえずGit入れたい！って人がいれば参考になれば幸いです。
おそらく各パッケージのバージョンなど、環境は人によって変わりますがGitにおいては~~上に挙げたパッケージを全て持っておけば大丈夫なはず。~~ 違うサーバーだと、大体必要になるものは同じでしたが、やはりかなり変わってきます。  
あとそもそもAIXがネット環境に繋がらないのでGitサーバー立てるしかないということもインストールしてから気付きました！そこらへんは[AIXにGitサーバーを構築した流れ](https://qiita.com/mkzyk/items/9202c025f23b095ad657)でやります！