前回、RHEL系のLinuxで使用出来るKickstartを用いた自動インストールディスクを作成したので、今回はDebian系のツールPreseedを用いたディスクを作成してみる。 使用するOSはUbuntu  Server14.04とする。 なお、通常のUbuntu Desktopではこの設定は使えないので注意。 というのが、「/isolinux/isolinux.cfg」で指定するkernel等の場所が、Desktop版とServer版とで相違があるためだ。

1.Kickstartとの違い

Preseedは、Debian系Linux用の自動インストールツールだ。基本的に、やれることはKickstartと変わらない。 ただ。Kickstartと違ってGUIでのconfigファイル作成ツールというものが存在しない。 そのため、Kickstartに比べると少し導入難易度は高いかもしれない。

2.configファイルの作成

さて、まずは早速configファイルの作成を行っていく。今回は、静的IPアドレスを自動的に設定させるために、以前書いたこちらのスクリプトを実行させる。 英語のページからサンプルを取得している(+わざわざ設定内容を日本語に直すのがダルかった)ため、細かい値は参考ページ等を参照しながら環境に合わせてもらいたい。 なお、Preseedの仕様なのかなんなのか不明だが、どうも「d-i preseed/late_command」で直接IPアドレス設定スクリプトを実行させても、「d-i netcfg」で指定している設定内容に上書きされるというウザイ仕様があるようだ。 そのため、ここでは「/etc/rc.local」に一時的にスクリプトの実行命令を記述し、スクリプト側でその記述を削除させるようにする。

●custom.seed

## ========================================================
## コマンドラインオプションの設定
## ========================================================
d-i debian-installer/locale string en_US.utf8
d-i console-setup/ask_detect boolean false
d-i console-setup/layout string us

d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string unassigned-domain

d-i time/zone string UTC
d-i clock-setup/utc-auto boolean true
d-i clock-setup/utc boolean true

d-i kbd-chooser/method select American English

d-i netcfg/choose_interface select auto

d-i base-installer/kernel/override-image string linux-server

d-i debconf debconf/frontend select Noninteractive

d-i pkgsel/install-language-support boolean false
tasksel tasksel/first multiselect standard, ubuntu-server

d-i partman-auto/method string lvm

d-i partman-lvm/confirm boolean true
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-auto/choose_recipe select atomic

d-i partman/confirm_write_new_label boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true

## ========================================================
# ディスクパーティションの設定
## ========================================================
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto-lvm/guided_size string max

## ========================================================
# ユーザ名の設定
## ========================================================
d-i passwd/user-fullname string test
d-i passwd/username string test
d-i passwd/user-password password test
d-i passwd/user-password-again password test
d-i user-setup/encrypt-home boolean false
d-i user-setup/allow-password-weak boolean true

## ========================================================
# パッケージインストール
## ========================================================
d-i pkgsel/include string openssh-server \
 ntp \
 ruby

d-i pkgsel/upgrade select none

d-i grub-installer/only_debian boolean true
d-i grub-installer/with_other_os boolean true
d-i finish-install/reboot_in_progress note

d-i pkgsel/update-policy select none

choose-mirror-bin mirror/http/proxy string

## ========================================================
# スクリプト実行
## ========================================================

d-i preseed/late_command string \
 in-target cp -r /media/cdrom/work/ /; \
 in-target sed -i -e "/^exit 0/i bash /work/setip.sh" /etc/rc.local

2.静的IPアドレス自動設定スクリプトの作成

次に、各機器のシリアルナンバー別に固定IPアドレスを設定するスクリプトを作成、設置する。 こちらは、以前書いたスクリプトをベースに修正を加えるだけだ。 まずは外部ファイルである「host.list」。

●host.list

