GNU Globalでソースパッケージを閲覧

#はじめに

今回はソースパッケージ入手からソースコードをWEBブラウザで閲覧するまでの設定をします。


RPMパッケージ関連のことは以下のドキュメントを参考にしました。

RPM Packaging Guide
https://rpm-packaging-guide.github.io/

How to change the default install location for source rpm installs in Red Hat Enterprise Linux 6 ?
https://access.redhat.com/solutions/99203

How do I build a source RPM using rpmbuild?
https://access.redhat.com/articles/1507

Module ngx_http_autoindex_module
http://nginx.org/en/docs/http/ngx_http_autoindex_module.html


#ソースコード展開前準備


##ソースコードを公開するディレクトリ作成


以下のコマンドを実行しディレクトリを作成します。

```
mkdir /usr/local/var/www
```

##NGINXのドキュメントルート変更とディレクトリ公開設定

以下のコマンドを実施し設定ファイルを変更します。

```
vi /etc/nginx/nginx.conf
```

変更前

```
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        location ~ \.cgi$ {
        fastcgi_pass   unix:/run/fcgiwrap/fcgiwrap.sock;
        include        /etc/nginx/fastcgi.conf;
        }

```


変更後

```
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/local/var/www;　★変更箇所

----------  追記ここから  ----------

        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;

----------  追記ここまで  ----------

        location ~ \.cgi$ {
        fastcgi_pass   unix:/run/fcgiwrap/fcgiwrap.sock;
        include        /etc/nginx/fastcgi.conf;
        }

```


##NGINXサービス再起動


以下のコマンドを実行しサービスを再起動します。

```
systemctl restart nginx

```

##RPMソースパッケージ入手と展開

以下のコマンドを実行しソースパッケージをダウンロードします。


```
dnf download --source systemd-239-41.el8_3 --downloaddir=/usr/local/src/
```

以下のコマンドを実行しソースパッケージをダウンロードできたことを確認します。

```
ls -l /usr/local/src/
```

```
合計 7672
-rw-r--r-- 1 root root 7853953 12月  3 20:16 systemd-239-41.el8_3.src.rpm
```

以下のコマンドを実行しソースパッケージを展開します。

```
rpm -ivh --define='%_topdir /usr/local/var/www/systemd-239-41.el8_3' /usr/local/src/systemd-239-41.el8_3.src.rpm
```

実行結果

```
更新中 / インストール中...
   1:systemd-239-41.el8_3             警告: user mockbuild does not exist - using root
警告: group mock does not exist - using root
警告: user mockbuild does not exist - using root
警告: group mock does not exist - using root
警告: user mockbuild does not exist - using root
```

警告が沢山表示されるため表示されてないように回避します。
以下のコマンドを実行しユーザとグループを追加します。

```
useradd -s /sbin/nologin mockbuild
```

```
groupadd mock
```

ユーザとグループ追加後は以下のようになります。

```
rpm -ivh --define='%_topdir /usr/local/var/www/systemd-239-41.el8_3' /usr/local/src/systemd-239-41.el8_3.src.rpm
```

```
更新中 / インストール中...
   1:systemd-239-41.el8_3             ################################# [100%]
```

##ファイル展開確認

以下のコマンドを実行しソースパッケージが展開されたことを確認します。

```
ls -l /usr/local/var/www/
```

実行結果

```
合計 0
drwxr-xr-x 4 root root 34 12月  6 01:09 systemd-239-41.el8_3
```

以下のコマンドを実行しtar.gzファイルを展開します。

```
tar -xvf /usr/local/var/www/systemd-239-41.el8_3/SOURCES/systemd-239.tar.gz -C /usr/local/var/www/systemd-239-41.el8_3/SOURCES/
```

##ソースコードを閲覧するためのHTMLファイル作成

以下のコマンドを実行しディレクトリを移動します。

```
cd /usr/local/var/www/systemd-239-41.el8_3/
```

以下のコマンドを実行しタグファイルを作成します。

```
gtags -v
```

以下のコマンドを実行しタグファイルが作成されたことを確認します。

```
ls -l
```

実行結果

```
合計 11536
-rw-r--r--  1 root root  843776 12月  6 01:15 GPATH　 ★
-rw-r--r--  1 root root 9338880 12月  6 01:15 GRTAGS　★
-rw-r--r--  1 root root 1589248 12月  6 01:15 GTAGS　 ★
drwxr-xr-x  3 root root   36864 12月  6 01:14 SOURCES
drwxr-xr-x  2 root root      26 12月  6 01:09 SPECS
```

以下のコマンドを実行しHTMLファイルを作成します。

```
htags -aFfnos
```

