Package: qemubuilder Version: 0.78 Severity: wishlist Tags: patch Hi,
it would be awesome if qemubuilder supported running hooks during build, so that you are able to customize it. I implemented copying files from a directory (HOOKDIR=) to qemu and run some of pbuilder's supported hook types at the correct time. Kind regards, Reiner
From 095eeb43c44f62eb369fe9e3acb97dad28c60235 Mon Sep 17 00:00:00 2001 From: Reiner Herrmann <[email protected]> Date: Sat, 2 Apr 2016 14:25:03 +0200 Subject: [PATCH] qemubuilder: add support for hooks Copy files from the directory configured in the HOOKDIR setting to the hook dir in qemu (/etc/pbuilder/hooks). The hooks are then run at the appropriate times, depending on the first letter of the filename, comparable to the pbuilder hooks. Hooks of the following types are currently supported: A, D, E, F, G --- parameter.c | 5 +++++ parameter.h | 1 + qemubuilder.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/parameter.c b/parameter.c index 8c015a6..8a41660 100644 --- a/parameter.c +++ b/parameter.c @@ -190,6 +190,10 @@ int load_config_file(const char* config, pbuilderconfig* pc) { pc->http_proxy=strdup_strip_quote(delim); } + else if (!strcmp(buf, "HOOKDIR")) + { + pc->hookdir=strdup_strip_quote(delim); + } } } @@ -237,6 +241,7 @@ int cpbuilder_dumpconfig(pbuilderconfig* pc) DUMPSTR(debbuildopts); DUMPINT(binary_arch); DUMPSTR(http_proxy); + DUMPSTR(hookdir); DUMPSTRARRAY(inputfile); DUMPSTRARRAY(outputfile); diff --git a/parameter.h b/parameter.h index 9ef23a7..7f0aa9b 100644 --- a/parameter.h +++ b/parameter.h @@ -41,6 +41,7 @@ typedef struct pbuilderconfig char* debbuildopts; int binary_arch; char* http_proxy; + char* hookdir; /* files to be copied into the chroot, and copied out of the chroot */ diff --git a/qemubuilder.c b/qemubuilder.c index 502a48a..4f8fb65 100755 --- a/qemubuilder.c +++ b/qemubuilder.c @@ -27,6 +27,8 @@ #include <sys/socket.h> #include <string.h> #include <unistd.h> +#include <errno.h> +#include <dirent.h> #include <getopt.h> #include <stdarg.h> #include <assert.h> @@ -38,6 +40,9 @@ #include "qemuarch.h" #include "file.h" +#define HOOKDIR "/etc/pbuilder/hooks" +#define execute_hooks(type) "for hook in $(ls "HOOKDIR" | grep ^" type "); do echo \" -> Running hook $hook\"; BUILDDIR=/tmp/buildd "HOOKDIR"/$hook; done\n" + /* * example exit codes: * @@ -174,13 +179,47 @@ static int copy_file_contents_through_temp(FILE* f, fprintf(f, "echo \"I: copying %s/%s from temporary location\"\n" + "mkdir -p %s\n" "cp $PBUILDER_MOUNTPOINT/%s %s/%s || echo \"E: Copy failed\"\n", targetdir, file_basename, + targetdir, file_basename, targetdir, file_basename); return ret; } +static void copy_hooks_dir(FILE *f, const char *hooks_dir, const char *tmp) +{ + struct dirent *dirp; + DIR *hd = opendir(hooks_dir); + + if (hd == NULL) + { + printf("can't copy hooks from '%s': %s\n", hooks_dir, strerror(errno)); + return; + } + + while((dirp = readdir(hd)) != NULL) + { + struct stat st; + char *src = NULL; + + asprintf(&src, "%s/%s", hooks_dir, dirp->d_name); + if (stat(src, &st) == -1) + { + printf("can't stat file '%s': %s\n", src, strerror(errno)); + continue; + } + + if ((st.st_mode & S_IFMT) != S_IFREG) + continue; + + copy_file_contents_through_temp(f, src, tmp, HOOKDIR); + fprintf(f, "chmod 0755 %s/%s\n", HOOKDIR, dirp->d_name); + } + closedir(hd); +} + /** run qemu until exit signal is received from within QEMU via serial console. @@ -479,9 +518,10 @@ static int run_second_stage_script "export IFNAME=`/sbin/ifconfig -a | grep eth | head -n1 | awk '{print $1}'`\n" "dhclient $IFNAME\n" "mkdir -p /tmp/buildd\n" + "mkdir -p "HOOKDIR"\n" "$PBUILDER_MOUNTPOINT/run-copyfiles\n" "hostname pbuilder-$(cat /etc/hostname)\n" - //TODO: run G hook + execute_hooks("G") "%s\n" //TODO: I can mount /var/cache/apt/archives from some scratch space to not need this: "apt-get clean || true\n" @@ -500,10 +540,14 @@ static int run_second_stage_script { copy_file_contents_through_temp(f, pc->inputfile[i], pc->buildplace, "/tmp/buildd"); } + /* copy hooks */ + if (pc->hookdir != NULL) + { + copy_hooks_dir(f, pc->hookdir, pc->buildplace); + } 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) @@ -778,11 +822,12 @@ int cpbuilder_create(const struct pbuilderconfig* pc) "mkdir /dev/pts\n" "mount -n devpts /dev/pts -t devpts\n" "dhclient eth0\n" + "mkdir -p "HOOKDIR"\n" "$PBUILDER_MOUNTPOINT/run-copyfiles\n" "hostname pbuilder-$(cat /etc/hostname)\n" //TODO: installaptlines "echo '%s' > /etc/apt/sources.list.d/other.list\n" - //TODO: run G hook + execute_hooks("G") "apt-get update || exit_from_qemu 1\n" //TODO: "dpkg --purge $REMOVEPACKAGES\n" //recover aptcache @@ -791,7 +836,7 @@ int cpbuilder_create(const struct pbuilderconfig* pc) //TODO: EXTRAPACKAGES handling //save aptcache //optionally autoclean aptcache - //run E hook + execute_hooks("E") //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" @@ -811,10 +856,14 @@ int cpbuilder_create(const struct pbuilderconfig* pc) 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 hooks */ + if (pc->hookdir != NULL) + { + copy_hooks_dir(f, pc->hookdir, pc->buildplace); + } 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(pc->buildplace); @@ -864,11 +913,11 @@ int cpbuilder_build(const struct pbuilderconfig* pc, const char* dscfile) hoststr=copy_dscfile(dscfile, pc->buildplace); asprintf(&commandline, - /* TODO: executehooks D: */ + execute_hooks("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: */ + execute_hooks("A") "cd $PBUILDER_MOUNTPOINT/*-*/; dpkg-buildpackage -us -uc %s\n", buildopt, dscfile, @@ -897,6 +946,7 @@ int cpbuilder_build(const struct pbuilderconfig* pc, const char* dscfile) int cpbuilder_login(const struct pbuilderconfig* pc) { return run_second_stage_script(pc->save_after_login, + execute_hooks("F") "bash", pc, NULL, @@ -916,7 +966,9 @@ int cpbuilder_execute(const struct pbuilderconfig* pc, char** av) asprintf(&hostcommand, "cp %s %s/runscript\n", av[0], pc->buildplace); /* TODO: add options too */ - asprintf(&runcommandline, "sh $PBUILDER_MOUNTPOINT/runscript"); + asprintf(&runcommandline, + execute_hooks("F") + "sh $PBUILDER_MOUNTPOINT/runscript"); ret=run_second_stage_script(pc->save_after_login, runcommandline, pc, hostcommand, NULL); free(hostcommand); @@ -944,7 +996,7 @@ int cpbuilder_update(const struct pbuilderconfig* pc) "apt-get install --force-yes -y build-essential dpkg-dev apt aptitude pbuilder\n" //TODO: EXTRAPACKAGES handling //optionally autoclean aptcache - //run E hook + execute_hooks("E") , pc, NULL, NULL); } -- 2.8.0.rc3
signature.asc
Description: PGP signature