hostname,serialno,defaultgw,nic0,nic1
Test-CentOS001,564D33C9F632AB40148800E9CA90D059,192.168.0.1,192.168.0.31/24,172.26.0.31/24
Test-CentOS002,564DAB560AE59CD285EDCFE97F5A9E64,192.168.0.1,192.168.0.32/24,172.26.0.32/24
Test-CentOS003,564DF163D810265B56707D081C45716F,192.168.0.1,192.168.0.33/24,172.26.0.33/24
Test-Ubuntu001,564DC8A6D8F477D20B15335663B0FB98,192.168.0.1,192.168.0.30/24,172.26.0.30/24

次はスクリプト「setip.sh」を作成する。

●setip.sh

#!/bin/bash

function get_network()
{
        local NETWORK=""
        local BROADCAST=""
        local NETMASK=""

        local IPADDR="$1"
        local MASKBIT="$2"

        local ip_array=(`echo "$IPADDR" | sed -e "s/\./ /g"`)
        local ip_index=0

        while [ $ip_index -lt 4 ]
        do
                if [ "$MASKBIT" -lt 8 ]
                then
                        MASK=$((256-2**$((8-MASKBIT))))
                        MASK_REV=$((~MASK%256+256))
                        MASKBIT=0
                else
                        MASK=255
                        MASK_REV=0
                        MASKBIT=$((MASKBIT - 8))
                fi

                NETWORK="${NETWORK}.$((ip_array[ip_index] && MASK))"
                BROADCAST="${BROADCAST}.$((ip_array[ip_index] | MASK_REV))"
                NETMASK="${NETMASK}.$MASK"

                ip_index=$((ip_index + 1))
        done

        NETWORK=`echo $NETWORK | sed -e "s/^\.//"`
        BROADCAST=`echo $BROADCAST | sed -e "s/^\.//"`
        NETMASK=`echo $NETMASK | sed -e "s/^\.//"`

        echo "$NETWORK $BROADCAST $NETMASK"
}

LIST="./host.list"
NIC0="eth0"
NIC1="eth1"

SCRIPT_DIR=`dirname $0`
cd $SCRIPT_DIR

MYSERIAL_CD=`dmidecode | grep UUID | awk 'BEGIN { FS=": "; } { print $2; }' | sed -e "s/-//g"`

IFCFGNIC0="ifcfg-${NIC0}"
IFCFGNIC1="ifcfg-${NIC1}"

if [ -z `cat $LIST | grep $MYSERIAL_CD` ]; then
    echo "It did not exist in [$ LIST] within [$ MYSERIAL_CD]"
    echo ""
    exit 1
fi

#Host Name
HOSTNAME=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $1 }'`

#Default Gateway
GATEWAY=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $3 }' | awk 'BEGIN {FS="/"} {print $1}'`

#NIC0
NIC0_IPADDR=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC0_PREFIX=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $4 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC0_HWADDR=`ifconfig $NIC0 | grep HWaddr | awk '{print $5}'`

NIC0_NEINFO=(`get_network "$NIC0_IPADDR" "$NIC0_PREFIX"`)
NIC0_NEADDR=${NIC0_NEINFO[0]}
NIC0_BRADDR=${NIC0_NEINFO[1]}
NIC0_PRMASK=${NIC0_NEINFO[2]}

#NIC1
NIC1_IPADDR=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $5 }' | awk 'BEGIN {FS="/"} {print $1}'`
NIC1_PREFIX=`cat $LIST | grep $MYSERIAL_CD | awk 'BEGIN {FS=","} { print $5 }' | awk 'BEGIN {FS="/"} {print $2}'`
NIC1_HWADDR=`ifconfig $NIC1 | grep HWaddr | awk '{print $5}'`

NIC1_NEINFO=(`get_network "$NIC1_IPADDR" "$NIC1_PREFIX"`)
NIC1_NEADDR=${NIC1_NEINFO[0]}
NIC1_BRADDR=${NIC1_NEINFO[1]}
NIC1_PRMASK=${NIC1_NEINFO[2]}

#create ifcfg-*
cd /etc/network/

echo "# The loopback network interface"  >  interfaces
echo "auto lo"                           >> interfaces
echo "iface lo inet loopback"            >> interfaces
echo ""                                  >> interfaces