##ソースコード閲覧

ブラウザでWebサーバにアクセスしHTMLフォルダをクリックします。

```
http://サーバアドレス/systemd-239-41.el8_3/HTML/
```

#デモ

RHEL7系からNetworkインターフェイス名が大きく変わりました。
公式のページを確認するとudevが関連していると記載があります。
そもそも本当にudevが関係しているのか？という疑問を確認したいと思います。


第11章 ネットワークデバイス命名における一貫性

>Red Hat Enterprise Linux では、udev が多くの異なる命名スキームをサポートしています。
>デフォルトでは、ファームウェア、トポロジー、および場所情報に基づいて固定名が割り当てられます。
>これには、名前が完全に自動的かつ予想可能であり、ハードウェアが追加もしくは
>削除されても (再列挙がなされず) 固定のままであり、またハードウェアが壊れた場合にシームレスに
>交代可能であるという利点があります。マイナス面は、従来使用されていた eth や wla といった名前と
>比べて読みにくい場合があるという点です。たとえば、enp5s0 などの場合です。

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/ch-consistent_network_device_naming

検索画面で"bios"と入力して検索

以下のコメントが見つかります。ファイル名から推測するとudev関連と予想できます。
細かい処理については実際にプログラムを読んで見てみて下さい。

```
root/SOURCES/systemd-239/src/udev/udev-builtin-net_id.c
```

```
   4  * Predictable network interface device names based on:
   5  *  - firmware/bios-provided index numbers for on-board devices
   6  *  - firmware-provided pci-express hotplug slot index number
   7  *  - physical/geographical location of the hardware
   8  *  - the interface's MAC address
```

#ソースパッケージ展開からHTML作成までのスクリプト

手動で行っていたものをシェルスクリプト化してみました。
実行する際は自己責任でお願い致します。

```
#!/bin/sh -x

#Environment variable
#Specify the source package name in the first argument
SOURCEDIR=/usr/local/src
DOCROOT=/usr/local/var/www
FILENAME=`basename $1 .src.rpm`

#Argument check
if [ $# -ne 1 ]; then echo "Argument Error" && exit 1;fi

#File extension check
if [ ".src.rpm" != ${1: -8} ]; then echo "Extension Error" && exit 1;fi

#Directory check
if [ -d $DOCROOT/$FILENAME ]; then echo "I already have a directory" && exit 1;fi

cd ~

#.rpmmacros file check
if [ -e .rpmmacros ]; then

    if [ -z "`cat .rpmmacros | grep %_topdir | awk '{print $1}'`" ]; then
      echo "Add definition"
      echo %_topdir $DOCROOT >> .rpmmacros

    elif [ $DOCROOT = `cat .rpmmacros | grep %_topdir | awk '{print $2}'` ]; then
      echo "Document root skipped because of the same definition"

    elif [ %_topdir = "`cat .rpmmacros | grep %_topdir | awk '{print $1}'`" ]; then

      echo "Do you want to rewrite the definition? yes or no"
        while :
        do
          read INPUT
          case $INPUT in

          yes)
            echo "Rewrote the definition"
            sed -i '/%_topdir/d' .rpmmacros
            echo %_topdir $DOCROOT >> .rpmmacros
            break ;;

          no)
            echo "Did not rewrite the definition"
            exit 1
            break;;

          *)
            echo "Entered other than yes, no";;
          esac
        done
    fi

else
  echo "I created a new file"
  echo %_topdir $DOCROOT > .rpmmacros

fi

cd $SOURCEDIR || { echo "SOURCEDIR directory move failure!"; exit 1; }

rpm -ivh `basename $1` || { echo "Source package deployment failure!"; exit 1; }

mkdir $DOCROOT/$FILENAME || { echo "Directory creation failure failure!"; exit 1; }

mv $DOCROOT/SOURCES $DOCROOT/$FILENAME || { echo "Directory move failure! for SOURCES"; exit 1; }

mv $DOCROOT/SPECS   $DOCROOT/$FILENAME || { echo "Directory move failure! for SPECS"; exit 1; }

tar -xvf `find $DOCROOT/$FILENAME -name "*.tar.gz"` -C $DOCROOT/$FILENAME/SOURCES/ || { echo "Tar.gz file extraction failed!"; exit 1; }

cd $DOCROOT/$FILENAME || { echo "Document root move failure!"; exit 1; }

gtags -v || { echo "gtags command failed!"; exit 1; }

htags -aFfnos || { echo "htags command failed!"; exit 1; }

echo "Work completed"

```

#まとめ

追加のスクリプトまで作成しましたので削除等を盛り込んだスクリプトに改修予定です。