Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

executable file 542 lines (463 sloc) 15.947 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
#!/bin/bash -e

# ami-0a59bb63 seems to be a good 64bit 5.4 ami # ec2-run-instances ami-0a59bb63 -k mine2 -t m1.large
# ami-08f41161 seems to be a good 32bit centos ami # ec2-run-instances ami-08f41161 -k mine2 -t c1.medium

# export architecture="i386"
export architecture="x86_64"
export IMAGE_NAME=centos5-$architecture-micro
export IMAGE_VERSION=alpha1
# For vmlinuz-2.6.18-xenU-ec2-v1.0.i386
# export KERNEL_ID=aki-9b00e5f2 #32bit - doesn't seem to be neccessary, does work.
# export KERNEL_ID=aki-9800e5f1 #64bit - doesn't seem to be necessary or work

source auth.sh

updateEc2AmiTools() {
  echo "Updating Local ec2-ami-tools"
  wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm
  rpm -Uvh ec2-ami-tools.noarch.rpm || true
}

setupEbsVolume() {
echo "mounting EBS Volume"
mkfs -t ext3 -F /dev/sdf
mkdir -p /mnt/ec2-fs
mount -t ext3 /dev/sdf /mnt/ec2-fs
mkdir -p /mnt/image
}

# for s3 backed AMIs
setupLoobackVolume() {
  echo "Creating 10GB Image"
  mkdir /mnt/image
  dd if=/dev/zero of=/mnt/image/$IMAGE_NAME bs=1M count=10240
  echo "Creating File System"
  mke2fs -F -j /mnt/image/$IMAGE_NAME
  mkdir /mnt/ec2-fs
  echo "Mounting File System in /mnt/ec2-fs"
  mount -o loop /mnt/image/$IMAGE_NAME /mnt/ec2-fs
}

makeFilesystems() {
  mkdir /mnt/ec2-fs/dev
  /sbin/MAKEDEV -d /mnt/ec2-fs/dev -x console
  /sbin/MAKEDEV -d /mnt/ec2-fs/dev -x null
  /sbin/MAKEDEV -d /mnt/ec2-fs/dev -x zero
  mkdir /mnt/ec2-fs/dev/pts
  mkdir /mnt/ec2-fs/proc
  mount -t proc none /mnt/ec2-fs/proc
  mkdir /mnt/ec2-fs/etc
  
  echo "base directory layout and proc fs created"
}

create32Fstab() {
  cat <<'EOL' > /mnt/ec2-fs/etc/fstab
/dev/sda1 / ext3 defaults 1 1
/dev/sda2 /mnt ext3 defaults 1 2
/dev/sda3 swap swap defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0
EOL
}

create64Fstab() {
  cat <<'EOL' > /mnt/ec2-fs/etc/fstab
/dev/sda1 / ext3 defaults 1 1
#/dev/sdb /mnt ext3 defaults 1 2 # Ephemeral storage isn't present on micros
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
EOL
}

doBaseAndSecondaryInstall() {
  echo "Creating Yum Confuration for Base install"
  mkdir -p /mnt/ec2-fs/sys/block
  mkdir -p /mnt/ec2-fs/var/
  mkdir -p /mnt/ec2-fs/var/log/
  mkdir -p /mnt/ec2-fs/var/lib/yum/
  touch /mnt/ec2-fs/var/log/yum.log
  cat <<EOL > /mnt/image/yum.conf
[main]
cachedir=/var/cache/yum
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=redhat-release
tolerant=1
exactarch=1
obsoletes=1
reposdir=/dev/null
gpgcheck=1
plugins=1

# Note: yum-RHN-plugin doesn't honor this.
metadata_expire=300

# Default.
# installonly_limit = 3

# CentOS-Base.repo
#
# This file uses a new mirrorlist system developed by Lance Davis for CentOS.
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#

[base]
name=CentOS-5 - Base
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$architecture&repo=os
#baseurl=http://mirror.centos.org/centos/5/os/$architecture/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5

#released updates
[updates]
name=CentOS-5 - Updates
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$architecture&repo=updates
#baseurl=http://mirror.centos.org/centos/5/updates/$architecture/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5

#packages used/produced in the build but not released
[addons]
name=CentOS-5 - Addons
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$architecture&repo=addons
#baseurl=http://mirror.centos.org/centos/5/addons/$architecture/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5

#additional packages that may be useful
[extras]
name=CentOS-5 - Extras
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$architecture&repo=extras
#baseurl=http://mirror.centos.org/centos/5/extras/$architecture/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-5 - Plus
mirrorlist=http://mirrorlist.centos.org/?release=5&arch=$architecture&repo=centosplus
#baseurl=http://mirror.centos.org/centos/5/centosplus/$architecture/
gpgcheck=1
enabled=0
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-5

EOL
  echo "Running Yum"
  yum -c /mnt/image/yum.conf --installroot=/mnt/ec2-fs -y groupinstall Base
  echo "Finished Base install"
  echo "Starting Secondary install"
  yum -c /mnt/image/yum.conf --installroot=/mnt/ec2-fs -y install openssh openssh-clients openssh-server
  yum -c /mnt/image/yum.conf --installroot=/mnt/ec2-fs -y clean packages
  cat <<EOL > /mnt/ec2-fs/etc/sysconfig/network
NETWORKING=yes
HOSTNAME=localhost.localdomain
EOL

  cat <<EOL > /mnt/ec2-fs/etc/sysconfig/network-scripts/ifcfg-eth0
ONBOOT=yes
DEVICE=eth0
BOOTPROTO=dhcp
EOL

  cat <<EOL >> /mnt/ec2-fs/etc/ssh/sshd_config
UseDNS no
PermitRootLogin without-password
EOL

  echo "Finished Secondary install"
}

