~ubuntu-on-ec2/vmbuilder/jenkins_kvm

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
#!/bin/bash

# Set default umask
umask 022

# Read in the common files
my_name=$(readlink -f ${0})
my_dir=$(dirname ${my_name})
my_pdir=$(dirname ${my_dir})

# Source in the common functions
source "${my_pdir}/functions/common"
source "${my_pdir}/functions/retry"
source "${my_pdir}/functions/locker"
export HOME=${WORKSPACE}

# needed for building on Jenkins
[ -e "build_properties" ] && source build_properties

# Copy the target disk imags
ARCH_TYPE=${ARCH_TYPE:-$ARCH}
disk_orig="${SUITE}-server-cloudimg-${ARCH_TYPE}-disk1.img"
disk_cp="${disk_orig//$ARCH_TYPE/$ARCH_TYPE-juju-vagrant}"
disk_root="${SRV_D:-/srv/ec2-images}/${SUITE}/${SERIAL:-current}"
disk_working="${WORKSPACE}/${disk_cp}"
final_disk="${WORKSPACE}/box-disk1.vdi"
final_location="${OUTPUT_D:-/srv/ec2-images}/vagrant/${SUITE}/${SERIAL}"
box_name="${disk_working//.img/.box}"
raw_f="${WORKSPACE}/raw_f-$(date +%s).img"
build_host_suite=$(lsb_release -c -s)

jenkins_build() {
    [ -e "build_properties" ] &&
        source build_properties ||
        fail "Failed to read build_properties. I don't know what I'm doing!"

    # Bail if something isn't right
    SUITE=${SUITE:?Suite must be defined}
    SERIAL=${SERIAL:?Serial must be defined}

    cp "${disk_root}/${disk_orig}" "${disk_working}" ||
        fail "Unable to copy ${disk_orig} from ${disk_root}"

    qemu-img resize ${disk_working} 40G

    # Launch KVM to do the worK
    ${my_pdir}/launch_kvm.sh \
            --id "${ARCH_TYPE}-${BUILD_ID}" \
            --user-data "${my_pdir}/config/cloud-vps.cfg" \
            --cloud-config "${my_pdir}/templates/img-juju.tmpl" \
            --extra-disk "${disk_working}" \
            --disk-gb 1 \
            --raw-disk "${raw_f}" \
            --raw-size 1 \
            --img-url /srv/builder/images/precise-builder-latest.img ||
                fail "KVM instance failed to build image."
}

# Assume that we're building in Jenkins unless otherwise stated
# What this allows us to do is to use the standalone builder for testing
# and finish running the bits below
[ "${LOCAL_BUILD:-0}" -eq 1 ] || jenkins_build