#ifcfg-NIC0
echo "# The primary network interface"   >> interfaces
echo "auto $NIC0"                        >> interfaces
echo "iface $NIC0 inet static"           >> interfaces
echo "address $NIC0_IPADDR"              >> interfaces
echo "network $NIC0_NEADDR"              >> interfaces
echo "netmask $NIC0_PRMASK"              >> interfaces
echo "broadcast $NIC0_BRADDR"            >> interfaces
echo "gateway $GATEWAY"                  >> interfaces
echo ""                                  >> interfaces

#ifcfg-NIC1
echo "# The secondery network interface" >> interfaces
echo "auto $NIC1"                        >> interfaces
echo "iface $NIC1 inet static"           >> interfaces
echo "address $NIC1_IPADDR"              >> interfaces
echo "network $NIC1_NEADDR"              >> interfaces
echo "netmask $NIC1_PRMASK"              >> interfaces
echo "broadcast $NIC1_BRADDR"            >> interfaces
echo "gateway $GATEWAY"                  >> interfaces
echo ""                                  >> interfaces

#set hostname
echo "$HOSTNAME"                         >  /etc/hostname
sed -i -e "/^127.0.1.1/c\127.0.1.1       $HOSTNAME" /etc/hosts

sed -i -e "/^bash/d" /etc/rc.local
reboot

さて、これでスクリプト(+外部ファイル)、preseedの設定ファイルが出来た。

3.インストールディスクからコピー

さて、後は自動インストールディスクの作成を行うため、一時的に通常のインストールメディアから中身を吸い出す。 適当なフォルダを作成し、以下のコマンドを実行して中身の吸い出しを行う。

test@Test-UbuntuOS004:~$ mkdir /home/test/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM
test@Test-UbuntuOS004:~$ cd /media/test/Ubuntu-Server\ 14.04\ LTS\ amd64/
test@Test-UbuntuOS004:/media/test/Ubuntu-Server 14.04 LTS amd64$ find . -maxdepth 1 -mindepth 1 -exec cp -rp {} /home/test/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM \;

中身を吸い出したフォルダに移動し、各ファイルをそれぞれ設置していく。

test@Test-UbuntuOS004:/media/test/Ubuntu-Server 14.04 LTS amd64$ cd /home/test/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM/
test@Test-UbuntuOS004:~/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM$
test@Test-UbuntuOS004:~/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM$ cp ../custom.seed preseed/custom.seed
test@Test-UbuntuOS004:~/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM$ mkdir work
test@Test-UbuntuOS004:~/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM$ cp ../host.list work/host.list
test@Test-UbuntuOS004:~/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM$ cp ../setip.sh work/setip.sh

なお、ここではディスクイメージの一番上の階層に「work」フォルダを作成し、その中にスクリプト関係のファイルを設置している。

4.isolinux.cfgの作成

さて、次は「/isolinux/isolinux.cfg」の作成を行う。 これについは、ファイルの内容を以下に書き換えてもらいたい。

default install
label install
 menu label ^Install Ubuntu Server
 kernel /install/vmlinuz
 append auto=true pkgsel/language-pack-patterns= pkgsel/install-language-support=false vga=normal file=/cdrom/preseed/custom.seed initrd=/install/initrd.gz quiet --
label hd
 menu label ^Boot from first hard disk
 localboot 0x80

5.ISOファイルへの書き込み

さて、これでISOファイルへの書き込み準備が出来た。 以下のコマンドを実行し、書き込みを行う。

test@Test-UbuntuOS004:~/ダウンロード/Ubuntu_Server_14.04_LTS_CUSTOM$ sudo genisoimage -N -J -R -D -V "PRESEED" -o ../Ubuntu_Server_14.04_LTS_CUSTOM.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table .

後は、事前にシリアルナンバーを確認している筐体に、このISOファイル(もしくは、ISOを焼いたディスク)を挿入してブートさせるだけだ。 これで、構築も多少は自動化されるだろう。


参考サイト

今回は、以下のサイトを参考に対応を進めた。 ありがとうございます。