install32KernelModules() {
  echo "Fetch Amazon EC2 kernel modules"
  curl -o /tmp/ec2-modules-2.6.18-xenU-ec2-v1.0-i686.tgz http://ec2-downloads.s3.amazonaws.com/ec2-modules-2.6.18-xenU-ec2-v1.0-i686.tgz
  echo "Installing EC2 kernel modules"
  tar -xzf /tmp/ec2-modules-2.6.18-xenU-ec2-v1.0-i686.tgz -C /mnt/ec2-fs/
  rm -fr /tmp/ec2-modules-2.6.18-xenU-ec2-v1.0-i686.tgz
}

install64KernelModules() {
  echo "Fetch Amazon EC2 kernel modules"
  curl -o /tmp/ec2-modules-2.6.18-xenU-ec2-v1.0-x86_64.tgz http://ec2-downloads.s3.amazonaws.com/ec2-modules-2.6.18-xenU-ec2-v1.0-x86_64.tgz
  echo "Installing EC2 kernel modules"
  tar -xzf /tmp/ec2-modules-2.6.18-xenU-ec2-v1.0-x86_64.tgz -C /mnt/ec2-fs/
  rm -fr /tmp/ec2-modules-2.6.18-xenU-ec2-v1.0-x86_64.tgz
}

setLdConfPatchStringFor32bit() {
  cat <<'LDCONF_PATCH' >> /mnt/ld_conf_patch
#fix '4gb seg fixup' Xen errors
cat <<'LDCONF' > /etc/ld.so.conf.d/libc6-xen.conf
# This directive teaches ldconfig to search in nosegneg subdirectories
# and cache the DSOs there with extra bit 0 set in their hwcap match
# fields. In Xen guest kernels, the vDSO tells the dynamic linker to
# search in nosegneg subdirectories and to match this extra hwcap bit
# in the ld.so.cache file.
hwcap 0 nosegneg

LDCONF
/sbin/ldconfig -v
LDCONF_PATCH
}