# Covert to VMDK.
qemu-img convert -O raw ${disk_working} ${disk_working//.img/.raw}

_vbox_cmd convertfromraw \
    --format vdi \
    ${disk_working//.img/.raw} ${final_disk}

# Create the VM
vmname="ubuntu-cloudimg-${SUITE}-juju-vagrant-${ARCH_TYPE}"
_vbox_cmd modifyhd --compact ${final_disk}

dist_v="Ubuntu"
[ "${ARCH_TYPE}" = "amd64" ] && dist_v="Ubuntu_64"
_vbox_cmd createvm \
    --name ${vmname} \
    --ostype ${dist_v} \
    --register

_vbox_cmd modifyvm ${vmname} \
    --memory 2048 \
    --boot1 disk \
    --boot2 none \
    --boot3 none \
    --boot4 none \
    --vram 12 \
    --pae off \
    --acpi on \
    --ioapic on \
    --rtcuseutc on \
    --bioslogodisplaytime 0 \
    --nic1 nat \
    --nictype1 virtio

if [ "${ARCH_TYPE}" = "i386" ]; then
    _vbox_cmd modifyvm ${vmname} \
        --ioapic off \
        --pae on
fi


_vbox_cmd modifyvm ${vmname} --natpf1 "guestssh,tcp,,2222,,22"

storage_cmd=(
    _vbox_cmd storagectl "${vmname}"
    --name "SATAController"
    --add sata
    --controller IntelAhci
    --hostiocache on
    )

if [ "$(lsb_release -r -s | sed 's/\.//')" -lt 1404 ]; then
	storage_cmd+=(--sataportcount 1)
else
	storage_cmd+=(--portcount 1)
fi

${storage_cmd[@]}

_vbox_cmd storageattach ${vmname} \
    --storagectl "SATAController" \
    --port 0 \
    --device 0 \
    --type hdd \
    --medium ${final_disk}

# Set extra-data
_vbox_cmd setextradata ${vmname} installdate ${serial}
_vbox_cmd setextradata ${vmname} supported false

# Set the Guest information to get rid of error message
[ -e vagrant_image.pkgs ] && {

    vbox_version=""
    while read -r line
    do
        line=( $(echo ${line}) )
        [[ ${line[0]} =~ virtualbox-guest-utils ]] && vbox_version=${line[1]}
    done < vagrant_image.pkgs
    debug "Guest Additions version is ${vbox_version}"

    # Set the revision to some arbitrary value
    _vbox_cmd guestproperty set ${vmname} \
        "/VirtualBox/GuestAdd/Revision" '8000'

    # Set the Ubuntu packaged version correctly
    _vbox_cmd guestproperty set ${vmname} \
        "/VirtualBox/GuestAdd/VersionExt" \
        "${vbox_version//-dfsg-*/_Ubuntu}"

    # Set the version string appropriately
    _vbox_cmd guestproperty set ${vmname} \
        "/VirtualBox/GuestAdd/Version" \
        "${vbox_version//-dfsg-*/}"
}

mkdir ${WORKSPACE}/box
_vbox_cmd export ${vmname} --output ${WORKSPACE}/box/box.ovf

# Create the Vagrant file
#macaddr="02:$(openssl rand -hex 5)"
macaddr=$(awk '-F"' '/<Adapter slot="0" enabled="true"/ {print$6}' ${WORKSPACE}/box/box.ovf)
cat << EOF > ${WORKSPACE}/box/Vagrantfile
\$script = <<SCRIPT
bzr branch lp:jujuredirector /tmp/jujuredir

if ! grep precise /etc/lsb-release > /dev/null; then
    cat << EOM > "/etc/apt/apt.conf.d/90proxy"
Acquire::http::Proxy "http://10.0.3.1:8000";
EOM

    for series in precise trusty; do
        version=\$(grep \$series /usr/share/distro-info/ubuntu.csv | cut -d, -f1 | cut -d' ' -f1)
        expected_filename=/var/cache/lxc/cloud-\${series}/ubuntu-\${version}-server-cloudimg-${ARCH_TYPE}-root.tar.gz
        if [ ! -e \$expected_filename ]; then
            mkdir -p "/var/cache/lxc/cloud-\${series}"
            curl -o "\$expected_filename" \
                http://cloud-images.ubuntu.com/releases/\${series}/release/ubuntu-\${version}-server-cloudimg-${ARCH_TYPE}-root.tar.gz
        fi
    done

    # Set up squid in the LXC template
    for lxc_template in \$(ls /var/cache/lxc/cloud-*/*-root.tar.gz); do
        gunzip "\$lxc_template"
        unwrapped_name=\$(dirname "\$lxc_template")/\$(basename "\$lxc_template" .gz)
        mkdir -p etc/apt/apt.conf.d
        echo 'Acquire::http::Proxy "http://10.0.3.1:8000";' > etc/apt/apt.conf.d/90proxy
        tar rf "\$unwrapped_name" etc/apt/apt.conf.d/90proxy
        gzip "\$unwrapped_name"
        rm -rf etc
    done
fi

bash /tmp/jujuredir/setup-juju.sh 6079
echo "export JUJU_REPOSITORY=/charms" >> /home/vagrant/.bashrc
SCRIPT

system 'mkdir', '-p', 'charms'

Vagrant.configure("2") do |config|
  # This Vagrantfile is auto-generated by 'vagrant package' to contain
  # the MAC address of the box. Custom configuration should be placed in
  # the actual 'Vagrantfile' in this box.

  config.vm.base_mac = "${macaddr}"
  config.vm.network :forwarded_port, guest: 22, host: 2122, host_ip: "127.0.0.1"
  config.vm.network :forwarded_port, guest: 80, host: 6080, host_ip: "127.0.0.1"
  config.vm.network :forwarded_port, guest: 6079, host: 6079, host_ip: "127.0.0.1"
  config.vm.network "private_network", ip: "172.16.250.15"
  config.vm.provider "virtualbox" do |vb|
       vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
  end
  config.vm.provision "shell", inline: \$script

  config.vm.synced_folder "charms/", "/charms"
end

# Load include vagrant file if it exists after the auto-generated
# so it can override any of the settings
include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
load include_vagrantfile if File.exist?(include_vagrantfile)
EOF

# Now pack it all up....
tar -C ${WORKSPACE}/box -Scvf ${box_name} box.ovf Vagrantfile box-disk1.vmdk ||
        fail "Unable to create box file"

# Some minor cleanup
rm ${disk_working} ${disk_working//.img/.raw} || /bin/true
rm -rf ${WORKSPACE}/box *.vdi
[ -e "${raw_f}" ] && rm "${raw_f}"

# Bail here if this is a local build
[ "${LOCAL_BUILD:-0}" -eq 1 ] && exit 0

# Put the box in place
mkdir -p "${final_location}" ||
    fail "Unable to create the vagrant image location"

cp ${box_name} ${final_location} ||
    fail "Failed to place vagrant image in final home"

# Now Checksum it all

# Override and set some home variables
export HOME="/srv/builder"
export CDIMAGE_BIN="${HOME}/cdimage/bin"
PUBLISH_SCRIPTS=${HOME}/ec2-publishing-scripts
export CDIMAGE_ROOT="${HOME}/cdimage"
export PATH="${PUBLISH_SCRIPTS}:${CDIMAGE_BIN}:${PATH}"
checksum-directory ${final_location}