// // proc on /tmp/8389210e66cd0df6/mnt/proc type proc (rw)
// }
//
// if (!isMounted)
{
ProcessExecution kpartxExecution = target.executeCommand(Command.build("kpartx -av {0}", imageFile));
String stdout = kpartxExecution.getStdOut();
List<String> tokens = Lists.newArrayList(Splitter.on(' ').split(stdout));
if (tokens.size() != 9) {
throw new IllegalStateException("Cannot parse kpartx stdout: " + stdout);
}
// add map loop6p1 (253:6): 0 16750592 linear /dev/loop6 2048
String partitionDevice = tokens.get(2);
if (!partitionDevice.startsWith("loop")) {
throw new IllegalStateException("kpartx output does not look like a partition: " + stdout);
}
loopbackPartition = new File("/dev/mapper/" + partitionDevice);
}
// Format filesystem
command = Command.build("yes | mkfs." + filesystem + " {0}", loopbackPartition);
command.setTimeout(TimeSpan.FIVE_MINUTES);
target.executeCommand(command);
// Get this onto disk now, so we don't delay later commands
target.executeCommand(Command.build("sync").setTimeout(TimeSpan.FIVE_MINUTES));
// Don’t force a check based on dates
target.executeCommand(Command.build("tune2fs -i 0 {0}", loopbackPartition)
.setTimeout(TimeSpan.FIVE_MINUTES));
// Get this onto disk now, so we don't delay later commands
target.executeCommand(Command.build("sync").setTimeout(TimeSpan.FIVE_MINUTES));
// Mount on mnt/
File mntDir = new File(tempDir, "mnt");
target.executeCommand("mkdir {0}", mntDir);
target.executeCommand(Command.build("mount {0} {1}", loopbackPartition, mntDir).setTimeout(
TimeSpan.FIVE_MINUTES));
rootfsDir = mntDir;
} else {
rootfsDir = new File(tempDir, "rootfs");
imageFile = new File(tempDir, "image.tar.bz2");
}
if (buildTar) {
apt.install(target, "bzip2");
}
// Do debootstrap
if (supportLxc) {
command = Command.build("fakechroot fakeroot debootstrap");
} else {
command = Command.build("debootstrap");
}
command.addLiteral("--verbose");
command.addLiteral("--resolve-deps");
if (supportLxc) {
// Lxc has problems with mounting etc; fakechroot avoids this
command.addLiteral("--variant=fakechroot");
// command.addLiteral("--variant=minbase");
}
command.addQuoted("--include=", Joiner.on(",").join(packages));
command.addLiteral(operatingSystem.getVersion());
command.addFile(rootfsDir);
// command.addQuoted(aptSource);
command.setEnvironment(httpProxyEnv);
command.setTimeout(TimeSpan.THIRTY_MINUTES);
try {
target.executeCommand(command);
} catch (ProcessExecutionException e) {
String debootstrapLog = target.readTextFile(new File(rootfsDir, "debootstrap/debootstrap.log"));
log.warn("Debootstrap log: " + debootstrapLog);
throw new OpsException("Error running debootstrap", e);
}
// TODO: Switch to ChrootOpsTarget, so we can move this stuff into utility functions
ChrootOpsTarget chrootTarget = new ChrootOpsTarget(rootfsDir, new File("/tmp"), target);
FileUpload.upload(target, new File(rootfsDir, "etc/hostname"), hostname);
{
// Stop services being started in the chroot
String policy = ResourceUtils.get(getClass(), "usr.sbin.policy-rc.d");
File policyFile = new File(rootfsDir, "usr/sbin/policy-rc.d");
FileUpload.upload(target, policyFile, policy);
target.chmod(policyFile, "755");
}
target.executeCommand("mount -t proc proc {0}", new File(rootfsDir, "proc"));
apt.update(chrootTarget, true);
target.executeCommand("chroot {0} locale-gen en_US.utf8", rootfsDir);
target.executeCommand("chroot {0} /bin/bash -c \"DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales\"",
rootfsDir);
if (!buildTar) {
{
File kernelImgConf = new File(rootfsDir, "etc/kernel-img.conf");
String preseedData = ResourceUtils.get(getClass(), "kernel-img.conf");
FileUpload.upload(target, kernelImgConf, preseedData);
}
{
File preseedTmpDir = target.createTempDir();
File preseedFile = new File(preseedTmpDir, "kernel.preseed");
String preseedData = ResourceUtils.get(getClass(), "kernel.preseed");
FileUpload.upload(target, preseedFile, preseedData);
target.executeCommand(Command.build("cat {0} | chroot {1} debconf-set-selections", preseedFile,
rootfsDir));
apt.install(chrootTarget, kernelPackage);
}
}
preconfigurePackages(chrootTarget, recipe.configurePackage);
if (recipe.repositoryKey != null) {
addRepositoryKeys(chrootTarget, recipe.repositoryKey);
}
if (recipe.repository != null) {
addRepositories(chrootTarget, recipe.repository);
apt.update(chrootTarget, true);
}
if (recipe.addPackage != null) {
apt.install(chrootTarget, recipe.addPackage);
if (recipe.addPackage.contains("jenkins")) {
// It looks like jenkins doesn't honor policy-rc.d (?)
// TODO: Fix this monstrosity...
log.warn("Hard-coding service stop after jenkins installation");
target.executeCommand(Command.build("chroot {0} /etc/init.d/jenkins stop", rootfsDir));
}
}
apt.upgrade(chrootTarget);
apt.clean(chrootTarget);
if (!buildTar) {
String uuid;
{
ProcessExecution uuidExecution = target.executeCommand("blkid -o value -s UUID {0}", loopbackPartition);
uuid = uuidExecution.getStdOut().trim();
}
// Set up /etc/fstab
String fstab = "# /etc/fstab: static file system information.\n";
// TODO: Swap
fstab += "proc\t/proc\tproc\tnodev,noexec,nosuid\t0\t0\n";
// fstab += "/dev/sda1\t/\t" + filesystem +
// "\terrors=remount-ro\t0\t1\n";
fstab += String.format("UUID=%s\t/\t%s\terrors=remount-ro\t0\t1\n", uuid, filesystem);
if (supportCloudConfigDisk) {
if (useConfigDriveSymlinks) {
// Use configuration from cloud_config mount
target.mkdir(new File(rootfsDir, "media/config"));
fstab += "/dev/disk/by-label/" + configDriveLabel + "\t/media/config\tudf,iso9660\tro\t0\t0\n";
}
}
FileUpload.upload(target, new File(rootfsDir, "etc/fstab"), fstab);
log.info("fstab = " + fstab);
// Set up extlinux
{
ProcessExecution kernelExecution = target.executeCommand("chroot {0} find boot/ -name \"vmlinuz-*\"",
rootfsDir);
List<String> kernels = Lists.newArrayList();
for (String kernel : kernelExecution.getStdOut().split("\n")) {
kernel = kernel.trim();
if (kernel.isEmpty()) {
continue;
}
kernels.add(kernel);
}
if (kernels.size() > 1) {
throw new IllegalStateException("Multiple kernels found");
} else if (kernels.size() != 1) {
throw new IllegalStateException("No kernels found");
}
ProcessExecution initrdExecution = target.executeCommand("chroot {0} find boot/ -name \"initrd*\"",
rootfsDir);
List<String> initrds = Lists.newArrayList();
for (String initrd : initrdExecution.getStdOut().split("\n")) {
initrd = initrd.trim();
if (initrd.isEmpty()) {
continue;
}
if (initrd.endsWith(".bak")) {