Created
March 15, 2011 14:40
-
-
Save matsuu/870789 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
#=============================================================================== | |
# | |
# USAGE | |
# ===== | |
# | |
# Get your X.509 Certificates and Private Key | |
# ------------------------------------------- | |
# http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key | |
# Download your cert-*.pem and pk-*.pem. | |
# | |
# Launch Amazon Linux AMI instance | |
# -------------------------------- | |
# If you want: | |
# - Gentoo x86 AMI, select 'Basic 32-bit Amazon Linux AMI'. | |
# - Gentoo amd64 AMI, select 'Basic 64-bit Amazon Linux AMI'. | |
# | |
# Copy this program and X.509 Certificates to your AMI instance | |
# ------------------------------------------------------------- | |
# $ scp -i your_ssh_key.pem create_gentoo_ami.sh ec2-user@<your.instance> | |
# $ scp -i your_ssh_key.pem pk-*.pem ec2-user@<your.instance> | |
# $ scp -i your_ssh_key.pem cert-*.pem ec2-user@<your.instance> | |
# | |
# Login your AMI instance and execute this program | |
# ------------------------------------------------ | |
# Login as ec2-user. | |
# | |
# $ ssh -i your_ssh_key.pem ec2-user@<your.instance> | |
# $ sudo sh create_gentoo_ami.sh | |
# ... | |
# Finished! | |
# | |
# Launch your Gentoo instance | |
# --------------------------- | |
# You can boot Gentoo instance from IMAGES/AMIs. | |
# | |
# Login your Gentoo instance | |
# -------------------------- | |
# Login as root. | |
# | |
# $ ssh -i your_ssh_key.pem root@<your.instance> | |
# | |
# Emerge logger and cron | |
# ---------------------- | |
# # emerge --sync | |
# # emerge syslog-ng | |
# # rc-update add syslog-ng default | |
# # emerge vixie-cron | |
# # rc-update add vixie-cron default | |
# | |
# | |
#=============================================================================== | |
#AMI_NAME_SUFFIX="[email protected]" | |
EC2_PRIVATE_KEY="`ls /home/ec2-user/pk-*.pem | head -n 1`" | |
EC2_CERT="`ls /home/ec2-user/cert-*.pem | head -n 1`" | |
#EC2_PRIVATE_KEY="/home/ec2-user/pk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem" | |
#EC2_CERT="/home/ec2-user/cert-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.pem" | |
# ftp:// is required for glob | |
GENTOO_MIRROR="ftp://ftp.iij.ad.jp/pub/linux/gentoo" | |
# Set AMI HDD size. default is 8GB | |
VOLUME_SIZE=8 | |
# Set timeszone. cf. /usr/share/zoneinfo/ | |
TIMEZONE="UTC" | |
#TIMEZONE="Asia/Tokyo" | |
#=============================================================================== | |
die() { | |
echo $@ | |
exit 1 | |
} | |
EC2_INSTANCE_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/instance-id`" | |
test -n "$EC2_INSTANCE_ID" || die 'cannot obtain instance-id' | |
EC2_KERNEL_ID="`wget -q -O - http://169.254.169.254/latest/meta-data/kernel-id`" | |
test -n "$EC2_KERNEL_ID" || die 'cannot obtain kernel-id' | |
EC2_AVAIL_ZONE="`wget -q -O - http://169.254.169.254/latest/meta-data/placement/availability-zone`" | |
test -n "$EC2_AVAIL_ZONE" || die 'cannot obtain availability-zone' | |
EC2_REGION="`echo \"$EC2_AVAIL_ZONE\" | sed -e 's:\([0-9]\+\)[a-z]*\$:\\1:'`" | |
EC2_URL="https://ec2.${EC2_REGION}.amazonaws.com" | |
EC2_HOME="/opt/aws/apitools/ec2" | |
JAVA_HOME="/usr/lib/jvm/jre" | |
export EC2_PRIVATE_KEY EC2_CERT EC2_URL EC2_HOME JAVA_HOME | |
create_ami() { | |
local PROFILE=$1 | |
local STAGE_FILE | |
local ESELECT_PROFILE | |
if [ "${PROFILE}" = "hardened" ] ; then | |
STAGE_FILE="hardened/stage3-${STAGE_ARCH}-hardened" | |
ESELECT_PROFILE="hardened/linux/${ARCH}" | |
elif [ "${PROFILE}" = "hardened-no-multilib" ] ; then | |
STAGE_FILE="hardened/stage3-${STAGE_ARCH}-hardened+nomultilib" | |
ESELECT_PROFILE="hardened/linux/${ARCH}/no-multilib" | |
elif [ "${PROFILE}" = "server" ] ; then | |
STAGE_FILE="stage3-${STAGE_ARCH}" | |
ESELECT_PROFILE="default/linux/${ARCH}/10.0/server" | |
elif [ "${PROFILE}" = "no-multilib" ] ; then | |
STAGE_FILE="stage3-${STAGE_ARCH}" | |
ESELECT_PROFILE="default/linux/${ARCH}/10.0/no-multilib" | |
fi | |
STAGE_TARBALL="${GENTOO_MIRROR}/releases/${ARCH}/current-stage3/${STAGE_FILE}-*.tar.bz2" | |
echo "create volume" | |
EC2_VOLUME_ID="`/opt/aws/bin/ec2-create-volume -s ${VOLUME_SIZE} -z \"${EC2_AVAIL_ZONE}\" | cut -f2`" || die "ec2-create-volume failed" | |
counter=0 | |
while [ $counter -lt 60 ] ; do | |
echo "get volume ${EC2_VOLUME_ID} status..." | |
status="`/opt/aws/bin/ec2-describe-volumes ${EC2_VOLUME_ID}| cut -f6`" || die "ec2-describe-volumes failed" | |
echo "volume status...$status" | |
if [ -z "$status" ] ; then | |
die "ec2-describe-volumes status failed" | |
fi | |
if [ "$status" = "available" ] ; then | |
break | |
fi | |
sleep 1 | |
counter=`expr $counter + 1` | |
done | |
if [ $counter -ge 60 ] ; then | |
die "ec2-volume-snapshots timeout" | |
fi | |
echo "attach volume ${EC2_VOLUME_ID}" | |
/opt/aws/bin/ec2-attach-volume "${EC2_VOLUME_ID}" -i "${EC2_INSTANCE_ID}" -d "${VOLUME_DEVICE}" || die "ec2-attach-volume failed" | |
counter=0 | |
while [ $counter -lt 60 ] ; do | |
echo "checking ${VOLUME_DEVICE}..." | |
if [ -e "${VOLUME_DEVICE}" ] ; then | |
break | |
fi | |
sleep 3 | |
counter=`expr $counter + 1` | |
done | |
if [ ! -e "${VOLUME_DEVICE}" ] ; then | |
die "${VOLUME_DEVICE} not found" | |
fi | |
mkfs.ext4 -j -L / "${VOLUME_DEVICE}" || die "mke2fs failed" | |
mkdir -p "${MOUNT_POINT}" || die "mkdir mountpoint failed" | |
mount "${VOLUME_DEVICE}" "${MOUNT_POINT}" || die "mount mountpoint failed" | |
cd "${MOUNT_POINT}" || die "cd mountpoint failed" | |
if [ ! -d "usr" ] ; then | |
wget "${STAGE_TARBALL}" || die "wget stage file failed" | |
tar jxpf stage3*.bz2 || die "unpack stage file failed" | |
fi | |
if [ ! -d "usr/portage" ] ; then | |
wget "${PORTAGE_SNAPSHOT}" || die "wget stage file failed" | |
tar jxf portage-latest.tar.bz2 -C "${MOUNT_POINT}/usr" || die "unpack stage file failed" | |
# sed -i -e "s/-march=[^ ]*/-march=core2/" "${MOUNT_POINT}/etc/make.conf" | |
echo "USE=\"\${USE} perl python\"" >> "${MOUNT_POINT}/etc/make.conf" | |
# echo "USE=\"\${USE} -gpm -pppd\"" >> "${MOUNT_POINT}/etc/make.conf" | |
fi | |
cp -L /etc/resolv.conf "${MOUNT_POINT}/etc/resolv.conf" || die "cp resolv.conf failed" | |
rsync -avz /boot/ "${MOUNT_POINT}/boot/" || die "rsync /boot failed" | |
rsync -avz /lib/modules/ "${MOUNT_POINT}/lib/modules/" || die "rsync /lib/modules failed" | |
sed -i \ | |
-e "s/Amazon/Gentoo/" \ | |
-e "/^kernel/s/$/ xencons=hvc0/" \ | |
"${MOUNT_POINT}/boot/grub/grub.conf" || die "sed failed" | |
mount -t proc none "${MOUNT_POINT}/proc" || die "mount /proc failed" | |
mount -o bind /dev "${MOUNT_POINT}/dev" || die "mount /dev failed" | |
cat > "${MOUNT_POINT}/install.sh" <<EOF | |
#!/bin/sh | |
die() { | |
echo \$@ | |
exit 1 | |
} | |
/usr/sbin/env-update | |
source /etc/profile | |
emerge --sync # || die "emerge --sync failed" | |
eselect profile set ${ESELECT_PROFILE} || die "eselect profile failed" | |
if [ -n "${TIMEZONE}" ] ; then | |
cp "/usr/share/zoneinfo/${TIMEZONE}" /etc/localtime || die "cp localtime failed" | |
fi | |
mkdir -p /etc/portage | |
echo "app-admin/amazon-ec2-init ~${ARCH}" > /etc/portage/package.keywords | |
emerge amazon-ec2-init || die "emerge amazon tools failed" | |
rc-update add amazon-ec2 boot || die "rc-update amazon-ec2 failed" | |
depmod -a | |
cat > /etc/fstab << CHROOT_EOF | |
LABEL=/ / ext4 defaults,noatime 0 1 | |
proc /proc proc defaults 0 0 | |
shm /dev/shm tmpfs nodev,nosuid,noexec 0 0 | |
CHROOT_EOF | |
sed -i -e 's/#rc_sys=""/rc_sys="xenU"/' /etc/rc.conf | |
#cat > /etc/conf.d/net << CHROOT_EOF | |
#config_eth0="dhcp" | |
#CHROOT_EOF | |
if [ ! -e /etc/init.d/net.eth0 ] ; then | |
ln -s net.lo /etc/init.d/net.eth0 | |
fi | |
rc-update add net.eth0 default || die "rc-update net.eth0 failed" | |
#emerge syslog-ng || die "emerge syslog-ng failed" | |
#rc-update add syslog-ng default || die "rc-update syslog-ng failed" | |
#emerge vixie-cron || die "emerge vixie-cron failed" | |
#rc-update add vixie-cron default || die "rc-update vixie-cron failed" | |
rc-update add sshd default || die "rc-update sshd failed" | |
emerge dhcpcd || die "emerge dhcpcd failed" | |
# Amazon specific setting | |
echo "PermitRootLogin without-password" >> /etc/ssh/sshd_config || die "sshd_config setting failed" | |
echo "UseDNS no" >> /etc/ssh/sshd_config || die "sshd_config setting failed" | |
if [ -n "${TIMEZONE}" ] ; then | |
sed -i \ | |
-e "/^clock=/s:=.*:=\"local\":" \ | |
/etc/conf.d/hwclock || die "clock setting failed" | |
echo "${TIMEZONE}" >> /etc/timezone || die "timezone setting failed" | |
fi | |
if [ -e /etc/conf.d/local ] ; then | |
sed -i \ | |
-e "/on startup/a pkill -9 nash" \ | |
/etc/conf.d/local || die "sed /etc/conf.d/local failed" | |
fi | |
if [ -e /etc/conf.d/local.start ] ; then | |
echo "pkill -9 nash" >> /etc/conf.d/local.start || die "added to /etc/conf.d/local.start failed" | |
fi | |
if [ -d /etc/local.d/ ] ; then | |
echo "pkill -9 nash" > /etc/local.d/kill_nash.start || die "generate /etc/local.d/kill_nash.start failed" | |
chmod +x /etc/local.d/kill_nash.start || die "chmod /etc/local.d/kill_nash.start failed" | |
fi | |
grep -v rootfs /proc/mounts > /etc/mtab || die "override /etc/mtab failed" | |
cat > /etc/motd << CHROOT_EOF | |
At first, emerge logger and cron. | |
# emerge --sync | |
# emerge syslog-ng | |
# rc-update add syslog-ng default | |
# emerge vixie-cron | |
# rc-update add vixie-cron default | |
# rm /etc/motd | |
CHROOT_EOF | |
rm -f /usr/portage/distfiles/* | |
exit 0 | |
EOF | |
chmod +x "${MOUNT_POINT}/install.sh" || die "chmod install.sh failed" | |
LANG=en_US.UTF-8 chroot "${MOUNT_POINT}" "/install.sh" || die "chroot failed" | |
if [ $? != 0 ] ; then | |
die "chroot failed" | |
fi | |
rm "${MOUNT_POINT}/install.sh" || die "rm install.sh failed" | |
rm "${MOUNT_POINT}/"stage3* || die "rm stage3 failed" | |
rm "${MOUNT_POINT}/portage-latest.tar.bz2" || die "rm portage-latest failed" | |
cd `dirname "${MOUNT_POINT}"` | |
umount "${MOUNT_POINT}/dev" "${MOUNT_POINT}/proc" "${MOUNT_POINT}" || die "umount failed" | |
rmdir "${MOUNT_POINT}" || die "rmdir mount_point failed" | |
DESCRIPTION="gentoo-${OS_BIT}-${PROFILE}-`date +%Y%m%d`${AMI_NAME_SUFFIX:+-}${AMI_NAME_SUFFIX}" | |
echo "create snapshot" | |
EC2_SNAPSHOT_ID="`/opt/aws/bin/ec2-create-snapshot -d \"${DESCRIPTION}\" \"${EC2_VOLUME_ID}\" | cut -f2`" || die "ec2-create-snapshot failed" | |
counter=0 | |
while [ $counter -lt 60 ] ; do | |
echo "get snapshot status..." | |
status="`/opt/aws/bin/ec2-describe-snapshots -F snapshot-id=${EC2_SNAPSHOT_ID} | cut -f4`" || die "ec2-describe-snapshots failed" | |
echo "snapshot status...$status" | |
if [ -z "$status" ] ; then | |
die "ec2-describe-snapshots status failed" | |
fi | |
if [ "$status" = "completed" ] ; then | |
break | |
fi | |
sleep 1 | |
counter=`expr $counter + 1` | |
done | |
if [ $counter -ge 60 ] ; then | |
die "ec2-describe-snapshots timeout" | |
fi | |
echo "register AMI" | |
/opt/aws/bin/ec2-register -n "${DESCRIPTION}" -d "Gentoo Linux ${ARCH} ${PROFILE}" -a "${EC2_ARCH}" --kernel "${EC2_KERNEL_ID}" -b "/dev/sda1=${EC2_SNAPSHOT_ID}" || die "ec2-register failed" | |
echo "detach volume" | |
/opt/aws/bin/ec2-detach-volume "${EC2_VOLUME_ID}" || die "ec2-detach-volume failed" | |
counter=0 | |
while [ $counter -lt 60 ] ; do | |
echo "get volume ${EC2_VOLUME_ID} status..." | |
status="`/opt/aws/bin/ec2-describe-volumes ${EC2_VOLUME_ID}| cut -f6`" || die "ec2-describe-volumes failed" | |
echo "volume status...$status" | |
if [ -z "$status" ] ; then | |
die "ec2-describe-volumes status failed" | |
fi | |
if [ "$status" = "available" ] ; then | |
break | |
fi | |
sleep 1 | |
counter=`expr $counter + 1` | |
done | |
/opt/aws/bin/ec2-delete-volume "${EC2_VOLUME_ID}" || die "ec2-delete-volume failed" | |
# echo "delete snapshot ${EC2_SNAPSHOT_ID}" | |
# /opt/aws/bin/ec2-delete-snapshot "${EC2_SNAPSHOT_ID}" || die "ec2-delete-snapshot failed" | |
} | |
VOLUME_DEVICE="/dev/sdb" | |
MOUNT_POINT="/mnt" | |
PORTAGE_SNAPSHOT="${GENTOO_MIRROR}/snapshots/portage-latest.tar.bz2" | |
AMI_ARCH="`uname -m`" | |
if [ "${AMI_ARCH}" = "i686" ] ; then | |
ARCH="x86" | |
STAGE_ARCH="${AMI_ARCH}" | |
OS_BIT=32 | |
EC2_ARCH="i386" | |
create_ami server | |
create_ami hardened | |
elif [ "${AMI_ARCH}" = "x86_64" ] ; then | |
ARCH="amd64" | |
STAGE_ARCH="amd64" | |
OS_BIT=64 | |
EC2_ARCH="x86_64" | |
create_ami server | |
create_ami no-multilib | |
create_ami hardened | |
create_ami hardened-no-multilib | |
else | |
die "unknown architecture" | |
fi | |
echo "Finished!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment