[iwhd] Update NEWS with Condor back-end.
by Pete Zaitcev
commit b3b93429e1feddfde57766550978c2b2a7763e1b
Author: Pete Zaitcev <zaitcev(a)yahoo.com>
Date: Thu Mar 31 14:22:59 2011 -0600
Update NEWS with Condor back-end.
NEWS | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
---
diff --git a/NEWS b/NEWS
index 1c70e8e..450acee 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
iwhd NEWS -*- outline -*-
+* Noteworthy changes in trunk (to be release 0.93 [stable])
+
+** New features
+
+ Condor back-end
+
* Noteworthy changes in release 0.92 (2011-03-15) [stable]
** New features
13 years
[iwhd] Add Condor Cloud back-end
by Pete Zaitcev
commit 57f831d3f2509a8a96d1b4e62b048128d4c25223
Author: Pete Zaitcev <zaitcev(a)yahoo.com>
Date: Thu Mar 31 14:13:03 2011 -0600
Add Condor Cloud back-end
The "Condor" is a toy back-end that Aeolus people use. This patch adds
a basic support for it, including a build-time test (t/registration).
The test also serves as documentation for now.
Makefile.am | 1 +
backend.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
dc-condor-image | 100 +++++++++++++++++++++++++++++++++++++
setup.c | 10 +++-
t/Makefile.am | 3 +-
t/registration | 97 ++++++++++++++++++++++++++++++++++++
6 files changed, 358 insertions(+), 2 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index bda9d64..a0a3c52 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,6 +24,7 @@ ACLOCAL_AMFLAGS = -I m4
bin_PROGRAMS = iwhd dc-rhev-image
EXTRA_DIST = \
+ dc-condor-image \
dc-register-image \
iwhd.init.in \
qparser.h \
diff --git a/backend.c b/backend.c
index 8e4a9cb..101f520 100644
--- a/backend.c
+++ b/backend.c
@@ -1558,6 +1558,144 @@ cleanup:
return rc;
}
+static int
+fs_condor_register (my_state *ms, const provider_t *prov, const char *next,
+ Hash_table *args)
+{
+ char *kernel = kv_hash_lookup(args,"kernel");
+ char *ramdisk = kv_hash_lookup(args,"ramdisk");
+ const char *nfs_dir;
+ const char *argv[12];
+ unsigned int argc = 0;
+ pid_t pid;
+ int organ[2];
+ int wstat;
+ FILE *fp;
+ char buf[LINE_SIZE];
+ char *s;
+ int rc = MHD_HTTP_BAD_REQUEST;
+ char ami_id_buf[64];
+ regmatch_t match[2];
+
+ strcpy(ami_id_buf, "none");
+
+ if (!regex_ok) {
+ return MHD_HTTP_BAD_REQUEST;
+ }
+
+ if (next) {
+ DPRINTF("Falcon register with next!=NULL\n");
+ return MHD_HTTP_BAD_REQUEST;
+ }
+
+ DPRINTF("*** register %s/%s via %s\n",
+ ms->bucket, ms->key, prov->name);
+ if (kernel) {
+ DPRINTF(" (using kernel %s)\n",kernel);
+ }
+ if (ramdisk) {
+ DPRINTF(" (using ramdisk %s)\n",ramdisk);
+ }
+
+ /*
+ * The discrepancy between POST argument key "nfs-dir" and JSON
+ * key "nfsdir" is unfortunate, but nfs-dir was there first.
+ */
+ nfs_dir = kv_hash_lookup(args,"nfs-dir");
+ if (!nfs_dir) {
+ nfs_dir = get_provider_value(prov,"nfsdir");
+ if (!nfs_dir) {
+ error (0, 0,
+ _("missing target directory (nfs-dir,nfsdir)"));
+ goto cleanup;
+ }
+ }
+
+ /*
+ * This is the point where we go from validation to execution. If we
+ * were double-forking so this could all be asynchronous, or for that
+ * matter to return an early 100-continue, this would probably be the
+ * place to do it. Even without that, we set the ami-id here so that
+ * the caller can know things are actually in progress.
+ */
+ sprintf(ami_id_buf,"pending %lld",(long long)time(NULL));
+ DPRINTF("temporary ami-id = \"%s\"\n",ami_id_buf);
+ (void)meta_set_value(ms->bucket,ms->key,"ami-id",ami_id_buf);
+ rc = MHD_HTTP_INTERNAL_SERVER_ERROR;
+
+ const char *cmd = "dc-condor-image";
+ argv[argc++] = cmd;
+ argv[argc++] = ms->bucket;
+ argv[argc++] = ms->key;
+ argv[argc++] = nfs_dir;
+ argv[argc++] = kernel ? kernel : "_default_";
+ argv[argc++] = ramdisk ? ramdisk : "_default_";
+ argv[argc] = NULL;
+ assert (argc < ARRAY_CARDINALITY (argv));
+
+ if (pipe(organ) < 0) {
+ error (0, errno, _("pipe creation failed"));
+ goto cleanup;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ error (0, errno, _("fork failed"));
+ close(organ[0]);
+ close(organ[1]);
+ goto cleanup;
+ }
+
+ if (pid == 0) {
+ (void)dup2(organ[1],STDOUT_FILENO);
+ (void)dup2(organ[1],STDERR_FILENO);
+ execvp(cmd, (char* const*)argv);
+ error (EXIT_FAILURE, errno, _("failed to run command %s"), cmd);
+ }
+
+ close(organ[1]);
+ fp = fdopen(organ[0],"r");
+ if (!fp) {
+ error (0, 0, _("could not open parent pipe stream"));
+ close(organ[0]);
+ goto cleanup;
+ }
+ while (fgets(buf,sizeof(buf)-1,fp)) {
+ if ((s = strchr(buf, '\n')) != NULL)
+ *s = '\0';
+ if (regexec(&s3_success_pat,buf,2,match,0) == 0) {
+ buf[match[1].rm_eo] = '\0';
+ DPRINTF("found AMI ID: %s\n",buf+match[1].rm_so);
+ sprintf(ami_id_buf,"OK %.60s",buf+match[1].rm_so);
+ rc = MHD_HTTP_OK;
+ }
+ else {
+ DPRINTF("ignoring line: <%s>\n",buf);
+ }
+ }
+ fclose(fp);
+
+ DPRINTF("waiting for child...\n");
+ if (waitpid(pid,&wstat,0) < 0) {
+ error (0, errno, _("waitpid failed"));
+ goto cleanup;
+ }
+ if (!WIFEXITED(wstat)) {
+ error (0, 0, _("%s is killed (status 0x%x)"), cmd, wstat);
+ goto cleanup;
+ }
+ if (WEXITSTATUS(wstat)) {
+ error (0, 0, _("%s exited with code %d"),
+ cmd, WEXITSTATUS(wstat));
+ goto cleanup;
+ }
+ DPRINTF("...child exited\n");
+
+cleanup:
+ (void)meta_set_value(ms->bucket,ms->key,"ami-id",ami_id_buf);
+ return rc;
+}
+
/***** Function tables. ****/
backend_func_tbl bad_func_tbl = {
@@ -1625,3 +1763,14 @@ backend_func_tbl fs_rhevm_func_tbl = {
fs_bcreate,
fs_rhevm_register,
};
+
+backend_func_tbl fs_condor_func_tbl = {
+ "FS-FALCON",
+ fs_init,
+ fs_get_child,
+ fs_put_child,
+ bad_cache_child,
+ fs_delete,
+ fs_bcreate,
+ fs_condor_register,
+};
diff --git a/dc-condor-image b/dc-condor-image
new file mode 100755
index 0000000..4f91435
--- /dev/null
+++ b/dc-condor-image
@@ -0,0 +1,100 @@
+#!/bin/bash
+
+# Copyright (C) 2010-2011 Red Hat, Inc.
+
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+ME=$(expr "./$0" : '.*/\(.*\)$')
+warn () { printf '%s\n' "$@" >&2; }
+die () { warn "$ME: $@"; exit 1; }
+
+# spidesc: Spit the XML at $1/$2.xml.
+#
+# This is the same XML spec that virsh uses for "dumpxml" and "define",
+# but it cannot be fed straight to virsh on purpose. A tool has to load it,
+# then fill out things like network, RAM, clock type, and OS features.
+spitdesc () {
+ tgtdir=$1; shift
+ object=$1; shift
+ export object
+
+ cat <<EOF > $tgtdir/$object.xml
+<domain type='kvm'>
+ <name>${object}</name>
+ <uuid>00000000-0000-0000-0000-000000000000</uuid>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='${object}'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ </devices>
+</domain>
+EOF
+ # Should we print something here if $?!=0, or expect cat to complain?
+ return $?
+}
+
+# main()
+
+# $bucket is iwhd bucket.
+bucket=$1; shift
+# $object is iwhd's image name, which also serves as ID.
+# So, if $object=foo.img, then we end uploading foo.img.xml.
+# The foo.img itself is an uncompressed root filesystem, a device image.
+# Finally, $object is in local directory $bucket/ (as fs back-end works).
+object=$1; shift
+# $nfsdir is the target directory, not including staging/.
+# It has to be absolute, because we rely on $bucket/$object being enough to
+# open the source and that's only possible if $pwd is the top of fs back-end.
+nfsdir=$1; shift
+
+test -z "$bucket" && die "No bucket"
+test -z "$object" && die "No object"
+test -z "$nfsdir" && die "No nfsdir"
+test -d "$nfsdir" || die "Not a directory: $nfsdir"
+
+#
+# We require staging/ to be pre-made, because it's a useful signifier
+# of correct target, in case of a configuration error in iwhd.
+#
+test -d "$nfsdir/staging" \
+ || die "Required directory is missing: $nfsdir/staging"
+
+#
+# The API defines staging/ for a good reason: if anything goes wrong,
+# a clean-up process can collect pieces even if we crash. So, create temp
+# in staging/, but be polite and set a trap anyway.
+#
+tmpdir=
+trap "rm -rf $tmpdir" 0
+tmpdir=$(mktemp -d -p $nfsdir/staging) || exit 1
+for sig_ in 1 2 3 13 15; do
+ eval "trap 'exit $(expr $sig_ + 128)' $sig_"
+done
+
+cp "$bucket/$object" "$tmpdir/$object" || exit 1
+spitdesc $tmpdir $object || exit 1
+
+# great, we didn't run out of disk space, now rename and declare victory.
+mv $tmpdir/$object $tmpdir/$object.xml "$nfsdir"
+
+# Spit the ID like EC2. Thus far it's always the same as $object, but
+# officially it does not have to be.
+echo "IMAGE $object"
+exit 0
diff --git a/setup.c b/setup.c
index 5e32387..8a46977 100644
--- a/setup.c
+++ b/setup.c
@@ -67,6 +67,7 @@ extern backend_func_tbl curl_func_tbl;
extern backend_func_tbl cf_func_tbl;
extern backend_func_tbl fs_func_tbl;
extern backend_func_tbl fs_rhevm_func_tbl;
+extern backend_func_tbl fs_condor_func_tbl;
static json_t *config = NULL;
static Hash_table *prov_hash = NULL;
@@ -213,7 +214,9 @@ json_validate_server (unsigned int i)
else if (!strcasecmp(type,"http")) {
needs = NEED_SERVER;
}
- else if (!strcasecmp(type,"fs") || !strcasecmp(type,"fs-rhev-m")) {
+ else if (!strcasecmp(type,"fs") ||
+ !strcasecmp(type,"fs-rhev-m") ||
+ !strcasecmp(type,"fs-condor")) {
needs = NEED_PATH;
}
else {
@@ -334,6 +337,9 @@ convert_provider (int i, provider_t *out)
else if (!strcasecmp(out->type,"fs-rhev-m")) {
out->func_tbl = &fs_rhevm_func_tbl;
}
+ else if (!strcasecmp(out->type,"fs-condor")) {
+ out->func_tbl = &fs_condor_func_tbl;
+ }
else {
out->func_tbl = &bad_func_tbl;
}
@@ -436,6 +442,8 @@ add_provider (Hash_table *h)
prov->func_tbl = &fs_func_tbl;
else if (!strcasecmp(prov->type,"fs-rhev-m"))
prov->func_tbl = &fs_rhevm_func_tbl;
+ else if (!strcasecmp(prov->type,"fs-condor"))
+ prov->func_tbl = &fs_condor_func_tbl;
else
prov->func_tbl = &bad_func_tbl;
diff --git a/t/Makefile.am b/t/Makefile.am
index a671c05..d7e3fbf 100644
--- a/t/Makefile.am
+++ b/t/Makefile.am
@@ -19,7 +19,8 @@ TESTS = \
basic \
provider \
replication \
- auto
+ auto \
+ registration
lock_dir = $(abs_builddir)/lock-dir
clean-local:
diff --git a/t/registration b/t/registration
new file mode 100644
index 0000000..c5407a3
--- /dev/null
+++ b/t/registration
@@ -0,0 +1,97 @@
+#!/bin/sh
+# Test registration functionality.
+# (currently Falcon only)
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+
+mkdir -p reg/mongod reg/_fs reg/condor/staging \
+ || framework_failure_ mkdir failed
+
+port=$(get_port 9095 $lock_dir/i-) || fail_ "failed to get iwhd port"
+m_port=$(get_port $mongo_base_port $lock_dir/m-) \
+ || fail_ "failed to get mongodb port"
+
+mongod --port $m_port --pidfilepath reg/mongod/pid --dbpath reg/mongod \
+ > reg/mongod.log 2>&1 &
+mongo_pid=$!
+cleanup_() { kill -9 $mongo_pid; }
+
+# Wait for up to 12 seconds for mongod to begin listening.
+wait_for .1 120 'mongo localhost:$m_port < /dev/null' \
+ || framework_failure_ mongod failed to start
+
+# Nobody sanity-checks nfsdir for being absolute pathname, but as it happens
+# iwhd runs dc-condor-image inside the fs back-end top directory, so
+# we must use an absolute path anyway.
+cat > iwhd_reg.conf << EOF
+[
+ {
+ "name": "main",
+ "type": "fs-condor",
+ "path": "reg/_fs",
+ "nfsdir": "$(pwd)/reg/condor"
+ }
+]
+EOF
+
+PATH=$PATH:${abs_top_srcdir} iwhd -v -p $port -c iwhd_reg.conf \
+ -d localhost:$m_port &
+iwhd_pid=$!
+cleanup_() { kill -9 $mongo_pid; kill $iwhd_pid; }
+
+wait_for .1 50 "curl -s http://localhost:$port" \
+ || framework_failure_ iwhd failed to start
+
+# Create an empty bucket.
+curl -X PUT http://localhost:$port/buk || fail=1
+# Create a file in that bucket.
+dd if=/dev/zero bs=8k count=1 2>/dev/null | \
+ curl -T - http://localhost:$port/buk/test_image || fail=1
+
+# Encoding the image as a here document is not future-proof in that it's
+# entirely legal for the registration script to format XML in whatever way.
+# However, this test works for us as long as the dc-condor-image also
+# generates the XML from a similar literal (instead of, say, calling xslt).
+cat <<EOF > reg/test_image.known.xml || framework_failure_
+<domain type='kvm'>
+ <name>test_image</name>
+ <uuid>00000000-0000-0000-0000-000000000000</uuid>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='test_image'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ </devices>
+</domain>
+EOF
+
+curl -d op=register -d site=main http://localhost:$port/buk/test_image
+# This location (condor/${ID}.xml) is future-proof as a part of Falcon API.
+compare reg/condor/test_image.xml reg/test_image.known.xml || fail=1
+# BTW, check if we saved the image, too. It's full of zeroes though...
+[ -s reg/condor/test_image ] || fail=1
+
+# One poorly understood feature of curl is that it actually exits with zero
+# upon an HTTP server error such as our favourite 500. The -f flag suppresses
+# the output to stderr _and_ enables error exit code. This is crazy, insane.
+# But it's life. We run one final curl with -f, in case iwhd spams 500 at us.
+curl -f http://localhost:$port/buk/test_image/ami-id > reg/ami-id || fail=1
+read regstatus regid < reg/ami-id
+# There may be conditions when registration failure is not detected, but
+# produces a diagnostic message inside the ami-id attribute (e.g. "pending").
+if [ "$regstatus" != "OK" ]; then
+ echo "Registration error:" $(cat reg/ami-id) >&2
+ fail=1
+fi
+# Current dc-condor-image returns the name that we sent as an ID. Verify that.
+if [ "$regid" != "test_image" ]; then
+ echo "Registration ID mismatch:" $(cat reg/ami-id) >&2
+ fail=1
+fi
+
+Exit $fail
13 years
[iwhd] Fix-ups for backend.c buglets
by Pete Zaitcev
commit 3b57ba96611e07974c3fd9595ede577421594e05
Author: Pete Zaitcev <zaitcev(a)yahoo.com>
Date: Thu Mar 31 14:10:05 2011 -0600
Fix-ups for backend.c buglets
This fell out of reviews associated with Condor.
- Add dc-register-image to EXTRA_DIST so that it's installed
- Correct confusion of rc vs ret
- Treat tagged errors in RHEV registration script as show-stopper
- Set ami_id_buf so that cleanup paths work
- Add an assert for a couple of "never happens" overflows
Makefile.am | 1 +
backend.c | 24 ++++++++++++++++--------
2 files changed, 17 insertions(+), 8 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 8fe1f88..bda9d64 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,6 +24,7 @@ ACLOCAL_AMFLAGS = -I m4
bin_PROGRAMS = iwhd dc-rhev-image
EXTRA_DIST = \
+ dc-register-image \
iwhd.init.in \
qparser.h \
iwhd.spec \
diff --git a/backend.c b/backend.c
index ad6da01..8e4a9cb 100644
--- a/backend.c
+++ b/backend.c
@@ -44,6 +44,8 @@
#include "state_defs.h"
#include "ignore-value.h"
+#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
+
#define NFSGID 36
struct hstor_client *hstor;
@@ -373,8 +375,8 @@ s3_register (my_state *ms, const provider_t *prov, const char *next,
const char *ami_key;
const char *ami_uid;
const char *argv[12];
- int argc = 0;
- pid_t pid;
+ unsigned int argc = 0;
+ pid_t pid;
int organ[2];
int wstat;
FILE *fp;
@@ -387,6 +389,8 @@ s3_register (my_state *ms, const provider_t *prov, const char *next,
char ami_id_buf[64];
regmatch_t match[2];
+ strcpy(ami_id_buf, "none");
+
if (!regex_ok) {
return MHD_HTTP_BAD_REQUEST;
}
@@ -492,6 +496,7 @@ s3_register (my_state *ms, const provider_t *prov, const char *next,
argv[argc++] = kernel ? kernel : "_default_";
argv[argc++] = ramdisk ? ramdisk : "_default_";
argv[argc] = NULL;
+ assert (argc < ARRAY_CARDINALITY (argv));
DPRINTF("api-key = %s\n",api_key);
DPRINTF("api-secret = %s\n",api_secret);
@@ -1350,11 +1355,10 @@ fs_rhevm_register (my_state *ms, const provider_t *prov, const char *next,
char *nfs_dir;
const char *conf_name = NULL;
char *conf_text;
- int ret = MHD_HTTP_BAD_REQUEST;
- int rc;
+ int rc = MHD_HTTP_BAD_REQUEST;
const char *argv[12];
- int argc = 0;
- pid_t pid;
+ unsigned int argc = 0;
+ pid_t pid;
int organ[2];
int wstat;
FILE *fp;
@@ -1363,6 +1367,8 @@ fs_rhevm_register (my_state *ms, const provider_t *prov, const char *next,
char ami_id_buf[64];
regmatch_t match[2];
+ strcpy(ami_id_buf, "none");
+
if (!regex_ok) {
return MHD_HTTP_BAD_REQUEST;
}
@@ -1472,6 +1478,7 @@ fs_rhevm_register (my_state *ms, const provider_t *prov, const char *next,
argv[argc++] = cmd;
argv[argc++] = conf_name;
argv[argc] = NULL;
+ assert (argc < ARRAY_CARDINALITY (argv));
if (pipe(organ) < 0) {
error (0, errno, _("pipe creation failed"));
@@ -1507,7 +1514,8 @@ fs_rhevm_register (my_state *ms, const provider_t *prov, const char *next,
buf[match[1].rm_eo] = '\0';
DPRINTF("found image UUID: %s\n",buf+match[1].rm_so);
sprintf(ami_id_buf,"OK %.60s",buf+match[1].rm_so);
- rc = MHD_HTTP_OK;
+ if (rc == MHD_HTTP_BAD_REQUEST)
+ rc = MHD_HTTP_OK;
}
else if (strcmp(buf,"ERROR") == 0) {
DPRINTF("found err marker: %s\n",buf+sizeof("ERROR"));
@@ -1547,7 +1555,7 @@ cleanup:
free((char *)conf_name);
(void)meta_set_value(ms->bucket,ms->key,"ami-id",ami_id_buf);
- return ret;
+ return rc;
}
/***** Function tables. ****/
13 years
[iwhd] maint: remove lock-dir so that "make distcheck" passes again
by Jim Meyering
commit dcc96fb823243daeca938772b9a8b56592892d5b
Author: Jim Meyering <meyering(a)redhat.com>
Date: Thu Mar 31 08:28:14 2011 +0200
maint: remove lock-dir so that "make distcheck" passes again
* t/Makefile.am (clean-local): New rule, to remove temporary lock-dir.
Reported by Pete Zaitcev.
t/Makefile.am | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
---
diff --git a/t/Makefile.am b/t/Makefile.am
index 6ffdfc8..a671c05 100644
--- a/t/Makefile.am
+++ b/t/Makefile.am
@@ -22,7 +22,9 @@ TESTS = \
auto
lock_dir = $(abs_builddir)/lock-dir
-CONFIG_CLEAN_FILES = lock-dir
+clean-local:
+ $(AM_V_GEN)rm -rf "$(lock_dir)"
+
.PHONY: prereq
prereq:
$(AM_V_GEN)rm -rf "$(lock_dir)" && mkdir "$(lock_dir)"
13 years
[iwhd] fix bug in previous change
by Jim Meyering
commit 8d9258f39f503d3f1a062c37682f6969bc69ccfd
Author: Jim Meyering <meyering(a)redhat.com>
Date: Thu Mar 31 07:41:43 2011 +0200
fix bug in previous change
* rest.c (recheck_replication): Don't return early just because
the first attempt to find policy failed. Remove now-unnecessary
if-block.
rest.c | 29 ++++++++++-------------------
1 files changed, 10 insertions(+), 19 deletions(-)
---
diff --git a/rest.c b/rest.c
index 41acc53..25e9847 100644
--- a/rest.c
+++ b/rest.c
@@ -373,36 +373,27 @@ recheck_replication (my_state *ms, char *policy)
if (!policy) {
DPRINTF("fetching policy for %s/%s\n",ms->bucket,ms->key);
int rc = meta_get_value(ms->bucket,ms->key, "_policy", &policy);
- if (rc) {
+ if (rc)
error (0, rc, _("failed to get policy for %s/%s"),
ms->bucket,ms->key);
- return;
- }
}
if (!policy) {
DPRINTF(" inheriting policy from %s\n",ms->bucket);
int rc = meta_get_value(ms->bucket, "_default",
"_policy", &policy);
- if (rc) {
+ if (rc || !policy)
error (0, rc, _("failed to get default policy"));
- return;
- }
}
- if (policy) {
- char fixed[MAX_FIELD_LEN];
- DPRINTF(" implementing policy %s\n",policy);
- /*
- * Can't use ms->url here because it might be a bucket POST
- * and in that case ms->url points to the bucket.
- */
- snprintf(fixed,sizeof(fixed),"%s/%s",ms->bucket,ms->key);
- replicate(fixed,0,policy,ms);
- }
- else {
- DPRINTF(" could not find a policy anywhere!\n");
- }
+ char fixed[MAX_FIELD_LEN];
+ DPRINTF(" implementing policy %s\n",policy);
+ /*
+ * Can't use ms->url here because it might be a bucket POST
+ * and in that case ms->url points to the bucket.
+ */
+ snprintf(fixed,sizeof(fixed),"%s/%s",ms->bucket,ms->key);
+ replicate(fixed,0,policy,ms);
}
static int
13 years
[iwhd] don't segfault upon ignored meta_get_value failure
by Jim Meyering
commit caa81f4353ffccb71cbf790afb4366c143a8b28c
Author: Jim Meyering <meyering(a)redhat.com>
Date: Wed Mar 30 20:34:32 2011 +0200
don't segfault upon ignored meta_get_value failure
This legitimate bug was highlighted by a
"variable 'rc' set but not used" compiler warning.
* rest.c (recheck_replication): Rather than ignoring meta_get_value
failure, which could probably lead to a segfault, diagnose it and
return early.
rest.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
---
diff --git a/rest.c b/rest.c
index 3dfea2b..41acc53 100644
--- a/rest.c
+++ b/rest.c
@@ -358,10 +358,8 @@ proxy_get_data (void *cctx, struct MHD_Connection *conn, const char *url,
}
static void
-recheck_replication (my_state * ms, char *policy)
+recheck_replication (my_state *ms, char *policy)
{
- int rc; /* FIXME: set but never used */
-
if (is_reserved(ms->key,reserved_name)) {
DPRINTF("declining to replicate reserved object %s\n",ms->key);
return;
@@ -374,13 +372,22 @@ recheck_replication (my_state * ms, char *policy)
if (!policy) {
DPRINTF("fetching policy for %s/%s\n",ms->bucket,ms->key);
- rc = meta_get_value(ms->bucket,ms->key, "_policy", &policy);
+ int rc = meta_get_value(ms->bucket,ms->key, "_policy", &policy);
+ if (rc) {
+ error (0, rc, _("failed to get policy for %s/%s"),
+ ms->bucket,ms->key);
+ return;
+ }
}
if (!policy) {
DPRINTF(" inheriting policy from %s\n",ms->bucket);
- rc = meta_get_value(ms->bucket,
- "_default", "_policy", &policy);
+ int rc = meta_get_value(ms->bucket, "_default",
+ "_policy", &policy);
+ if (rc) {
+ error (0, rc, _("failed to get default policy"));
+ return;
+ }
}
if (policy) {
13 years
[iwhd] don't ignore failing strdup
by Jim Meyering
commit 89bed8fd8218cbb7f5c259de3c072df2c1a454f8
Author: Jim Meyering <meyering(a)redhat.com>
Date: Wed Mar 30 20:26:31 2011 +0200
don't ignore failing strdup
* meta.cpp (RepoMeta::GetValue): Diagnose a failing strdup
rather than claiming "success" and providing a NULL result.
meta.cpp | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
---
diff --git a/meta.cpp b/meta.cpp
index 110a7c6..aa533c2 100644
--- a/meta.cpp
+++ b/meta.cpp
@@ -375,6 +375,9 @@ RepoMeta::GetValue (const char *bucket, const char *key, const char *mkey,
}
*mvalue = strdup(data);
+ if (*mvalue == NULL)
+ return ENOMEM;
+
return 0;
}
13 years
[iwhd] tests: make test port-selection safe and maintainable
by Jim Meyering
commit ce4ed6e9fb98e6ea77fd01ce11520ba758aab302
Author: Jim Meyering <meyering(a)redhat.com>
Date: Mon Mar 28 22:34:17 2011 +0200
tests: make test port-selection safe and maintainable
Before, we had to ensure that each new test used no port (one
for mongod and at least one for iwhd) that conflicted with any
other test. Otherwise, a parallel "make check" would fail.
It was too easy to forget about that rule. Now, port numbers
are chosen automatically.
* t/Makefile.am (lock_dir): New var/tmpdir.
(CONFIG_CLEAN_FILES): Remove it.
(prereq): New rule, to be run before all tests.
(TESTS_ENVIRONMENT): Propagate $lock_dir to test scripts.
* .gitignore: Ignore the temporary directory.
* t/init.cfg (get_port): New function.
* t/basic: Use it, rather than hard-coding port numbers.
* t/provider: Likewise.
* t/replication: Likewise.
Also replace hard-coded 9093 in expected output with $d_port.
.gitignore | 1 +
t/Makefile.am | 9 +++++++++
t/basic | 5 +++--
t/init.cfg | 21 +++++++++++++++++++++
t/provider | 6 ++++--
t/replication | 10 ++++++----
6 files changed, 44 insertions(+), 8 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index fb871d5..297315d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@
/qparser.h
/stamp-h1
/t/*.log
+/t/lock-dir
ChangeLog
ID
INSTALL
diff --git a/t/Makefile.am b/t/Makefile.am
index bf95ff4..6ffdfc8 100644
--- a/t/Makefile.am
+++ b/t/Makefile.am
@@ -21,6 +21,14 @@ TESTS = \
replication \
auto
+lock_dir = $(abs_builddir)/lock-dir
+CONFIG_CLEAN_FILES = lock-dir
+.PHONY: prereq
+prereq:
+ $(AM_V_GEN)rm -rf "$(lock_dir)" && mkdir "$(lock_dir)"
+
+$(TEST_LOGS): prereq
+
EXTRA_DIST = \
$(TESTS) \
init.cfg \
@@ -52,6 +60,7 @@ TESTS_ENVIRONMENT = \
abs_top_srcdir='$(abs_top_srcdir)' \
abs_srcdir='$(abs_srcdir)' \
built_programs='$(built_programs)' \
+ lock_dir='$(lock_dir)' \
srcdir='$(srcdir)' \
top_srcdir='$(top_srcdir)' \
CC='$(CC)' \
diff --git a/t/basic b/t/basic
index fd4bca9..7dcf10b 100644
--- a/t/basic
+++ b/t/basic
@@ -14,7 +14,8 @@
mkdir FS mongod iwhd || framework_failure_ mkdir failed
-m_port=$(expr $mongo_base_port + 0)
+m_port=$(get_port $mongo_base_port $lock_dir/m-) \
+ || fail_ "failed to get mongodb port"
mongod --port $m_port --pidfilepath mongod/pid --dbpath mongod > mongod.log 2>&1 &
mongo_pid=$!
@@ -24,7 +25,7 @@ cleanup_() { kill -9 $mongo_pid; }
wait_for .1 50 'mongo localhost:$m_port < /dev/null' \
|| framework_failure_ mongod failed to start
-port=9091
+port=$(get_port 9095 $lock_dir/i-) || fail_ "failed to get iwhd port"
bucket=http://localhost:$port/b1
cat <<EOF > root.xml || framework_failure_
diff --git a/t/init.cfg b/t/init.cfg
index af9356e..858bd38 100644
--- a/t/init.cfg
+++ b/t/init.cfg
@@ -129,3 +129,24 @@ emit_bucket_list()
printf ']\n'
fi
}
+
+# Each test script uses its own mongod instance as well as at least one
+# iwhd process. Each of those needs a unique port number, so that the
+# tests may be run in parallel without interfering with one another.
+# Call this function to get each port number.
+# Inputs:
+# starting_port: start with this port number
+# dir_prefix (we mkdir $dir_prefix$i for some $i >= $starting_port)
+# Return the first PID >= $starting_port for which mkdir $dir_prefix$i succeeds
+get_port()
+{
+ local starting_port=$1
+ local dir_prefix=$2
+ local i=0
+ while :; do
+ local p=$((starting_port + i))
+ mkdir $dir_prefix$p 2>/dev/null \
+ && { echo $p; echo $$ > $dir_prefix$p/pid; break; }
+ i=$((i+1))
+ done
+}
diff --git a/t/provider b/t/provider
index 82b8e5f..c858be2 100644
--- a/t/provider
+++ b/t/provider
@@ -5,7 +5,8 @@
mkdir FS mongod iwhd || framework_failure_ mkdir failed
-m_port=$(expr $mongo_base_port + 2)
+m_port=$(get_port $mongo_base_port $lock_dir/m-) \
+ || fail_ "failed to get mongodb port"
mongod --port $m_port --pidfilepath mongod/pid --dbpath mongod > mongod.log 2>&1 &
mongo_pid=$!
@@ -15,7 +16,8 @@ cleanup_() { kill -9 $mongo_pid; }
wait_for .1 50 'mongo localhost:$m_port < /dev/null' \
|| framework_failure_ mongod failed to start
-port=9095
+port=$(get_port 9095 $lock_dir/i-) || fail_ "failed to get iwhd port"
+
ulimit -c unlimited
printf '[{"path": "FS", "type": "fs", "name": "primary"}]\n' \
diff --git a/t/replication b/t/replication
index 803fe2c..30d761c 100644
--- a/t/replication
+++ b/t/replication
@@ -12,7 +12,8 @@
mkdir mongod fs_upstream fs_downstream || framework_failure_ mkdir failed
-m_port=$(expr $mongo_base_port + 1)
+m_port=$(get_port $mongo_base_port $lock_dir/m-) \
+ || fail_ "failed to get mongodb port"
mongod --port $m_port --pidfilepath mongod/pid --dbpath mongod > mongod.log 2>&1 &
mongo_pid=$!
@@ -22,15 +23,17 @@ cleanup_() { kill -9 $mongo_pid; }
wait_for .1 120 'mongo localhost:$m_port < /dev/null' \
|| framework_failure_ mongod failed to start
+port=$(get_port 9095 $lock_dir/i-) || fail_ "failed to get iwhd port"
+d_port=$(get_port 9095 $lock_dir/i-) || fail_ "failed to get 2nd iwhd port"
+
cat > iwhd_u.cfg << EOF
[
{ "name":"upstream", "type":"fs", "path":"fs_upstream" },
- { "name":"downstream", "type":"http", "host":"localhost", "port": 9093,
+ { "name":"downstream", "type":"http", "host":"localhost", "port": $d_port,
"color": "blue" }
]
EOF
-port=9092
iwhd -v -p $port -c iwhd_u.cfg -d localhost:$m_port &
iwhd_pid=$!
wait_for .1 50 "curl http://localhost:$port" \
@@ -43,7 +46,6 @@ cat > iwhd_d.cfg << EOF
]
EOF
-d_port=9093
iwhd -v -p $d_port -c iwhd_d.cfg -d localhost:$m_port -m localhost:$port &
iwhd_d_pid=$!
wait_for .1 50 "curl http://localhost:$d_port" \
13 years
[iwhd] tests: enable another synatx-check test
by Jim Meyering
commit fe65b06db35fcbdfed8293b8d0fa427e0b6ee36d
Author: Jim Meyering <meyering(a)redhat.com>
Date: Wed Mar 23 20:44:57 2011 +0100
tests: enable another synatx-check test
* cfg.mk (skip_low_priority): Rather than disabling the bindtextdomain
test, simply tell it to exempt dc-rhev-image.c.
cfg.mk | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
---
diff --git a/cfg.mk b/cfg.mk
index 0089d61..5359a59 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -19,7 +19,6 @@ manual_title = GNU Grep: Print lines matching a pattern
# Fixing these can wait.
skip_low_priority = \
- sc_bindtextdomain \
sc_texinfo_acronym \
sc_prohibit_tab_based_indentation \
sc_prohibit_strcmp \
@@ -63,6 +62,7 @@ odt = ^doc/image_repo\.odt$
exclude_file_name_regexp--sc_trailing_blank = $(odt)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = $(odt)
exclude_file_name_regexp--sc_prohibit_test_double_equal = ^t/parse-test$$
+exclude_file_name_regexp--sc_bindtextdomain = ^dc-rhev-image\.c$$
update-copyright-env = \
UPDATE_COPYRIGHT_USE_INTERVALS=1 \
13 years, 1 month
[iwhd] dc-rhev-image: always detect/diagnose write failure
by Jim Meyering
commit 082f1560be7a4a1b1db78dadbba6886018206f35
Author: Jim Meyering <meyering(a)redhat.com>
Date: Wed Mar 23 19:52:11 2011 +0100
dc-rhev-image: always detect/diagnose write failure
* dc-rhev-image.c: Include "closeout.h" and "progname.h".
(main): Call set_program_name and arrange for close_stdout to
be called on exit.
dc-rhev-image.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
---
diff --git a/dc-rhev-image.c b/dc-rhev-image.c
index aff22fa..e944343 100644
--- a/dc-rhev-image.c
+++ b/dc-rhev-image.c
@@ -45,7 +45,9 @@
#include "base64.h"
#include "close-stream.h"
+#include "closeout.h"
#include "copy-file.h"
+#include "progname.h"
/*
* Note that we almost never prefix with TAG due to compatibility with EC2.
@@ -1482,6 +1484,9 @@ int main(int argc, char **argv, char **envp)
struct stor_dom *sd;
char uuidbuf[37];
+ set_program_name (TAG);
+ atexit (close_stdout);
+
env_p = envp;
if (argc == 1) {
13 years, 1 month