Cobblerの省力化のためにプロキシと組み合わせる

（2015-06-21 Fedora 21とFedora 22とで公式リポジトリに同じ名前で違う中身のファイルが一部あることがわかったのでその対策を追加）
（2015-07-06 DebianとUbuntuを追加。DebianとUbuntuとでも同じ名前で違う中身のファイルがあった）

# 何故そうしようとしたか

Cobblerを使ってOSをインストールする際に、通常はCobblerの機能を使って事前にOSのリポジトリをミラーしてローカルに保持しておく、ということを行う。

これは何台（何十台、何百台……）もOSインストールを行う場合にはネットワーク的に近い場所にパッケージがあった方が早く済むし、パブリックミラーに迷惑も掛からないし、そもそもOSインストールされるマシンはインターネットに繋がらないようになっていることもしばしばあることだ。

しかしCobblerの機能としては、インストールしたOSにローカルミラーだけでなくリモートのリポジトリも参照させるようにすることができるようになっている。
この機能とプロキシを組み合わせれば、OSのリポジトリに含まれるすべてのパッケージをローカルに保持する代わりに、よく使うパッケージだけをプロキシのキャッシュとして保持しておくようにすることができる。

そうすれば保持しておくパッケージの数が断然少なくなるのでストレージの必要量も減るし、最初にローカルにダウンロードしておく準備時間が必要ない。
CentOSのリポジトリはそれほど大きくないのでCentOSだけならそれほど気にならないのだが、やれFedoraだDebianだUbuntuだ、という辺りはCentOSよりリポジトリのサイズがずっと大きいので、こうすることによるストレージ使用量の削減効果がかなりある。
加えてDebianやUbuntuのローカルミラーを作ろうとしたら、何万ファイル（かどうかは確認してないのでわからないが）もダウンロードするせいかDNSサーバに負荷が掛かったらしく、しばらく一部のホスト名が解決できなくなったりする「事件」まで発生したのでローカルミラーを作る手法はちょっと避けたいと思うようになったのもプロキシを使用する手法に移行しようとした一因である。ああ自宅ので良かった。

というわけでCobblerと同じホストにプロキシを立ててみることにする。
プロキシには興味からnginxを使ってみた。

