Fabric テンプレート アップロード

Fabric decorators task」でディストリビューションやOSごとにファイルを分割してタスクを書けるようにした。今回はインストールスルクリプトをテンプレート化してアップロードするタスクを書いてみる。

$ vi __init__.py
from fabric.api import env
from fabric.decorators import task

from . import debian
from . import centos
from . import gentoo
from . import freebsd

@task
def server():
  env.hosts = ['192.168.0.1']
  env.port = 22
  env.user = 'root'
$ vi debian.py
from fabric.decorators import task
from fabric.contrib.files import upload_template

@task
def upload(macaddress, disk, hostname, ipaddress, netmask, gateway,
    source_template, dest_template):

    upload_template(
      source_template,
      dest_template,
      context={
        'macaddress': macaddress,
        'disk': disk,
        'hostname': hostname,
        'ipaddress': ipaddress,
        'netmask': netmask,
        'gateway': gateway,
      },
      use_jinja=True,
    )
$ mkdir templates
$ vi templates/debian_template.conf
#!/bin/bash -x

# {{ macaddress }}

DISK=/dev/{{ disk }}
IFACE=$1
CWD=$2
CHROOT_DEBIAN="/mnt/$3"

dd if=/dev/zero of=$DISK bs=1024 count=1

parted $DISK -s 'mklabel msdos'
parted $DISK -s 'mkpart primary 1 500'
parted $DISK -s 'mkpart primary 501 35000'
parted $DISK -s 'mkpart extended 35001 -0'
parted $DISK -s 'mkpart logical 35001 38000'
parted $DISK -s 'mkpart logical 38001 -0'
parted $DISK -s 'set 1 boot on'

mkswap ${DISK}5
swapon ${DISK}5
mkfs.ext2 ${DISK}1
mkfs.ext4 ${DISK}2
mkfs.ext4 ${DISK}6

mkdir $CHROOT_DEBIAN

mount ${DISK}2 ${CHROOT_DEBIAN}

cp -Rp ${CWD}/wheezy/* $CHROOT_DEBIAN

mount ${DISK}1 ${CHROOT_DEBIAN}/boot
mount ${DISK}6 ${CHROOT_DEBIAN}/home

mount --rbind /dev ${CHROOT_DEBIAN}/dev
mount -t proc none ${CHROOT_DEBIAN}/proc
mount --rbind /sys ${CHROOT_DEBIAN}/sys

cat << EOF > ${CHROOT_DEBIAN}/etc/hostname
{{ hostname }}
EOF


cat << EOF > ${CHROOT_DEBIAN}/etc/resolv.conf
nameserver 8.8.8.8
EOF

cat << EOF > ${CHROOT_DEBIAN}/etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address {{ ipaddress }}
netmask {{ netmask }}
gateway {{ gateway }}
EOF

cat << EOF > ${CHROOT_DEBIAN}/etc/fstab
${DISK}1               /boot           ext2            defaults        0 2
${DISK}2               /               ext4            defaults        0 1
${DISK}6               /home           ext4            defaults        0 2
${DISK}5               none            swap            sw              0 0
EOF

cat << EOF > ${CHROOT_DEBIAN}/tmp/debian_setup.sh
export DEBIAN_FRONTEND=noninteractive
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
grep -v rootfs /proc/mounts > /etc/mtab

apt-get install -y linux-image-`uname -r` grub2 openssh-server

grub-mkconfig -o /boot/grub/grub.cfg
grub-install --no-floppy --root-directory=/ $DISK
EOF

cat << 'EOF' > ${CHROOT_DEBIAN}/tmp/user_acount.sh
useradd -m -G sudo nanashi
printf 'nanashi:$6$oHUVG9WPkdiCoxCP$XsnO5TmowzdGWNkZHv9pPUmFqgsEojkfzUa1OQj2zUOWAChL5cdGkm.dhseF0z5Tz30IEDrxNzOcsflPUgHDs.' | chpasswd -e
printf 'root:$6$wAeDl/exZFEDC0Sl$UdvTamL.94EcWFcGIAYJSgsvzaFxSd.ZLRMkD.KI27L6jxUGsWqOdEJs6if0rTG/XuEfQ9TNzHbjI99YfxPLD1' | chpasswd -e
EOF

chroot ${CHROOT_DEBIAN} /bin/bash /tmp/debian_setup.sh
chroot ${CHROOT_DEBIAN} /bin/bash /tmp/user_acount.sh

rm ${CHROOT_DEBIAN}/tmp/debian_setup.sh
rm ${CHROOT_DEBIAN}/tmp/user_acount.sh

cd /
umount -l ${CHROOT_DEBIAN}/{boot,home,proc,dev,sys}
umount -l $CHROOT_DEBIAN
sleep 2
rmdir $CHROOT_DEBIAN
reboot

Pythonのweb frameworkのひとつFlaskに使用されているテンプレートエンジンJinjaが、Fabricでも使えるようなのでuse_jinja=Trueして使うことにする。{{ hoge }}で囲まれた部分が変数展開される。

$ fab -l
Available commands:

    server
    centos.cmd
    debian.upload
    freebsd.cmd
    gentoo.cmd
$ fab server debian.upload:macaddress="01:23:45:67:89:ab",disk="vda",hostname="hoge.localnet",ipaddress="192.168.0.50",netmask="255.255.255.0",gateway="192.168.0.254",source_template="templates/debian_template.conf",dest_template="/var/diskless/scripts/debian_template.conf"