doPostInstall() {
  echo "Performing (chrooted) Post install"
  mkdir -p /mnt/ec2-fs/tmp/
  touch /mnt/ec2-fs/etc/mtab
  cat <<'EOL' > /mnt/ec2-fs/tmp/post-install-script

echo "Starting Post install"
echo "127.0.0.1 localhost localhost.localdomain" > /etc/hosts
authconfig --enableshadow --useshadow --enablemd5 --updateall

EOL
  test -f /mnt/ld_conf_patch && cat /mnt/ld_conf_patch >> /mnt/ec2-fs/tmp/post-install-script

  cat <<'EOL' >> /mnt/ec2-fs/tmp/post-install-script
echo "/sbin/MAKEDEV /dev/urandom" >> /etc/rc.sysinit
echo "/sbin/MAKEDEV /dev/random" >> /etc/rc.sysinit
echo "/sbin/MAKEDEV /dev/sdc" >> /etc/rc.sysinit
echo "/sbin/MAKEDEV /dev/sdc1" >> /etc/rc.sysinit
echo "/sbin/MAKEDEV /dev/sdc2" >> /etc/rc.sysinit
echo "/sbin/MAKEDEV /dev/ptmx" >> /etc/rc.sysinit


echo "Disabling TTYs"
perl -p -i -e 's/(.*tty2)/#\1/' /etc/inittab
perl -p -i -e 's/(.*tty3)/#\1/' /etc/inittab
perl -p -i -e 's/(.*tty4)/#\1/' /etc/inittab
perl -p -i -e 's/(.*tty5)/#\1/' /etc/inittab
perl -p -i -e 's/(.*tty6)/#\1/' /etc/inittab
perl -p -i -e 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
perl -p -i -e 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config
perl -p -i -e 's/#ClientAliveCountMax 3/ClientAliveCountMax 240/' /etc/ssh/sshd_config

echo "Installing getsshkey"
cat <<'SSH' >/etc/init.d/getsshkey
#!/bin/bash
# chkconfig: 4 11 11
# description: This script fetches the ssh key early. \
#

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
[ -r /etc/sysconfig/network ] && . /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 1

start() {
if [ ! -d /root/.ssh ] ; then
mkdir -p /root/.ssh
chmod 700 /root/.ssh
fi
# Fetch public key using HTTP
curl -f http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key > /tmp/my-key
if [ $? -eq 0 ] ; then
cat /tmp/my-key >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
rm /tmp/my-key
fi
# or fetch public key using the file in the ephemeral store:
if [ -e /mnt/openssh_id.pub ] ; then
cat /mnt/openssh_id.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
fi
}

stop() {
echo "Nothing to do here"
}

restart() {
stop
start
}

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $"Usage: $0 {start|stop}"
exit 1
esac

exit $?

SSH
chmod +x /etc/init.d/getsshkey

echo "Modifying Services"
chkconfig --add getsshkey
chkconfig --level 4 getsshkey on
chkconfig --level 4 psacct on
chkconfig --level 4 smartd off
chkconfig --level 4 anacron off
chkconfig --level 4 apmd off
chkconfig --level 4 acpid off
chkconfig --level 4 auditd off
chkconfig --level 4 irqbalance off
chkconfig --level 4 mdmpd off
chkconfig --level 4 portmap off
chkconfig --level 4 nfslock off
chkconfig --level 4 cpuspeed off
chkconfig --level 4 cups off
chkconfig --level 4 autofs off
chkconfig --level 4 bluetooth off
chkconfig --level 4 rpcidmapd off
chkconfig --level 4 rpcsvcgssd off
chkconfig --level 4 rpcgssd off
chkconfig --level 4 pcscd off
chkconfig --level 4 gpm off
chkconfig --level 4 hidd off
chkconfig --level 4 yum-updatesd off
chkconfig --del acpid
chkconfig --del auditd
chkconfig --del irqbalance
chkconfig --del mdmpd
chkconfig --del NetworkManager
chkconfig --del NetworkManagerDispatcher
chkconfig --del dhcdbd
chkconfig --del dund
chkconfig --del firstboot
chkconfig --del irda
chkconfig --del apmd
chkconfig --del smartd
chkconfig --del kudzu
chkconfig --del hidd
chkconfig --del gpm
chkconfig --del pcscd
chkconfig --del bluetooth
chkconfig --del cpuspeed
chkconfig --del cups
chkconfig --del rdisc
chkconfig --del readahead_later
chkconfig --del wpa_supplicant
chkconfig --del pand
chkconfig --del netplugd

echo "Setting up Bash environment for root"
cat <<'EOF'> /root/.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

EOF

cat <<'EOF'> /root/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
unset USERNAME

EOF

cat <<'EOF'> /root/.bash_logout
# ~/.bash_logout

clear

EOF

touch /root/.bash_logout

cat <<'EOF'> /usr/local/sbin/update-modules.sh
#!/bin/bash

# Update EC2 kernel modules autmatically.
modules_file="ec2-modules-`uname -r`-`uname -m`.tgz"
[ -f $modules_file ] && rm -f $modules_file
echo "Attempting kernel modules update from S3"
(wget http://s3.amazonaws.com/ec2-downloads/$modules_file && echo "Retreived $modules_file from S3" || echo "Unable to retreive $modules_file from S3")|logger -s -t "ec2"
(tar xzf $modules_file -C / && depmod -a && echo "Updated kernel modules from S3")|logger -s -t "ec2"

EOF

chmod +x /usr/local/sbin/update-modules.sh

cat <<'EOF'> /etc/rc.local
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

# Stuff we want to do once at launch and never again:
if [ -f "/root/firstrun" ]; then
# Randomise root password to avoid common password across instances:
dd if=/dev/urandom count=50|md5sum|passwd --stdin root

# Try to find kernel modules matching current kernel:
[ -x "/usr/local/sbin/update-modules.sh" ] && /usr/local/sbin/update-modules.sh

# Some kernels use xvc0 as their serial console device:
if [ -c /dev/xvc0 ]; then
if ! grep 'co:2345:respawn:/sbin/agetty xvc0 9600' /etc/inittab; then
echo 'co:2345:respawn:/sbin/agetty xvc0 9600 vt100' >> /etc/inittab
echo 'xvc0' >> /etc/securetty
kill -1 1
fi
fi

# Ensure devpts is mounted to prevent ssh hang-ups
mount | grep devpts > /dev/null
if [ $? -ne 0 ] ; then
devpts="none /dev/pts devpts gid=5,mode=620 0 0"
( grep -v "\#" /etc/fstab | grep devpts > /dev/null ) || echo $devpts >> /etc/fstab
mount -a
fi
rm -f /root/firstrun
fi

touch /var/lock/subsys/local

# =*Output ssh host keys to console*=
[ -f /etc/ssh/ssh_host_key ] || (ssh-keygen -f /etc/ssh/ssh_host_key -t rsa1 -C 'host' -N '' | logger -s -t "ec2")
[ -f /etc/ssh/ssh_host_rsa_key ] || (ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -C 'host' -N '' | logger -s -t "ec2")
[ -f /etc/ssh/ssh_host_dsa_key ] || (ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t dsa -C 'host' -N '' | logger -s -t "ec2")

echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----" |logger -s -t "ec2"
ssh-keygen -l -f /etc/ssh/ssh_host_key.pub |logger -s -t "ec2"
ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub |logger -s -t "ec2"
ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub |logger -s -t "ec2"
echo "-----END SSH HOST KEY FINGERPRINTS-----" |logger -s -t "ec2"

EOF

exit

EOL

  chmod +x /mnt/ec2-fs/tmp/post-install-script
  chroot /mnt/ec2-fs/ /tmp/post-install-script
  echo "Cleaning up Image"
  echo "$IMAGE_NAME version $IMAGE_VERSION" > /mnt/ec2-fs/etc/t3-ami-release
  echo "Finished Post Install"
}

unmountEBS() {
umount /mnt/ec2-fs/proc/
umount /mnt/ec2-fs
}

# s3 backed AMI only
bundleVolume() {
  sync
  echo "Bundling Volume"
  mkdir -p /mnt/tmp
  if [ -z "$KERNEL_ID" ]; then
ec2-bundle-vol -v /mnt/ec2-fs -d /mnt/tmp -p $IMAGE_NAME -k $EC2_PRIVATE_KEY -c $EC2_CERT -u $AWS_ACCOUNT_NUMBER --fstab /mnt/ec2-fs/etc/fstab -r $architecture
  else
ec2-bundle-vol -v /mnt/ec2-fs -d /mnt/tmp -p $IMAGE_NAME -k $EC2_PRIVATE_KEY -c $EC2_CERT -u $AWS_ACCOUNT_NUMBER --fstab /mnt/ec2-fs/etc/fstab -r $architecture --kernel $KERNEL_ID
  fi
echo "Finished Bundling Volume"

}

# s3 backed AMI only
uploadBundle() {
  echo "Uploading Bundle"
  ec2-upload-bundle -b $AWS_BUCKET -m /mnt/tmp/$IMAGE_NAME.manifest.xml -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY --retry 5
  echo "Finished Uploading Bundle"
  echo "to register, run: ec2-register $AWS_BUCKET/$IMAGE_NAME.manifest.xml"
}

cleanup() {
  echo "Starting Cleanup"
  echo "Unmounting /mnt/ec2-fs"
  umount /mnt/ec2-fs/proc
  umount -d /mnt/ec2-fs
  rm -fr /mnt/image/
  rm -fr /mnt/ec2-fs
  rm -fr /mnt/tmp
  echo "File System Cleaned"
  echo "Done! Put a fork in it!"
}

if [ "$architecture" == "i386" ]; then
echo "Building i386 AMI"
  updateEc2AmiTools
setupEbsVolume
  makeFilesystems
  create32Fstab
  doBaseAndSecondaryInstall
  install32KernelModules
  setLdConfPatchStringFor32bit
  doPostInstall
  bundleVolume
  uploadBundle
  # cleanup
elif [ "$architecture" == "x86_64" ]; then
echo "Building x86_64 AMI"
  updateEc2AmiTools
setupEbsVolume
  makeFilesystems
  create64Fstab
  doBaseAndSecondaryInstall
  install64KernelModules
  doPostInstall
unmountEBS
  # bundleVolume
  # uploadBundle
  # cleanup
else
echo "Please set your architecture to i386 or x86_64"
  exit 1
fi
Something went wrong with that request. Please try again.