tags 564425 + pending thanks Dear maintainer,
I've prepared an NMU for cowdancer (versioned as 0.62+nmu1) dsc http://mentors.debian.net/debian/pool/main/c/cowdancer/cowdancer_0.62+nmu1.dsc Regards. Martijn van Brummelen
diff -Nru cowdancer-0.62/debian/changelog cowdancer-0.62+nmu1/debian/changelog --- cowdancer-0.62/debian/changelog 2010-08-15 16:43:49.000000000 +0200 +++ cowdancer-0.62+nmu1/debian/changelog 2010-09-17 16:15:24.000000000 +0200 @@ -1,3 +1,13 @@ +cowdancer (0.62+nmu1) unstable; urgency=low + + * Non-maintainer upload. + * Add 564425.patch from Gregor Herrmann + - Fix "qemubuilder --create fails to start qemu - umount problem": replace + workblockdevicepath with pc->buildplace to use the mount point to umount, + hint from Heiko Stuebner (closes: #564425). + + -- Martijn van Brummelen <[email protected]> Fri, 17 Sep 2010 16:13:27 +0200 + cowdancer (0.62) unstable; urgency=low [ Stefan Kisdaroczi ] diff -Nru cowdancer-0.62/debian/patches/564425.patch cowdancer-0.62+nmu1/debian/patches/564425.patch --- cowdancer-0.62/debian/patches/564425.patch 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/debian/patches/564425.patch 2010-09-17 16:18:08.000000000 +0200 @@ -0,0 +1,31 @@ +Index: cowdancer-0.62+nmu1/qemubuilder.c +=================================================================== +--- cowdancer-0.62+nmu1.orig/qemubuilder.c 2010-09-17 16:16:14.000000000 +0200 ++++ cowdancer-0.62+nmu1/qemubuilder.c 2010-09-17 16:18:02.000000000 +0200 +@@ -471,7 +471,7 @@ + system(hostcommand1); + } + +- loop_umount(workblockdevicepath); ++ loop_umount(pc->buildplace); + + asprintf(&cowdevpath, "%s.cowdev", pc->buildplace); + ret=forkexeclp("qemu-img", "qemu-img", +@@ -504,7 +504,7 @@ + printf("running host command: %s\n", hostcommand2); + system(hostcommand2); + } +- loop_umount(workblockdevicepath); ++ loop_umount(pc->buildplace); + rmdir(pc->buildplace); + printf(" -> clean up COW device files\n"); + unlink(workblockdevicepath); +@@ -755,7 +755,7 @@ + /* TODO: hooks probably need copying here. */ + /* TODO: recover aptcache */ + +- loop_umount(workblockdevicepath); ++ loop_umount(pc->buildplace); + rmdir(pc->buildplace); + + // this will have wrong time. how to workaround? diff -Nru cowdancer-0.62/debian/patches/series cowdancer-0.62+nmu1/debian/patches/series --- cowdancer-0.62/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/debian/patches/series 2010-09-17 16:15:58.000000000 +0200 @@ -0,0 +1 @@ +564425.patch diff -Nru cowdancer-0.62/.pc/564425.patch/qemubuilder.c cowdancer-0.62+nmu1/.pc/564425.patch/qemubuilder.c --- cowdancer-0.62/.pc/564425.patch/qemubuilder.c 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/.pc/564425.patch/qemubuilder.c 2010-09-17 16:16:14.000000000 +0200 @@ -0,0 +1,902 @@ +/*BINFMTC: parameter.c forkexec.c qemuipsanitize.c qemuarch.c file.c main.c + * qemubuilder: pbuilder with qemu + * Copyright (C) 2007-2009 Junichi Uekawa + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <sys/socket.h> +#include <string.h> +#include <unistd.h> +#include <getopt.h> +#include <stdarg.h> +#include <assert.h> +#include <termios.h> +#include <time.h> +#include <locale.h> +#include "parameter.h" +#include "qemuipsanitize.h" +#include "qemuarch.h" +#include "file.h" + +/* + * example exit codes: + * + * END OF WORK EXIT CODE=1 + * END OF WORK EXIT CODE=0 + * END OF WORK EXIT CODE=16 + */ +const char* qemu_keyword="END OF WORK EXIT CODE="; + +/** create a sparse ext3 block device suitable for + loop-mount. + + This code takes approx 7 seconds to run, should be cached? + + @returns -1 on error, 0 on success + */ +static int create_ext3_block_device(const char* filename, + unsigned long int gigabyte) +{ + int ret = 0; + char *s = NULL; + char *s2 = NULL; + + /* create 10GB sparse data */ + if (create_sparse_file(filename, + gigabyte*1UL<<30UL)) + { + ret=-1; + goto out; + } + + if ((ret=forkexeclp("mke2fs", "mke2fs", + "-q", + "-F", + "-j", + "-m1", + "-O", "sparse_super", + filename, NULL))) + { + ret=-1; + goto out; + } + + if ((ret=forkexeclp("tune2fs", "tune2fs", + "-c", "0", + "-i", "0", + filename, NULL))) + { + ret=-1; + } + + out: + if(s) free(s); + if(s2) free(s2); + return ret; +} + +/** loopback mount file system. + @returns 0 on success +*/ +static int loop_mount(const char* device, const char* mountpoint) +{ + int ret=forkexeclp("mount", "mount", "-o", "loop", + device, mountpoint, NULL); + return ret; +} + +/** + loopback umount file system + + @returns 0 on success + */ +static int loop_umount(const char* device) +{ + int ret=forkexeclp("umount", "umount", device, + NULL); + return ret; +} + +/** create a script file. + +...@returns NULL on failure, FILE* on success +*/ +static FILE* create_script(const char* mountpoint, const char* relative_path) +{ + char *s = NULL; + FILE *f = NULL; + FILE *ret = NULL; + + asprintf(&s, "%s/%s", mountpoint, relative_path); + if(!(f=fopen(s, "w"))) + goto fail; + if(chmod(s, 0700)) + { + fclose(f); + goto fail; + } + ret=f; + fail: + free(s); + return ret; +} + +/* minimally fix terminal I/O */ +static void fix_terminal(void) +{ + struct termios t; + + if (isatty(1)) + { + tcgetattr(1, &t); + t.c_lflag |= ECHO; + tcsetattr(1, TCSANOW, &t); + } +} + +static int copy_file_contents_through_temp(FILE* f, + const char* orig, + const char* temppath, + const char* targetdir) +{ + char* tempname; + int ret; + char* file_basename = basename(orig); + asprintf(&tempname, "%s/%s", temppath, file_basename); + ret=copy_file(orig, tempname); + if (ret == -1) + { + fprintf(f, "E: Copy file error in %s to %s\n", + orig, tempname); + } + + free(tempname); + + fprintf(f, + "echo \"I: copying %s/%s from temporary location\"\n" + "cp $PBUILDER_MOUNTPOINT/%s %s/%s || echo \"E: Copy failed\"\n", + targetdir, file_basename, + file_basename, + targetdir, file_basename); + return ret; +} + +/** + run qemu until exit signal is received from within QEMU via serial + console. + + exit code: + -1: error + 0..X: return code from inside qemu +*/ +static int fork_qemu(const char* hda, const char* hdb, const struct pbuilderconfig* pc) +{ + pid_t child; + int sp[2]; + fd_set readfds; + int exit_code=-1; + const int buffer_size=4096; + char* buf=malloc(buffer_size); + size_t count; + + if (-1==socketpair(AF_UNIX, SOCK_STREAM,0,sp)) + { + /* error handle? */ + return -1; + } + + fflush(NULL); + if ((child=fork())) + { + /* this is parent process */ + + close(sp[1]); + close(0); + + FD_ZERO(&readfds); + while (1) + { + FD_SET(sp[0],&readfds); + if (-1!=(select(sp[0]+1,&readfds, NULL, NULL, NULL))) + { + if (FD_ISSET(sp[0],&readfds)) + { + void* matchptr; + + /* data available from qemu */ + + /* sleep a bit to let it buffer-up a bit more. */ + usleep(100000); + + count=read(sp[0],buf,buffer_size); + + /* this won't work sometimes, but this is a good best-effort thing. */ + if ((matchptr=memmem(buf, count, + qemu_keyword, strlen(qemu_keyword)))!=0) + { + int status; + + exit_code = atoi(matchptr + strlen(qemu_keyword)); + printf("\n -> received termination message from inside qemu with exit-code %i, killing child process (qemu:%i)\n", + exit_code, + child); + + assert(child != 0);assert(child > 0); + + if (!kill(child, SIGTERM)) + printf(" -> successfully killed qemu\n"); + else + perror(" -> failed to kill qemu? :"); + if (-1==waitpid(child, &status, 0)) + { + perror("qemubuilder: waitpid"); + } + break; + } + write(1,buf,count); + } + } + else + { + perror("select"); + break; + } + } + } + else if(child == 0) + { + /* this is the child process */ + const char* qemu = qemu_arch_qemu(pc->arch); + const char* machine = qemu_arch_qemumachine(pc->arch); + char* append_command; + const char* kernel_image = pc->kernel_image; + const char* initrd = pc->initrd; + char* mem; + int argc = 0; + const int MAX_ARGS = 30; + char *argv[MAX_ARGS]; + int i; + + if (qemu == NULL || machine == NULL) { + fprintf(stderr, "Your architecture %s does not seem to be supported\n", pc->arch); + exit(1); + } + + asprintf(&mem, "%i", pc->memory_megs); + + asprintf(&append_command, + "root=/dev/%sa quiet init=/pbuilder-run console=%s", + qemu_arch_diskdevice(pc), + qemu_arch_tty(pc->arch)); + + dup2(sp[1],1); + dup2(sp[1],2); + close(sp[0]); + + argv[argc++]=strdupa(qemu); + argv[argc++]="-nodefaults"; + argv[argc++]="-nographic"; + argv[argc++]="-M"; + argv[argc++]=strdupa(machine); + argv[argc++]="-m"; + argv[argc++]=mem; + argv[argc++]="-kernel"; + argv[argc++]=strdupa(kernel_image); + if (initrd && strcmp(initrd, "")) + { + argv[argc++]="-initrd"; + argv[argc++]=strdupa(initrd); + } + argv[argc++]="-hda"; + argv[argc++]=strdupa(hda); + argv[argc++]="-hdb"; + argv[argc++]=strdupa(hdb); + argv[argc++]="-append"; + argv[argc++]=append_command; + argv[argc++]="-serial"; + argv[argc++]="stdio"; + argv[argc]=NULL; + assert(argc < MAX_ARGS); + + printf(" forking qemu: "); + for (i=0; i<argc; ++i) + { + printf("%s ", argv[i]); + } + printf("\n"); + + execvp(argv[0], argv); + perror("fork_qemu"); + exit (1); + } + else + { + perror("fork"); + return -1; + } + + fix_terminal(); + return exit_code; +} + +static int do_fsck(const char* devfile) +{ + /* force-running this fsck isn't a good idea; let it fail. + If it's mounted by someone else, I don't want to touch it, + and chroots can be re-created any time, right? + */ + return forkexeclp("/sbin/fsck", + "/sbin/fsck", + devfile, + NULL); +} + +/* + get the current time string which can be used in date command to + set time inside the chroot. + */ +static char* get_current_time_string(void) +{ + char* locsave, *timestring; + time_t currenttime; + + /* save/set/restore locale settings to get current time in POSIX format */ + locsave = setlocale(LC_TIME, NULL); + (void) setlocale(LC_TIME, "POSIX"); + currenttime=time(NULL); + timestring=asctime(gmtime(¤ttime)); + (void) setlocale(LC_TIME, locsave); + return timestring; +} + + +/** + * Invoke qemu, and run the second-stage script within QEMU. + * + * hostcommand1 is used from build and login and exeute + */ +static int run_second_stage_script +( + /** save the result of this command*/ + int save_result, + /** the command-line to invoke within QEMU */ + const char* commandline, + const struct pbuilderconfig* pc, + /** the commands to invoke in the host OS */ + const char* hostcommand1, + /** the commands to invoke in the guest OS */ + const char* hostcommand2) +{ + char* script=NULL; + char* workblockdevicepath=NULL; + char* cowdevpath=NULL; + char* timestring; + int ret=1; + FILE* f; + int i; + + if (mkdir(pc->buildplace,0777)) + { + /* could not create the buildplace here. */ + perror("mkdir"); + goto out; + } + + do_fsck(pc->basepath); + + timestring=get_current_time_string(); + + asprintf(&workblockdevicepath, "%s.dev", pc->buildplace); + ret=create_ext3_block_device(workblockdevicepath, 1); + loop_mount(workblockdevicepath, pc->buildplace); + + f = create_script(pc->buildplace, "pbuilder-run"); + fprintf(f, + "#!/bin/bash\n" + + /* define function to terminate qemu */ + "function exit_from_qemu() {\n" + "sync\n" + "sync\n" + "sleep 1s\n" /* sleep before sending dying message */ + "echo ' -> qemu-pbuilder %s$1'\n" + "sleep 1s\n" + "halt -f -p\n" /* just halt myself if possible */ + "}\n", + qemu_keyword); + + fprintf(f, + /* main code */ + "echo \n" + "echo ' -> qemu-pbuilder second-stage' \n" + //TODO: copy hook scripts + //"mount -n /proc /proc -t proc\n" // this is done in first stage. + "echo ' -> setting time to %s' \n" + "date --set=\"%s\"\n" + "echo ' -> configuring network' \n" + "ifconfig -a\n" + "export IFNAME=`/sbin/ifconfig -a | grep eth | head -n1 | awk '{print $1}'`\n" + "dhclient $IFNAME\n" + "mkdir -p /tmp/buildd\n" + "$PBUILDER_MOUNTPOINT/run-copyfiles\n" + "hostname pbuilder-$(cat /etc/hostname)\n" + //TODO: run G hook + "%s\n" + //TODO: I can mount /var/cache/apt/archives from some scratch space to not need this: + "apt-get clean || true\n" + "exit_from_qemu 0\n", + timestring, + timestring, + commandline); + fclose(f); + + /* copy files script */ + f = create_script(pc->buildplace, "run-copyfiles"); + copy_file_contents_through_temp(f, "/etc/hosts", pc->buildplace, "/etc"); + copy_file_contents_through_temp(f, "/etc/hostname", pc->buildplace, "/etc"); + /* copy inputfile */ + for (i=0; pc->inputfile[i]; ++i) + { + copy_file_contents_through_temp(f, pc->inputfile[i], pc->buildplace, "/tmp/buildd"); + } + fclose(f); + + /* do I not need to copy /etc/pbuilderrc, and ~/.pbuilderrc to inside chroot? */ + /* TODO: hooks probably need copying here. */ + /* TODO: recover aptcache */ + + if(hostcommand1) + { + printf("running host command: %s\n", hostcommand1); + system(hostcommand1); + } + + loop_umount(workblockdevicepath); + + asprintf(&cowdevpath, "%s.cowdev", pc->buildplace); + ret=forkexeclp("qemu-img", "qemu-img", + "create", + "-f", + "qcow", + "-b", + pc->basepath, + cowdevpath, + NULL); + + fork_qemu(cowdevpath, workblockdevicepath, pc); + /* this will always return 0. */ + + /* commit the change here */ + if (save_result) + { + printf(" -> commit change to qemu image\n"); + ret=forkexeclp("qemu-img", "qemu-img", + "commit", + cowdevpath, + NULL); + } + + /* after-run */ + loop_mount(workblockdevicepath, pc->buildplace); + printf(" -> running post-run process\n"); + if(hostcommand2) + { + printf("running host command: %s\n", hostcommand2); + system(hostcommand2); + } + loop_umount(workblockdevicepath); + rmdir(pc->buildplace); + printf(" -> clean up COW device files\n"); + unlink(workblockdevicepath); + unlink(cowdevpath); + ret=0; + + out: + if(workblockdevicepath) free(workblockdevicepath); + if(cowdevpath) free(cowdevpath); + if(script) free(script); + return ret; +} + +/* + @return shell command to copy the dsc file. + */ +static char* copy_dscfile(const char* dscfile_, const char* destdir) +{ + int ret=1; + size_t bufsiz=0; + char* buf=NULL; + char* filename=NULL; + char* origdir=NULL; + char* dscfile=canonicalize_file_name(dscfile_); + FILE* f=fopen(dscfile,"r"); + + char* memstr=0; + size_t len=0; + FILE* fmem=open_memstream(&memstr, &len); + int filelist=0; + + origdir=strdup(dscfile); + + assert(strrchr(origdir,'/') != 0); + (*(strrchr(origdir,'/')))=0; + + fprintf(fmem, "cp %s %s/\n", + dscfile, destdir); + + while (getline(&buf,&bufsiz,f)>0) + { + if (strrchr(buf,'\n')) + { + *(strrchr(buf,'\n'))=0; + } + if(filelist) + { + if(sscanf(buf, " %*s %*s %as", &filename)!=1) + filelist=0; + else + { + fprintf(fmem, "cp %s/%s %s/\n", + origdir, filename, destdir); + assert(filename); + free(filename); + } + } + if (!(buf[0]==' ')&& + !strcmp(buf,"Files: ")) + { + filelist=1; + } + } + + ret=0; + assert(fmem); + assert(f); + fclose(fmem); + fclose(f); + + if(buf) free(buf); + if(origdir) free(origdir); + if(dscfile) free(dscfile); + return ret?NULL:memstr; +} + +/* + return 0 on success, nonzero on failure. + + variable ret holds the state. + */ +int cpbuilder_create(const struct pbuilderconfig* pc) +{ + int ret=0; + char* s=NULL; /* generic asprintf buffer */ + char* workblockdevicepath=NULL; + FILE* f; + char* t; + char* timestring; + + /* remove existing file; it can be old qemu image, or a directory if + it didn't exist before. */ + unlink(pc->basepath); + rmdir(pc->basepath); + + /* 3GB should be enough to install any Debian system; hopefully */ + ret=create_ext3_block_device(pc->basepath, 3); + + if (ret) + { + goto out; + } + + if (mkdir(pc->buildplace,0777)) + { + /* could not create the buildplace here. */ + ret=1; + perror("mkdir"); + goto out; + } + + ret=loop_mount(pc->basepath, pc->buildplace); + if (ret) + { + goto out; + } + + printf(" -> Invoking debootstrap\n"); + ret=forkexeclp("debootstrap", "debootstrap", + "--arch", + pc->arch, + "--foreign", + pc->distribution, + pc->buildplace, + pc->mirror, + NULL); + if (ret) + { + fprintf(stderr, "debootstrap failed with %i\n", + ret); + goto umount_out; + } + + /* arch-dependent code here. + create required device files. + + ttyAMA0 is probably ARM-specific + others are probably linux-portable as documented in linux/Documentation/devices.txt + other OSes will require different, but hey, they probably don't even boot from ext3, + we'll need think of other ways to work with them. + + */ + printf(" -> Doing architecture-specific /dev population\n"); + + qemu_create_arch_devices(pc->buildplace, pc->arch); + + f = create_script(pc->buildplace, "pbuilder-run"); + fprintf(f, + "#!/bin/bash\n" + "echo \n" + "echo ' -> qemu-pbuilder first-stage' \n" + "export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'\n" + "mount -n /proc /proc -t proc\n" + "mount -n -o rw,remount /\n" + "cp /proc/mounts /etc/mtab\n" + "export PBUILDER_MOUNTPOINT=/var/cache/pbuilder/pbuilder-mnt\n" + "mkdir -p $PBUILDER_MOUNTPOINT\n" + "mount -n -t ext3 /dev/%sb $PBUILDER_MOUNTPOINT \n" + "$PBUILDER_MOUNTPOINT/pbuilder-run \n", + qemu_arch_diskdevice(pc) + ); + fclose(f); + + free(s); s=0; + + ret=loop_umount(pc->buildplace); + + /* create the temporary device for command-execution */ + asprintf(&workblockdevicepath, "%s.dev", pc->buildplace); + ret=create_ext3_block_device(workblockdevicepath, 1); + + loop_mount(workblockdevicepath, pc->buildplace); + + timestring=get_current_time_string(); + + f = create_script(pc->buildplace, "pbuilder-run"); + fprintf(f, + "#!/bin/bash\n" + /* define function to terminate qemu */ + "function exit_from_qemu() {\n" + "%s\n" + "sync\n" + "sync\n" + "sleep 1s\n" /* sleep before sending dying message */ + "echo ' -> qemu-pbuilder %s$1'\n" + "sleep 1s\n" + "halt -f -p\n" /* just halt myself if possible */ + "}\n", + pc->debug?"echo \"Debug shell\"; /bin/bash":"", + qemu_keyword); + + fprintf(f, + /* start of main code */ + "export RET=0\n" + "echo \n" + "echo ' -> qemu-pbuilder second-stage' \n" + "echo ' -> setting time to %s' \n" + "date --set=\"%s\"\n" + "echo ' -> Running debootstrap second-stage script' \n" + "touch /etc/udev/disabled\n" // work-around for #520742 + "/debootstrap/debootstrap --second-stage || ( " + " echo dumping debootstrap log\n" + " cat /debootstrap/debootstrap.log\n" + " exit_from_qemu\n" + "\n )\n" + "rm /etc/udev/disabled\n" // work-around for #520742 + "echo deb %s %s %s > /etc/apt/sources.list \n" + "echo 'APT::Install-Recommends \"false\"; ' > /etc/apt/apt.conf.d/15pbuilder\n" + //TODO: copy hook scripts + "mount -n proc /proc -t proc\n" + "mount -n sysfs /sys -t sysfs\n" + "mkdir /dev/pts\n" + "mount -n devpts /dev/pts -t devpts\n" + "dhclient eth0\n" + "$PBUILDER_MOUNTPOINT/run-copyfiles\n" + "hostname pbuilder-$(cat /etc/hostname)\n" + //TODO: installaptlines + //"echo 'deb http://192.168.1.26/debian/ sid main ' > /etc/apt/sources.list\n" + //TODO: run G hook + "apt-get update || exit_from_qemu 1\n" + //TODO: "dpkg --purge $REMOVEPACKAGES\n" + //recover aptcache + "apt-get -y --force-yes -o DPkg::Options::=--force-confnew dist-upgrade || exit_from_qemu 1\n" + "apt-get install --force-yes -y build-essential dpkg-dev apt aptitude pbuilder || exit_from_qemu 1\n" + //TODO: EXTRAPACKAGES handling + //save aptcache + //optionally autoclean aptcache + //run E hook + //TODO: I can mount /var/cache/apt/archives from some scratch space to not need this: + "apt-get clean || true\n" + "exit_from_qemu $RET\n" + "bash\n", + timestring, + timestring, + t=sanitize_mirror(pc->mirror), pc->distribution, pc->components); + fclose(f); + free(t); + + /* TODO: can I do 'date --set' from output of 'LC_ALL=C date' */ + + /* copy files script */ + f = create_script(pc->buildplace, "run-copyfiles"); + copy_file_contents_through_temp(f, "/etc/hosts", pc->buildplace, "/etc"); + copy_file_contents_through_temp(f, "/etc/hostname", pc->buildplace, "/etc"); + fclose(f); + + /* do I not need to copy /etc/pbuilderrc, and ~/.pbuilderrc to inside chroot? */ + /* TODO: hooks probably need copying here. */ + /* TODO: recover aptcache */ + + loop_umount(workblockdevicepath); + rmdir(pc->buildplace); + + // this will have wrong time. how to workaround? + ret=fork_qemu(pc->basepath, workblockdevicepath, pc); + + unlink(workblockdevicepath); + + out: + if(workblockdevicepath) + { + free(workblockdevicepath); + } + if(s) free(s); + return ret; + + umount_out: + loop_umount(pc->buildplace); + if(s) free(s); + return ret; +} + +/* + * @return: return code of pbuilder, or <0 on failure + */ +int cpbuilder_build(const struct pbuilderconfig* pc, const char* dscfile) +{ + int ret; + char* hoststr=NULL; + char* hoststr2=NULL; + char* commandline=NULL; + + const char* buildopt="--binary-all"; /* TODO: add --binary-arch option */ + + hoststr=copy_dscfile(dscfile, pc->buildplace); + + asprintf(&commandline, + /* TODO: executehooks D: */ + "/usr/lib/pbuilder/pbuilder-satisfydepends --control $PBUILDER_MOUNTPOINT/*.dsc --internal-chrootexec 'chroot . ' %s \n" + "cd $PBUILDER_MOUNTPOINT; /usr/bin/dpkg-source -x $(basename %s) \n" + "echo ' -> Building the package'\n" + /* TODO: executehooks A: */ + "cd $PBUILDER_MOUNTPOINT/*-*/; dpkg-buildpackage -us -uc %s\n", + buildopt, + dscfile, + pc->debbuildopts); + + /* Obscure assumption!: assume _ is significant for package name and + no other file will have _. */ + + asprintf(&hoststr2, + "cp -p \"%s\"/*_* \"%s\" 2>/dev/null || true", + pc->buildplace, pc->buildresult); + + ret=run_second_stage_script + (0, + commandline, pc, + hoststr, + hoststr2); + + if(hoststr2) free(hoststr2); + if(hoststr) free(hoststr); + if(commandline) free(commandline); + return ret; +} + +int cpbuilder_login(const struct pbuilderconfig* pc) +{ + return run_second_stage_script(pc->save_after_login, + "bash", + pc, + NULL, + NULL); +} + +/* + +Mostly a copy of pbuilder login, executes a script. + + */ +int cpbuilder_execute(const struct pbuilderconfig* pc, char** av) +{ + char* hostcommand; + char* runcommandline; + int ret; + + asprintf(&hostcommand, "cp %s %s/run\n", av[0], pc->buildplace); + /* TODO: add options too */ + asprintf(&runcommandline, "sh $PBUILDER_MOUNTPOINT/run"); + ret=run_second_stage_script(pc->save_after_login, runcommandline, pc, + hostcommand, NULL); + free(hostcommand); + free(runcommandline); + return ret; +} + +/** + implement pbuilder update + + @return 0 on success, other values on failure. + */ +int cpbuilder_update(const struct pbuilderconfig* pc) +{ + /* TODO: --override-config support. + There is no way to change distribution in this code-path... + */ + return run_second_stage_script + (1, + //TODO: installaptlines if required. + //TODO: "dpkg --purge $REMOVEPACKAGES\n" + //TODO: add error code handling. + "apt-get update -o Acquire::PDiffs=false\n" + "apt-get -y --force-yes -o DPkg::Options::=--force-confnew dist-upgrade\n" + "apt-get install --force-yes -y build-essential dpkg-dev apt aptitude pbuilder\n" + //TODO: EXTRAPACKAGES handling + //optionally autoclean aptcache + //run E hook + , pc, + NULL, NULL); +} + +int cpbuilder_help(void) +{ + printf("qemubuilder [operation] [options]\n" + "operation:\n" + " --build\n" + " --create\n" + " --update\n" + " --login\n" + " --execute\n" + " --help\n" + " --dumpconfig\n" + "options:\n" + " --basepath:\n" + " --buildplace:\n" + " --distribution:\n" + " ... and other pbuilder options \n" + ); + return 0; +} + +int app_main(int ac, char** av) +{ + return parse_parameter(ac, av, "qemu"); +} diff -Nru cowdancer-0.62/.pc/applied-patches cowdancer-0.62+nmu1/.pc/applied-patches --- cowdancer-0.62/.pc/applied-patches 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/.pc/applied-patches 2010-09-17 16:15:58.000000000 +0200 @@ -0,0 +1 @@ +564425.patch diff -Nru cowdancer-0.62/.pc/.quilt_patches cowdancer-0.62+nmu1/.pc/.quilt_patches --- cowdancer-0.62/.pc/.quilt_patches 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/.pc/.quilt_patches 2010-09-17 16:15:58.000000000 +0200 @@ -0,0 +1 @@ +debian/patches diff -Nru cowdancer-0.62/.pc/.quilt_series cowdancer-0.62+nmu1/.pc/.quilt_series --- cowdancer-0.62/.pc/.quilt_series 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/.pc/.quilt_series 2010-09-17 16:15:58.000000000 +0200 @@ -0,0 +1 @@ +series diff -Nru cowdancer-0.62/.pc/.version cowdancer-0.62+nmu1/.pc/.version --- cowdancer-0.62/.pc/.version 1970-01-01 01:00:00.000000000 +0100 +++ cowdancer-0.62+nmu1/.pc/.version 2010-09-17 16:15:58.000000000 +0200 @@ -0,0 +1 @@ +2 diff -Nru cowdancer-0.62/qemubuilder.c cowdancer-0.62+nmu1/qemubuilder.c --- cowdancer-0.62/qemubuilder.c 2010-08-15 16:27:44.000000000 +0200 +++ cowdancer-0.62+nmu1/qemubuilder.c 2010-09-17 16:18:02.000000000 +0200 @@ -471,7 +471,7 @@ system(hostcommand1); } - loop_umount(workblockdevicepath); + loop_umount(pc->buildplace); asprintf(&cowdevpath, "%s.cowdev", pc->buildplace); ret=forkexeclp("qemu-img", "qemu-img", @@ -504,7 +504,7 @@ printf("running host command: %s\n", hostcommand2); system(hostcommand2); } - loop_umount(workblockdevicepath); + loop_umount(pc->buildplace); rmdir(pc->buildplace); printf(" -> clean up COW device files\n"); unlink(workblockdevicepath); @@ -755,7 +755,7 @@ /* TODO: hooks probably need copying here. */ /* TODO: recover aptcache */ - loop_umount(workblockdevicepath); + loop_umount(pc->buildplace); rmdir(pc->buildplace); // this will have wrong time. how to workaround?