この文章は[CentOS 7にCobblerをインストールする](http://qiita.com/yunano/items/476c6c060f28dd919740)を発展させたものとなるが、両文章の共通部分についてはそちらを参照する構成になっている。
Cobblerとは何か、という辺りの情報もそちらに書いてある。

# nginxのセットアップ

nginxをフォワードプロキシとしてセットアップする。
OSはCentOS 7を使用している。

## nginxのインストール

EPELにあるので、EPELを使えるようにしてからnginxをインストールする。

```
# yum install epel-release
# yum install nginx
```

## 任意：キャッシュを個別に削除する機能を有効化したnginxをビルドする

しかしEPELにあるnginxはキャッシュを個別に削除する機能が有効化されていない。
キャッシュされたファイルのファイル名は元のファイル名ではなく16進数32文字のファイル名になるので、滅多にないことだろうが化けたファイルをキャッシュした場合、個別に削除する機能がないとキャッシュファイルの全削除で対応するか、頑張って何らかのツールでどのキャッシュファイルがどのURLに対応するのか調べて削除することになる。

もしキャッシュを個別に削除する機能を有効化したければnginxをビルドする必要がある。
ここではビルドしてみよう。

nginxとngx_cache_purgeのソースをダウンロードしてきて解凍し、解凍してできたnginx-x.y.zディレクトリに移動する。
ここでnginxは1.6.2をダウンロードしているが、これはEPELでインストールされたバージョンと合わせないとconfigure argumentsがそのまま使えないかもしれないと考えたからであり、試行錯誤する気なら別のバージョンでも構わないだろう（本当に試行錯誤することになるのかは知らない）。

```
# curl http://nginx.org/download/nginx-1.6.2.tar.gz -o nginx-1.6.2.tar.gz
# curl http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz -o ngx_cache_purge-2.3.tar.gz
# tar xf nginx-1.6.2.tar.gz
# tar xf ngx_cache_purge-2.3.tar.gz
# cd nginx-1.6.2
```

EPELからインストールしたnginxのconfigure argumentsを「nginx -V」で調べてみる。

```
# nginx -V
nginx version: nginx/1.6.2
built by gcc 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-pcre --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
```

このconfigure argumentsにngx_cache_purgeをモジュールとして追加するように、つまり「--add-module=../ngx_cache_purge-2.3」を追加してconfigureしてやればよい。
（今回の目的を達成するのにこんなにたくさんモジュールが必要なわけでは当然ないが、どれが要らないとか選別するために調べるのは時間が掛かりそうだったので）

```
# ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-pcre --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E' --add-module=../ngx_cache_purge-2.3
```

とはいえこれを実行するには大抵の環境ではいろいろ足りずにエラーになるだろう。
上手く行くまでエラーメッセージをぐぐるなどして足りないパッケージをインストールしていく。
CentOS 7.1.1503のminimalで作成した環境では次のパッケージが足りなかったので追加した。

```
# yum install gcc redhat-rpm-config pcre-devel openssl-devel libxslt-devel gd-devel perl-ExtUtils-Embed GeoIP-devel gperftools-devel
```

configureがエラーなく通るところまで行ったらmakeしてmake install。

```
# make
# make install
```

これでキャッシュを個別に削除する機能が有効化された。

## nginxの設定

キャッシュを保持するディレクトリを作成してnginxユーザが書き込めるようにする。

```
# mkdir /var/lib/nginx/cache
# chown nginx:nginx /var/lib/nginx/cache
# chmod 700 /var/lib/nginx/cache
```

/etc/nginx/nginx.conf を修正する。
以下に示すのは追加あるいは修正した箇所のみである。

```txt:/etc/nginx/nginx.conf
http {
    proxy_cache_path /var/lib/nginx/cache levels=2 keys_zone=one:128m inactive=30d max_size=50g;

    server {
        listen       8080 default_server;
        server_name  _;
        resolver <適当なDNSサーバ>;

        location / {
            set $do_not_cache 0;
            if ($uri !~* "\.(.?rpm|deb)$") {
                set $do_not_cache 1;
            }
            set $key $request_uri;
            if ($request_uri ~ "/x86_64(/.+)") {
               set $key $1;
            }
            if ($request_uri ~ "(/[1-9][0-9]*/.+)") {
               set $key $1;
            }
            if ($request_uri ~ "(/(?:debian|ubuntu)/.+)") {
               set $key $1;
            }
            proxy_no_cache $do_not_cache;
            proxy_cache_bypass $do_not_cache;
            proxy_cache one;
            proxy_cache_key $key;
            proxy_cache_valid 200 300d;
            proxy_redirect off;
            proxy_pass $scheme://$http_host$request_uri;
        }

        location ~ ^/purge(/.+) {
            set $key $1;
            set $key_tmp $1;
            if ($key_tmp ~ "/x86_64(/.+)") {
                set $key $1;
            }
            if ($key_tmp ~ "(/[1-9][0-9]*/.+)") {
                set $key $1;
            }
            if ($key_tmp ~ "(/(?:debian|ubuntu)/.+)") {
                set $key $1;
            }
            allow 127.0.0.1;
            deny all;
            proxy_cache_purge one $key;
        }
    }
}
```

以下、特徴的な部分を説明する。

* proxy_cache_path
 * levels=2 → キャッシュディレクトリの中に2階層できるのはあまり好きではないので1階層になるように設定している。設定値が3だと4096個ディレクトリができるがそれはちょっと多いと思ったので2（ディレクトリ256個）にした。
 * keys_zone=one:128m → ゾーン名と使用メモリ量。ここでは128MB使用するように設定している。http://qiita.com/harukasan/items/80061c7429a39c0b2dab によると100万ファイルをキャッシュできる、ということになる。それだけあれば十分だろう。
 * inactive=30d → 30日間アクセスがなければキャッシュが削除される、という設定。アップデートされる前のパッケージには通常二度とアクセスされないのであまり長くなくても良いだろう。
 * max_size=50g → キャッシュに使って良いストレージ容量を設定する。ここでは50GBにした。
* listen 8080 → Cobblerが80番ポートを使用するので別のポート(8080)にする。
* location /
 * $do_not_cache → 値が0ならキャッシュする、1ならキャッシュしない。この設定だと拡張子がrpm,drpmかdebのファイルだけキャッシュすることになる。つまり、パッケージ本体はキャッシュするがメタデータはキャッシュしないようにしている。
 * $key → パッケージは同じファイル名ならどのパブリックミラーからダウンロードしても同じファイルであるはずなので、URLのx86_64以降の部分を切り出し、どのパブリックミラーからダウンロードしても同じキャッシュにヒットするようにする。もしかしたら例外があるかもしれないが、その時はその時考える。→*2015-06-21*:Fedora 21とFedora 22とで公式リポジトリに同じ名前で違う中身のファイルが一部あることがわかったので、URLのディレクトリが1以上の整数となっている箇所があればそこから切り出すようにした。→*2015-07-06*:DebianとUbuntuの部分を追加。DebianとUbuntuとでも同じ名前で違う中身のファイルがあったので/debianや/ubuntuから切り出している。
 * proxy_cache_key \$key → キャッシュファイル名を作るための元文字列として、先程作った$keyをセットしている。
 * proxy_cache_valid 200 300d → ステータスコードが200の場合に、300日間キャッシュする。この期間はキャッシュされた時点から数え、proxy_cache_pathのinactiveのように最終アクセスからではない。期限が切れるとリモートから取り直しになるので、こちらは長い方が良い。
* location ~ ^/purge(/.+) → キャッシュの個別削除に関する設定。機能を有効化してなければこの項目は不要である。
 * allow 127.0.0.1; deny all → キャッシュの個別削除はlocalhostからのみ実施できるようにしている。
 * proxy_cache_purge one \$key → どのキャッシュファイルを削除するか。キャッシュ削除用URLにアクセスした時に、proxy_cache_keyで設定した$keyと一致する文字列が取得できるように設定しないとならない。ここでは http://(hostname)/(filepath) のキャッシュは http://(hostname)/purge/(filepath) にプロキシを通してアクセスすると削除されるように設定している。

## nginxの起動とファイアウォールの解放

nginxサービスを起動し、8080/tcpについてファイアウォールを開放する。

```
# systemctl enable nginx.service
# systemctl start nginx.service
# firewall-cmd --add-port=8080/tcp
# firewall-cmd --add-port=8080/tcp --permanent
```

## キャッシュの個別削除

nginx.conf の設定の箇所で書いたように、キャッシュの個別削除機能を有効化していれば http://(hostname)/(filepath) のキャッシュは http://(hostname)/purge/(filepath) に、nginxを起動しているマシン上でプロキシを通してアクセスすると削除される。

例えば http://ftp.iij.ad.jp/pub/linux/centos/7/extras/x86_64/Packages/kubernetes-0.9.0-0.3.git96af0c3.el7.x86_64.rpm がキャッシュされていたとすると次を実行すると削除できる。

```
# curl -x localhost:8080 http://ftp.iij.ad.jp/purge/pub/linux/centos/7/extras/x86_64/Packages/kubernetes-0.9.0-0.3.git96af0c3.el7.x86_64.rpm
```

実際にはホスト名は参照していないので、

```
# curl -x localhost:8080 http://ftp.jaist.ac.jp/purge/pub/Linux/CentOS/7/extras/x86_64/Packages/kubernetes-0.9.0-0.3.git96af0c3.el7.x86_64.rpm
```

でも削除されるし、7より前のファイルパスも参照していないので、

```
# curl -x localhost:8080 http://ftp.jaist.ac.jp/purge/7/extras/x86_64/Packages/kubernetes-0.9.0-0.3.git96af0c3.el7.x86_64.rpm
```

でさえも良い。

正しく削除された場合は次のようなメッセージが出力される。

```
<html>
<head><title>Successful purge</title></head>
<body bgcolor="white">
<center><h1>Successful purge</h1>
<br>Key : /7/extras/x86_64/Packages/kubernetes-0.9.0-0.3.git96af0c3.el7.x86_64.rpm
<br>Path: /var/lib/nginx/cache/85/1146128d64b69a45041867e60b77fc85
</center>
<hr><center>nginx/1.6.2</center>
</body>
</html>
```

# Cobblerのセットアップ

ここは[「CentOS 7にCobblerをインストールする」の"Cobblerのセットアップ"](http://qiita.com/yunano/items/476c6c060f28dd919740#cobblerのセットアップ)と、この時点でもうすでにepel-releaseがインストールされていること以外はまったく変更ないので、そちらを参照のこと。

# OSイメージの追加

ここは[「CentOS 7にCobblerをインストールする」の"OSイメージの追加"](http://qiita.com/yunano/items/476c6c060f28dd919740#osイメージの追加)とは大きく変更がある。

以下では[「CentOS 7にCobblerをインストールする」の"OSイメージの追加"](http://qiita.com/yunano/items/476c6c060f28dd919740#osイメージの追加)と違いが分かるように、ほぼ同じ章立てでCentOS 7を追加する方法を記述する。
両ページに同じ文章が書かれている場合があるがご容赦を。

また、CentOS 6やFedora 21の追加についても最後に記述する。
DebianやUbuntuもそのうち書くつもりだが、これはまた別記事になるだろう。→2015-07-06: [Cobblerを使ってDebianやUbuntuをPXEインストールする](http://qiita.com/yunano/items/a883ae60f610dbb71ab8)に書いた。

## OSイメージの取り込み

curlやwgetなどでインストールISOをダウンロードしてマウントする。wgetはminimalではインストールされないのでcurlでの例を示す。

取り込んだパッケージは基本的には使わないが、インポート時にcentos-releaseパッケージだけバージョン判別に必要になる。
従ってNetInstall.isoではエラーになり、利用可能な最小のISOファイルはMinimal.isoである。
なお、取り込んだパッケージはOSインストール時にはまったく使用されないのでISOは7.0.1406のものでも7.1.1503のものでも実際には構わない。

```
# curl http://ftp.iij.ad.jp/pub/linux/centos/7.1.1503/isos/x86_64/CentOS-7-x86_64-Minimal-1503-01.iso -o CentOS-7-x86_64-Minimal-1503-01.iso
# mount CentOS-7-x86_64-Minimal-1503-01.iso /mnt
```

ISOファイルの中身をCobblerにインポートする。

```
# cobbler import --name c7 --path /mnt
```

インポートが終わったらISOファイルはアンマウントして良い。

```
# umount /mnt
```

### ISOファイルの取り込み直し

前述の通り、7ならばどのバージョンのISOを使っても構わないので、CentOS 7の新しいポイントリリースが出てもISOファイルの取り込み直しは行わなくて良い。

## パッケージリポジトリの設定

パブリックミラーのbaseとupdatesを参照するようにしておけば常に最新のパッケージを利用できる。
ローカルミラーではなくリモートのリポジトリを参照させるようにする設定が「--mirror-locally 0」である。

次のコマンドで参照先を設定することができる。

```
# cobbler repo add --name c7-base --mirror http://ftp.iij.ad.jp/pub/linux/centos/7/os/x86_64 --mirror-locally 0
# cobbler repo add --name c7-updates --mirror http://ftp.iij.ad.jp/pub/linux/centos/7/updates/x86_64 --mirror-locally 0
```

URLさえわかっていれば任意のyumリポジトリを参照先にすることができる。
ここではついでにextrasリポジトリとepelを参照先にする。

```
# cobbler repo add --name c7-extras --mirror http://ftp.iij.ad.jp/pub/linux/centos/7/extras/x86_64 --mirror-locally 0
# cobbler repo add --name epel7 --mirror http://ftp.iij.ad.jp/pub/linux/fedora/epel/7/x86_64 --mirror-locally 0
```

オプションとして「--yumopts "enabled=0"」を付けると、インストールしたOS上で明示的に有効にしないと利用できないリポジトリも追加することができる。
ここではepel-testingを「--yumopts "enabled=0"」付きで参照先にする。

```
# cobbler repo add --name epel7-testing --mirror http://ftp.iij.ad.jp/pub/linux/fedora/epel/testing/7/x86_64 --mirror-locally 0 --yumopts "enabled=0"
```

以下を実行するとリポジトリのセットアップが行われる。
このコマンドはリポジトリの追加や変更を行った際に実行すれば良い。

```
# cobbler reposync
```

## cobbler profileの設定変更

Cobblerは取り込んだOSをdistroという単位で、OSをどのようにインストールするかをprofileという単位で扱っている。
「c7」という名前でインポートした場合、自動的に「c7-x86_64」という名前のdistroとprofileが作成される。これは`cobbler distro list`や`cobbler profile list`で名称を得ることができる。

distroの設定をいじることはあまりないが、profileの方はいくらかいじる必要がある。特に変更されるのは「どのような内容でインストールすることにするか」と「どのリポジトリを利用するか」である。

RHEL系では自動インストール時にどのような内容でインストールするかはkickstartファイルに記述する。
CobblerにおいてRHEL系標準のkickstartファイルのテンプレートは /var/lib/cobbler/kickstarts/sample_end.ks であり、これは「c7-x86_64」プロファイルが作られた時点でこれを使うように設定されている（`cobbler profile report --name c7-x86_64`のKickstart項で確認できる）。

ここではこのファイルをコピーして、このプロファイル用に1つ作ることにしよう。

```
# cp /var/lib/cobbler/kickstarts/sample_end.ks /var/lib/cobbler/kickstarts/c7.ks
```

kickstartテンプレートの修正は説明がちょっと長いので別に章立てて行う。

作ったkickstartファイルのテンプレートと利用するリポジトリをプロファイルに紐づける。利用可能なリポジトリは前項で参照先にしたものである。

```
# cobbler profile edit --name c7-x86_64 --repos "c7-base c7-updates c7-extras epel7 epel7-testing" --kickstart /var/lib/cobbler/kickstarts/c7.ks
```

## スニペットの作成

次の内容でスニペット /var/lib/cobbler/snippets/yum_repo_proxy_config を作成する。
このスニペットはkickstartテンプレートファイル内で使用し、有効なリポジトリを1つずつnginxで作ったフォワードプロキシを通してアクセスするようにする記述を追加する作用がある。

```txt:/var/lib/cobbler/snippets/yum_repo_proxy_config
#set $repo_data = $getVar("repo_data",[])
#for $repo in $repo_data
  #set $enabled = '1'
  #if $repo.yumopts.has_key('enabled')
    #set $enabled = $repo.yumopts.enabled
  #end if
  #if $enabled == '1'
repo --name=${repo.name} --proxy=http://$http_server:8080 --baseurl=${repo.mirror}
  #end if
#end for
```

## kickstartテンプレートの修正

kickstartファイルのテンプレートを修正することにより、どのような内容でインストールするかを決めることができる。

kickstartファイルのオプションは以下を参照すれば良い。
https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/Installation_Guide/sect-kickstart-syntax.html

今作業しているのがCentOS 7上なので、インストールした時の設定である /root/anaconda-ks.cfg を参考にするのも良いだろう。

とりあえず /var/lib/cobbler/kickstarts/sample_end.ks から変更しておきたいのは以下のようなものだ。

* auth: shadowファイルにユーザのパスワードを保存する時のハッシュアルゴリズムがmd5になっているので、最近の標準であるsha512にしておく。
* keyboard: 日本語106キーボードに。
* timezone: 東京に。

```
# sed -ri "s/(^auth ).*/\1--enableshadow --passalgo=sha512/" /var/lib/cobbler/kickstarts/c7.ks
# sed -ri "s/(^keyboard ).*/\1--vckeymap=jp106 --xlayouts='jp'/" /var/lib/cobbler/kickstarts/c7.ks
# sed -ri "s|(^timezone ).*|\1--utc Asia/Tokyo|" /var/lib/cobbler/kickstarts/c7.ks
```

/var/lib/cobbler/kickstarts/c7.ks の`$yum_repo_stanza`という行はkickstartファイルに、有効なリポジトリを1つずつrepo行として追加してくれる。
しかしこれではプロキシを通ってくれないので、先程作ったスニペットを読み込む`$SNIPPET('yum_repo_proxy_config')`という行に差し替える。
（つまり、この先程作成したスニペットは`$yum_repo_stanza`が生成する文字列にプロキシを通す設定を追加しただけのものであった）

```
# sed -i "s/^\\\$yum_repo_stanza$/\$SNIPPET('yum_repo_proxy_config')/" /var/lib/cobbler/kickstarts/c7.ks
```

kickstartファイルの%packagesと%endの間にはインストールさせたいパッケージを記述することができる。
Cobblerのkickstartテンプレートには、ここに`$SNIPPET('func_install_if_enabled')`という行があるが、何もしない限りこれは空白に変換されるので無視して良い。

%packagesと%endの間が空白でもcoreパッケージグループは指定されたものとなり、「最小限のインストール」相当となる。
パッケージ名ではなくパッケージグループ名を指定する場合には、パッケージグループ名の前に"@"を付ける。例えばbaseパッケージグループもインストールさせることにする場合、`@base`を追加する。

kickstartファイルの%postと%endの間には、インストール完了直前に実行させたいコマンドを記述する。Cobblerのkickstartテンプレートにはここにいろいろ書いてあるが、良いようにしてくれる部分なので削除しないで良い。

Cobblerでインストールしたコンピュータは、リポジトリとしてCobblerで設定したミラーを使うように設定されているが、元々のOS標準のリポジトリが無効になっているわけではないので、同じ内容のリポジトリが2箇所に設定された状態になる。
以下の例では、よりネットワーク的に遠い /etc/yum.repos.d/CentOS-Base.repo に書かれた元々のOS標準のリポジトリ(base, updates, extras)、およびCobblerによって作られる /etc/yum.repos.d/cobbler-config.repo からcobbler importで取り込んだパッケージを利用するリポジトリ(core-0)を無効にしている。

これをsedでやるには%postと%endの間に次の4行を追加すれば良い。
ただし /etc/yum.repos.d/cobbler-config.repo の生成は`$yum_config_stanza`で行われるので、core-0の無効化はそれ以降に追加する必要がある。
（さっきスニペットに差し替えたのは`$yum_repo_stanza`で、こっちは`$yum_config_stanza`）

```
sed -i '/^\[base\]$/a\enabled=0' /etc/yum.repos.d/CentOS-Base.repo
sed -i '/^\[updates\]$/a\enabled=0' /etc/yum.repos.d/CentOS-Base.repo
sed -i '/^\[extras\]$/a\enabled=0' /etc/yum.repos.d/CentOS-Base.repo
sed -i '4c\enabled=0' /etc/yum.repos.d/cobbler-config.repo
```

この4行を /var/lib/cobbler/kickstarts/c7.ks にsedで追加する例。

```
# sed -i "/^# End yum configuration$/i\sed -i '/^\\\[base\\\]$/a\\\enabled=0' /etc/yum.repos.d/CentOS-Base.repo" /var/lib/cobbler/kickstarts/c7.ks
# sed -i "/^# End yum configuration$/i\sed -i '/^\\\[updates\\\]$/a\\\enabled=0' /etc/yum.repos.d/CentOS-Base.repo" /var/lib/cobbler/kickstarts/c7.ks
# sed -i "/^# End yum configuration$/i\sed -i '/^\\\[extras\\\]$/a\\\enabled=0' /etc/yum.repos.d/CentOS-Base.repo" /var/lib/cobbler/kickstarts/c7.ks
# sed -i "/^# End yum configuration$/i\sed -i '4c\\\enabled=0' /etc/yum.repos.d/cobbler-config.repo" /var/lib/cobbler/kickstarts/c7.ks
```

あるいはyum-utilsパッケージを追加しているなら（baseパッケージグループに含まれている）、yum-utilsパッケージに含まれているyum-config-managerを使った方がよりきれいで正式っぽい手順になる。
この場合、%postと%endの間に次の4行を追加すれば良い。

```
yum-config-manager --disable base
yum-config-manager --disable updates
yum-config-manager --disable extras
yum-config-manager --disable core-0
```

この4行を /var/lib/cobbler/kickstarts/c7.ks にsedで追加する例。

```
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable base" /var/lib/cobbler/kickstarts/c7.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable updates" /var/lib/cobbler/kickstarts/c7.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable extras" /var/lib/cobbler/kickstarts/c7.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable core-0" /var/lib/cobbler/kickstarts/c7.ks
```

最後に、yumの設定でフォワードプロキシを通すようにする必要がある。
%postと%endの間に次の1行を追加すれば良い。
`$http_server`はCobblerマシンのIPアドレスに変換される。

```
echo 'proxy=http://$http_server:8080' >> /etc/yum.conf
```

この1行を /var/lib/cobbler/kickstarts/c7.ks にsedで追加する例。

```
# sed -i "/^# End yum configuration$/i\echo 'proxy=http://\$http_server:8080' >> /etc/yum.conf" /var/lib/cobbler/kickstarts/c7.ks
```

# cobbler systemの作成

ここは[「CentOS 7にCobblerをインストールする」の"cobbler systemの作成"](http://qiita.com/yunano/items/476c6c060f28dd919740#cobbler-systemの作成)からまったく変更ないので、そちらを参照のこと。

# CentOS 6の追加

CentOS 7と手順はほぼ変わらない。

インポート。

```
# curl http://ftp.iij.ad.jp/pub/linux/centos/6.6/isos/x86_64/CentOS-6.6-x86_64-minimal.iso -o CentOS-6.6-x86_64-minimal.iso
# mount CentOS-6.6-x86_64-minimal.iso /mnt
# cobbler import --name c6 --path /mnt
# umount /mnt
```

参照リポジトリの追加。

```
# cobbler repo add --name c6-base --mirror http://ftp.iij.ad.jp/pub/linux/centos/6/os/x86_64 --mirror-locally 0
# cobbler repo add --name c6-updates --mirror http://ftp.iij.ad.jp/pub/linux/centos/6/updates/x86_64 --mirror-locally 0
# cobbler repo add --name c6-extras --mirror http://ftp.iij.ad.jp/pub/linux/centos/6/extras/x86_64 --mirror-locally 0
# cobbler repo add --name epel6 --mirror http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64 --mirror-locally 0
# cobbler repo add --name epel6-testing --mirror http://ftp.iij.ad.jp/pub/linux/fedora/epel/testing/6/x86_64 --mirror-locally 0 --yumopts "enabled=0"
# cobbler reposync
```

プロファイルの設定。

```
# cp /var/lib/cobbler/kickstarts/sample_end.ks /var/lib/cobbler/kickstarts/c6.ks
# cobbler profile edit --name c6-x86_64 --repos "c6-base c6-updates c6-extras epel6 epel6-testing" --kickstart /var/lib/cobbler/kickstarts/c6.ks
```

スニペットはCentOS 7のものと同じものを使用する。

```txt:/var/lib/cobbler/snippets/yum_repo_proxy_config
#set $repo_data = $getVar("repo_data",[])
#for $repo in $repo_data
  #set $enabled = '1'
  #if $repo.yumopts.has_key('enabled')
    #set $enabled = $repo.yumopts.enabled
  #end if
  #if $enabled == '1'
repo --name=${repo.name} --proxy=http://$http_server:8080 --baseurl=${repo.mirror}
  #end if
#end for
```

kickstartテンプレートファイルの編集。
keyboard項についてはCentOS 7とは指定の仕方が違う。
また、インストールされるパッケージは初期状態ではcoreパッケージグループとbaseパッケージグループのものとなる。%packagesに--nobaseオプションを付けるとbaseパッケージグループのものはインストールされないようになる。

```
# sed -ri "s/(^auth ).*/\1--enableshadow --passalgo=sha512/" /var/lib/cobbler/kickstarts/c6.ks
# sed -ri "s/(^keyboard ).*/\1jp106/" /var/lib/cobbler/kickstarts/c6.ks
# sed -ri "s|(^timezone ).*|\1--utc Asia/Tokyo|" /var/lib/cobbler/kickstarts/c6.ks
# sed -i "s/^\\\$yum_repo_stanza$/\$SNIPPET('yum_repo_proxy_config')/" /var/lib/cobbler/kickstarts/c6.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable base" /var/lib/cobbler/kickstarts/c6.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable updates" /var/lib/cobbler/kickstarts/c6.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable extras" /var/lib/cobbler/kickstarts/c6.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable core-0" /var/lib/cobbler/kickstarts/c6.ks
# sed -i "/^# End yum configuration$/i\echo 'proxy=http://\$http_server:8080' >> /etc/yum.conf" /var/lib/cobbler/kickstarts/c6.ks
```

# Fedora 21の追加

Cobbler 2.6.7同梱のsignatureファイルではFedora 21が追加できないので、最新のもの( http://www.cobblerd.org/signatures/latest.json )から持ってくる。

```
# cobbler signature update
```

Fedora 21のISOの中でインポート可能な最小のものはFedora-Server-DVD-x86_64-21.isoだと思われるのでこれをダウンロード。

```
# curl http://ftp.iij.ad.jp/pub/linux/fedora/releases/21/Server/x86_64/iso/Fedora-Server-DVD-x86_64-21.iso -o Fedora-Server-DVD-x86_64-21.iso
```

後はCentOS 7と手順は変わらない。

インポート。

```
# mount Fedora-Server-DVD-x86_64-21.iso /mnt
# cobbler import --name f21 --path /mnt
# umount /mnt
```

参照リポジトリの追加。

```
# cobbler repo add --name f21-base --mirror http://ftp.iij.ad.jp/pub/linux/fedora/releases/21/Everything/x86_64/os --mirror-locally 0
# cobbler repo add --name f21-updates --mirror http://ftp.iij.ad.jp/pub/linux/fedora/updates/21/x86_64 --mirror-locally 0
# cobbler repo add --name f21-updates-testing --mirror http://ftp.iij.ad.jp/pub/linux/fedora/updates/testing/21/x86_64 --mirror-locally 0 --yumopts "enabled=0"
# cobbler reposync
```

プロファイルの設定。

```
# cp /var/lib/cobbler/kickstarts/sample_end.ks /var/lib/cobbler/kickstarts/f21.ks
# cobbler profile edit --name f21-x86_64 --repos "f21-base f21-updates f21-updates-testing" --kickstart /var/lib/cobbler/kickstarts/f21.ks
```

スニペットはCentOS 7のものと同じものを使用する。

```txt:/var/lib/cobbler/snippets/yum_repo_proxy_config
#set $repo_data = $getVar("repo_data",[])
#for $repo in $repo_data
  #set $enabled = '1'
  #if $repo.yumopts.has_key('enabled')
    #set $enabled = $repo.yumopts.enabled
  #end if
  #if $enabled == '1'
repo --name=${repo.name} --proxy=http://$http_server:8080 --baseurl=${repo.mirror}
  #end if
#end for
```

kickstartテンプレートファイルの編集。

```
# sed -ri "s/(^auth ).*/\1--enableshadow --passalgo=sha512/" /var/lib/cobbler/kickstarts/f21.ks
# sed -ri "s/(^keyboard ).*/\1--vckeymap=jp106 --xlayouts='jp'/" /var/lib/cobbler/kickstarts/f21.ks
# sed -ri "s|(^timezone ).*|\1--utc Asia/Tokyo|" /var/lib/cobbler/kickstarts/f21.ks
# sed -i "s/^\\\$yum_repo_stanza$/\$SNIPPET('yum_repo_proxy_config')/" /var/lib/cobbler/kickstarts/f21.ks
# sed -i '/^%packages$/a\yum-utils' /var/lib/cobbler/kickstarts/f21.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable fedora" /var/lib/cobbler/kickstarts/f21.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable updates" /var/lib/cobbler/kickstarts/f21.ks
# sed -i "/^# End yum configuration$/i\yum-config-manager --disable core-0" /var/lib/cobbler/kickstarts/f21.ks
# sed -i "/^# End yum configuration$/i\echo 'proxy=http://\$http_server:8080' >> /etc/yum.conf" /var/lib/cobbler/kickstarts/f21.ks
```

# Fedora 22の追加

2015-06-27現在、最新のsignatureファイルではFedora 22が追加できない。
signatureファイル /var/lib/cobbler/distro_signatures.json のFedora 17以降のものをコピーして22に書き換えると良い。

```json:/var/lib/cobbler/distro_signatures.json(追加部分)
   "fedora22": {
    "signatures":["Packages"],
    "version_file":"(fedora)-release-22-(.*)\\.noarch\\.rpm",
    "version_file_regex":null,
    "kernel_arch":"kernel-(.*)\\.rpm",
    "kernel_arch_regex":null,
    "supported_arches":["i386","x86_64","ppc","ppc64"],
    "supported_repo_breeds":["rsync", "rhn", "yum"],
    "kernel_file":"vmlinuz(.*)",
    "initrd_file":"initrd(.*)\\.img",
    "isolinux_ok":false,
    "default_kickstart":"/var/lib/cobbler/kickstarts/sample_end.ks",
    "kernel_options":"repo=$tree",
    "kernel_options_post":"",
    "boot_files":[]
   },
```

ちなみに最新のsignatureファイルのURLが http://cobbler.github.io/signatures/latest.json に変更されているのでCobbler 2.6.7の`cobbler signature update`では取得できないようになっている。

/var/lib/cobbler/distro_signatures.json を変更したらcobblerd.serviceを再起動して反映させる。

```
# systemctl restart cobblerd.service
```

Fedora 22のISOの中でインポート可能な最小のものはFedora-Server-DVD-x86_64-22.isoだと思われるのでこれをダウンロード。

```
# curl http://ftp.iij.ad.jp/pub/linux/fedora/releases/22/Server/x86_64/iso/Fedora-Server-DVD-x86_64-22.iso -o Fedora-Server-DVD-x86_64-22.iso
```

後はCentOS 7と手順はほぼ一緒だがyumがdnfに変わるのでkickstartをそれ用に変更する。

インポート。

```
# mount Fedora-Server-DVD-x86_64-22.iso /mnt
# cobbler import --name f22 --path /mnt
# umount /mnt
```

参照リポジトリの追加。

```
# cobbler repo add --name f22-base --mirror http://ftp.iij.ad.jp/pub/linux/fedora/releases/22/Everything/x86_64/os --mirror-locally 0
# cobbler repo add --name f22-updates --mirror http://ftp.iij.ad.jp/pub/linux/fedora/updates/22/x86_64 --mirror-locally 0
# cobbler repo add --name f22-updates-testing --mirror http://ftp.iij.ad.jp/pub/linux/fedora/updates/testing/22/x86_64 --mirror-locally 0 --yumopts "enabled=0"
# cobbler reposync
```

プロファイルの設定。

```
# cp /var/lib/cobbler/kickstarts/sample_end.ks /var/lib/cobbler/kickstarts/f22.ks
# cobbler profile edit --name f22-x86_64 --repos "f22-base f22-updates f22-updates-testing" --kickstart /var/lib/cobbler/kickstarts/f22.ks
```

スニペットはCentOS 7のものと同じものを使用する。

```txt:/var/lib/cobbler/snippets/yum_repo_proxy_config
#set $repo_data = $getVar("repo_data",[])
#for $repo in $repo_data
  #set $enabled = '1'
  #if $repo.yumopts.has_key('enabled')
    #set $enabled = $repo.yumopts.enabled
  #end if
  #if $enabled == '1'
repo --name=${repo.name} --proxy=http://$http_server:8080 --baseurl=${repo.mirror}
  #end if
#end for
```

kickstartテンプレートファイルの編集。
yum-config-managerを使わないのでyum-utilsは不要。代わりにdnf config-manager（追加パッケージは不要）を使用する。

```
# sed -ri "s/(^auth ).*/\1--enableshadow --passalgo=sha512/" /var/lib/cobbler/kickstarts/f22.ks
# sed -ri "s/(^keyboard ).*/\1--vckeymap=jp106 --xlayouts='jp'/" /var/lib/cobbler/kickstarts/f22.ks
# sed -ri "s|(^timezone ).*|\1--utc Asia/Tokyo|" /var/lib/cobbler/kickstarts/f22.ks
# sed -i "s/^\\\$yum_repo_stanza$/\$SNIPPET('yum_repo_proxy_config')/" /var/lib/cobbler/kickstarts/f22.ks
# sed -i "/^# End yum configuration$/i\dnf config-manager --set-disabled fedora updates core-0" /var/lib/cobbler/kickstarts/f22.ks
# sed -i "/^# End yum configuration$/i\dnf config-manager --setopt proxy=http://\$http_server:8080/ --save" /var/lib/cobbler/kickstarts/f22.ks
```

# さいごに

この方法、パブリックミラーがHTTPじゃなくHTTPSになったら崩壊する。
nginxはHTTPSをプロキシできないようだし、squidとか使ってもHTTPSの場合にキャッシュできるかどうか調べてない。
まあ、そうなってから考えよう。