Commit 3ce74686 by Serge Hallyn

lxc_create: prepend pretty header to config file (v2)

Define a sha1sum_file() function in utils.c. Use that in lxcapi_create to write out the sha1sum of the template being used. If libgnutls is not found, then the template sha1sum simply won't be printed into the container config. This patch also trivially fixes some cases where SYSERROR is used after a fclose (masking errno) and missing consts in mkdir_p. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com>
parent 868a70af
......@@ -105,6 +105,8 @@ if test "$enable_apparmor" = "check" ; then
fi
AM_CONDITIONAL([ENABLE_APPARMOR], [test "x$enable_apparmor" = "xyes"])
AC_CHECK_LIB([gnutls], [gnutls_hash_fast])
AM_COND_IF([ENABLE_APPARMOR],
[AC_CHECK_HEADER([sys/apparmor.h],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
......
......@@ -870,6 +870,107 @@ static bool create_run_template(struct lxc_container *c, char *tpath, bool quiet
return true;
}
bool prepend_lxc_header(char *path, const char *t, char *const argv[])
{
size_t flen;
char *contents, *tpath;
int i, ret;
FILE *f;
unsigned char md_value[SHA_DIGEST_LENGTH];
bool have_tpath = false;
if ((f = fopen(path, "r")) == NULL) {
SYSERROR("Opening old config");
return false;
}
if (fseek(f, 0, SEEK_END) < 0) {
SYSERROR("Seeking to end of old config file");
fclose(f);
return false;
}
if ((flen = ftell(f)) < 0) {
SYSERROR("telling size of old config");
fclose(f);
return false;
}
if (fseek(f, 0, SEEK_SET) < 0) {
SYSERROR("rewinding old config");
fclose(f);
return false;
}
if ((contents = malloc(flen + 1)) == NULL) {
SYSERROR("out of memory");
fclose(f);
return false;
}
if (fread(contents, 1, flen, f) != flen) {
SYSERROR("Reading old config");
free(contents);
fclose(f);
return false;
}
contents[flen] = '\0';
if (fclose(f) < 0) {
SYSERROR("closing old config");
free(contents);
return false;
}
if ((tpath = get_template_path(t)) < 0) {
ERROR("bad template: %s\n", t);
free(contents);
return false;
}
#if HAVE_LIBGNUTLS
if (tpath) {
have_tpath = true;
ret = sha1sum_file(tpath, md_value);
if (ret < 0) {
ERROR("Error getting sha1sum of %s", tpath);
free(contents);
return false;
}
free(tpath);
}
#endif
if ((f = fopen(path, "w")) == NULL) {
SYSERROR("reopening config for writing");
free(contents);
return false;
}
fprintf(f, "# Template used to create this container: %s\n", t);
if (argv) {
fprintf(f, "# Parameters passed to the template:");
while (*argv) {
fprintf(f, " %s", *argv);
argv++;
}
fprintf(f, "\n");
}
#if HAVE_LIBGNUTLS
if (have_tpath) {
fprintf(f, "# Template script checksum (SHA-1): ");
for (i=0; i<SHA_DIGEST_LENGTH; i++)
fprintf(f, "%02x", md_value[i]);
fprintf(f, "\n");
}
#endif
if (fwrite(contents, 1, flen, f) != flen) {
SYSERROR("Writing original contents");
free(contents);
fclose(f);
return false;
}
free(contents);
if (fclose(f) < 0) {
SYSERROR("Closing config file after write");
return false;
}
return true;
}
static bool lxcapi_destroy(struct lxc_container *c);
/*
* lxcapi_create:
......@@ -967,6 +1068,11 @@ static bool lxcapi_create(struct lxc_container *c, const char *t,
if (c->lxc_conf)
lxc_conf_free(c->lxc_conf);
c->lxc_conf = NULL;
if (!prepend_lxc_header(c->configfile, tpath, argv)) {
ERROR("Error prepending header to configuration file");
goto out_unlock;
}
bret = load_config_locked(c, c->configfile);
out_unlock:
......@@ -1623,13 +1729,13 @@ static int update_name_and_paths(const char *path, struct lxc_container *oldc,
}
flen = ftell(f);
if (flen < 0) {
fclose(f);
SYSERROR("telling size of old config");
fclose(f);
return -1;
}
if (fseek(f, 0, SEEK_SET) < 0) {
fclose(f);
SYSERROR("rewinding old config");
fclose(f);
return -1;
}
contents = malloc(flen+1);
......@@ -1639,15 +1745,15 @@ static int update_name_and_paths(const char *path, struct lxc_container *oldc,
return -1;
}
if (fread(contents, 1, flen, f) != flen) {
SYSERROR("reading old config");
free(contents);
fclose(f);
SYSERROR("reading old config");
return -1;
}
contents[flen] = '\0';
if (fclose(f) < 0) {
free(contents);
SYSERROR("closing old config");
free(contents);
return -1;
}
......
......@@ -37,6 +37,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include "utils.h"
#include "log.h"
lxc_log_define(lxc_utils, lxc);
......@@ -173,10 +174,10 @@ extern int get_u16(unsigned short *val, const char *arg, int base)
return 0;
}
extern int mkdir_p(char *dir, mode_t mode)
extern int mkdir_p(const char *dir, mode_t mode)
{
char *tmp = dir;
char *orig = dir;
const char *tmp = dir;
const char *orig = dir;
char *makeme;
do {
......@@ -392,3 +393,57 @@ int lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected
}
return ret;
}
#if HAVE_LIBGNUTLS
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
int sha1sum_file(char *fnam, unsigned char *digest)
{
char *buf;
int ret;
FILE *f;
long flen;
if (!fnam)
return -1;
if ((f = fopen(fnam, "r")) < 0) {
SYSERROR("Error opening template");
return -1;
}
if (fseek(f, 0, SEEK_END) < 0) {
SYSERROR("Error seeking to end of template");
fclose(f);
return -1;
}
if ((flen = ftell(f)) < 0) {
SYSERROR("Error telling size of template");
fclose(f);
return -1;
}
if (fseek(f, 0, SEEK_SET) < 0) {
SYSERROR("Error seeking to start of template");
fclose(f);
return -1;
}
if ((buf = malloc(flen+1)) == NULL) {
SYSERROR("Out of memory");
fclose(f);
return -1;
}
if (fread(buf, 1, flen, f) != flen) {
SYSERROR("Failure reading template");
free(buf);
fclose(f);
return -1;
}
if (fclose(f) < 0) {
SYSERROR("Failre closing template");
free(buf);
return -1;
}
buf[flen] = '\0';
ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, buf, flen, (void *)digest);
free(buf);
return ret;
}
#endif
......@@ -176,5 +176,9 @@ extern int lxc_wait_for_pid_status(pid_t pid);
extern int lxc_write_nointr(int fd, const void* buf, size_t count);
extern int lxc_read_nointr(int fd, void* buf, size_t count);
extern int lxc_read_nointr_expect(int fd, void* buf, size_t count, const void* expected_buf);
#if HAVE_LIBGNUTLS
#define SHA_DIGEST_LENGTH 20
extern int sha1sum_file(char *fnam, unsigned char *md_value);
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment