diff options
author | William Johansson <radar@radhuset.org> | 2015-04-24 20:22:51 +0200 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2015-06-10 15:43:11 -0400 |
commit | 1f21fbe26dfbc982492c8b7b90f3758a910f113d (patch) | |
tree | 80183a72bf5cd18387a89ddd368e762841c5f930 | |
parent | 87bb4978dade6117f69799f435dad741eb741655 (diff) |
Initial FreeBSD support with pkgng plugin
Add a basic pkgng plugin as a preparation to integrate etckeeper on
FreeBSD. Currently not enabled to build automatically.
To use on FreeBSD, install etckeeper manually and install the plugin
with:
$ cd pkgng
$ make
$ make install
and add this line to /usr/local/etc/pkg.conf:
PLUGINS [ etckeeper ]
-rwxr-xr-x | list-installed.d/50list-installed | 2 | ||||
-rw-r--r-- | pkgng/Makefile | 17 | ||||
-rw-r--r-- | pkgng/etckeeper.c | 132 |
3 files changed, 151 insertions, 0 deletions
diff --git a/list-installed.d/50list-installed b/list-installed.d/50list-installed index 2ac569a..4a8ce70 100755 --- a/list-installed.d/50list-installed +++ b/list-installed.d/50list-installed @@ -17,5 +17,7 @@ else rpm -qa --qf "%|epoch?{%{epoch}}:{0}|:%{name}-%{version}-%{release}.%{arch}\n" | sort elif [ "$LOWLEVEL_PACKAGE_MANAGER" = pacman ]; then pacman -Q + elif [ "$LOWLEVEL_PACKAGE_MANAGER" = pkgng ]; then + pkg info -E "*" fi fi diff --git a/pkgng/Makefile b/pkgng/Makefile new file mode 100644 index 0000000..92d3c1d --- /dev/null +++ b/pkgng/Makefile @@ -0,0 +1,17 @@ +.include <bsd.own.mk> + +PREFIX?= /usr/local +LIBDIR= ${PREFIX}/lib/pkg/ +SHLIB_DIR?= ${LIBDIR}/ +SHLIB_NAME?= ${PLUGIN_NAME}.so + +PLUGIN_NAME= etckeeper +SRCS= etckeeper.c + +PKGFLAGS!= pkgconf --cflags pkg +CFLAGS+= ${PKGFLAGS} + +beforeinstall: + ${INSTALL} -d ${LIBDIR} + +.include <bsd.lib.mk> diff --git a/pkgng/etckeeper.c b/pkgng/etckeeper.c new file mode 100644 index 0000000..6c54388 --- /dev/null +++ b/pkgng/etckeeper.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015 William Johansson <radar@radhuset.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Based upon the pkg plugin zfssnap: + * Copyright (c) 2012 Marin Atanasov Nikolov <dnaeon@gmail.com> + */ + +#include <stdio.h> +#include <sys/wait.h> +#include <err.h> +#include <errno.h> +#include <spawn.h> + +#include <pkg.h> +#define PLUGIN_NAME "etckeeper" +/* TODO: make configuration param? */ +#define ETCKEEPER_PATH "/usr/local/bin/etckeeper" + +extern char **environ; + +struct pkg_plugin *self; + +static int pre_install_hook(void *data, struct pkgdb *db); +static int post_install_hook(void *data, struct pkgdb *db); + +int +pkg_plugin_init(struct pkg_plugin *p) +{ + self = p; + + pkg_plugin_set(p, PKG_PLUGIN_NAME, PLUGIN_NAME); + pkg_plugin_set(p, PKG_PLUGIN_DESC, "etckeeper plugin"); + pkg_plugin_set(p, PKG_PLUGIN_VERSION, "1.0.0"); + + /* NOTE: upgrade/deinstall is regarded as install */ + + if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_INSTALL, &pre_install_hook) != EPKG_OK) { + pkg_plugin_error(self, "failed to hook into the library"); + return (EPKG_FATAL); + } + + if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_INSTALL, &post_install_hook) != EPKG_OK) { + pkg_plugin_error(self, "failed to hook into the library"); + return (EPKG_FATAL); + } + + if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_DEINSTALL, &pre_install_hook) != EPKG_OK) { + pkg_plugin_error(self, "failed to hook into the library"); + return (EPKG_FATAL); + } + + if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_DEINSTALL, &post_install_hook) != EPKG_OK) { + pkg_plugin_error(self, "failed to hook into the library"); + return (EPKG_FATAL); + } + + if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_UPGRADE, &pre_install_hook) != EPKG_OK) { + pkg_plugin_error(self, "failed to hook into the library"); + return (EPKG_FATAL); + } + + if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_UPGRADE, &post_install_hook) != EPKG_OK) { + pkg_plugin_error(self, "failed to hook into the library"); + return (EPKG_FATAL); + } + + return (EPKG_OK); +} + +static int +call_etckeeper(char *arg) +{ + int error, pstat; + pid_t pid; + char *argv[] = { + "etckeeper", + arg, + NULL, + }; + + if ((error = posix_spawn(&pid, ETCKEEPER_PATH, NULL, NULL, + __DECONST(char **, argv), environ)) != 0) { + errno = error; + pkg_plugin_errno(self, "Failed to spawn process", arg); + return (EPKG_FATAL); + } + while (waitpid(pid, &pstat, 0) == -1) { + if (errno != EINTR) + return (EPKG_FATAL); + } + + if ((error = WEXITSTATUS(pstat)) != 0) { + pkg_plugin_error(self, "etckeeper failed with exit code %d", error); + return (EPKG_FATAL); + } + + return (EPKG_OK); +} + +static int +pre_install_hook(void *data, struct pkgdb *db) +{ + return call_etckeeper("pre-install"); +} + +static int +post_install_hook(void *data, struct pkgdb *db) +{ + return call_etckeeper("post-install"); +} |