[pacman-dev] [PATCH] Add support for user defined per package post install actions

Mårten Olsson marten.olsson at purplescout.se
Sun Feb 1 05:44:06 EST 2009


Hi!

Oh, that was a neat idea... 
Which I have unfortunetly missed when searching in the archives. :-)

I think it should be possible to have it triggered by packages as well,
something like this:

[kernel-install]
Package = kernel26
Run = rebuildoutofkerneltreedrivers

(I recognice the ridiculous name of the Run-argument and that this probably 
wouldn't work as a reboot probably is necessery first but just something 
as an example. (and it was this need that triggered my own idea).)

Of course it is possible to have it triggered by file in this case as well,
just list files in this package and choose one of them, but it is still an
unecessery extra step (even if it is a small one).

BR,
Mårten

----- Original Message -----
From: "Allan McRae" <allan at archlinux.org>
To: "Discussion list for pacman development" <pacman-dev at archlinux.org>
Sent: Sunday, February 1, 2009 2:59:10 AM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna
Subject: Re: [pacman-dev] [PATCH] Add support for user defined per package post install actions

Hi,

This seems similar to the hooks mechanism the we have been discussing 
but less general.  Have a look at 
http://wiki.archlinux.org/index.php/User:Allan/Pacman_Hooks for more 
information.  So in short, I like the idea but would want a more general 
approach taken.

Allan

Mårten Olsson wrote:
> Hi all!
>
> Wasn't sure if I could include additonal text in "patch-mail".
> So I hope it is ok to send an additonal mail with extra info:
>
> At some places the code needs cleanup which I will do if the concept shown
> is accepted (didn't want to take to much time on that if the concept is disliked
> and never will be accpeted for that reason).
> I want to fix the code-duplication issue (one function) and make the parsign so one
> can have arguments with spaces inside " ".
>
> I wasn't sure if this functionality can be considered dangerous because it will run a script
> with full access to the system, but I guess the same problem could show up if you make "bad"
> packages with an install script.  
>
> BR,
> Mårten
>
> ----- Original Message -----
> From: "Mårten Olsson" <marten.olsson at purplescout.se>
> To: pacman-dev at archlinux.org
> Sent: Sunday, February 1, 2009 2:36:46 AM GMT +01:00 Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna
> Subject: [pacman-dev] [PATCH] Add support for user defined per package post install actions
>
> This adds suport for user to add per package post install
> actions, somewhat similar to post-install scripts in packages
> but controlled by local user and not part of package/not done
> by package maintainer.
> The actions is performed by "system" call and can't contain
> spaces (not even when inside ").
> Syntax in logfile is
> PostInstallAction = <packagename>:<action>
> Functionality added inside libalpm, add support for configuring
> in pacman.
>
> Signed-off-by: Mårten Olsson <marten.olsson_at_purplescout.se>
> ---
>  lib/libalpm/add.c    |   43 +++++++++++++++++++++++++++++++++
>  lib/libalpm/alpm.h   |    3 ++
>  lib/libalpm/handle.c |   65 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/libalpm/handle.h |    6 ++++
>  src/pacman/pacman.c  |   20 +++++++++++++++
>  5 files changed, 137 insertions(+), 0 deletions(-)
>
> diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
> index 6eb2085..1cd6e28 100644
> --- a/lib/libalpm/add.c
> +++ b/lib/libalpm/add.c
> @@ -632,6 +632,46 @@ static int extract_single_file(struct archive *archive,
>  	return(errors);
>  }
>  
> +static int postinstallcompare(const void *postinstalldata, const void *pkgname)
> +{
> +	const postinstallaction_t *postinstallaction=postinstalldata;
> +
> +	if( (pkgname != NULL) && (postinstallaction->pkgname != NULL) && (strcmp(postinstallaction->pkgname, pkgname) == 0)) {
> +		return(0);
> +	}
> +
> +	return(1);
> +}
> +
> +/** Test if a package has a postinstallaction associated with it and executes the action.
> + *
> + * Checks if the package has a postinstallaction associated with it
> + * and if so executes the action by the system call
> + *
> + * @param pkg the package to test
> + *
> + * @return 0 if no action found or if the associated action completed succesfully, 1 otherwise
> + */
> +static int check_run_postinstallaction(pmpkg_t *pkg)
> +{
> +	postinstallaction_t *postinstallaction = NULL;
> +
> +	_alpm_log(PM_LOG_DEBUG, "PostInstallAction: finding PostInstallAction for package: %s\n", alpm_pkg_get_name(pkg));
> +
> +	postinstallaction=alpm_list_find(handle->postinstallactions, alpm_pkg_get_name(pkg), postinstallcompare);
> +
> +	if( postinstallaction != NULL) {
> +		_alpm_log(PM_LOG_DEBUG, "PostInstallAction: package: %s action: %s \n", postinstallaction->pkgname, postinstallaction->action);
> +
> +		/* should this be more like the install-scriptlet code */
> +		if( system(postinstallaction->action) != 0) {
> +			return(1);
> +		}
> +	}
> +
> +	return(0);
> +}
> +
>  static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
>  		pmtrans_t *trans, pmdb_t *db)
>  {
> @@ -847,6 +887,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count,
>  		}
>  	}
>  
> +	/* check and run postinstall action */
> +	check_run_postinstallaction(newpkg);
> +
>  	if(is_upgrade) {
>  		EVENT(trans, PM_TRANS_EVT_UPGRADE_DONE, newpkg, oldpkg);
>  	} else {
> diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
> index 7b7ca4e..04ff886 100644
> --- a/lib/libalpm/alpm.h
> +++ b/lib/libalpm/alpm.h
> @@ -122,6 +122,9 @@ void alpm_option_add_noupgrade(const char *pkg);
>  void alpm_option_set_noupgrades(alpm_list_t *noupgrade);
>  int alpm_option_remove_noupgrade(const char *pkg);
>  
> +int alpm_option_add_postinstallaction(const char *pkg, const char *action);
> +int alpm_option_remove_postinstallaction(const char *pkg);
> +
>  alpm_list_t *alpm_option_get_noextracts();
>  void alpm_option_add_noextract(const char *pkg);
>  void alpm_option_set_noextracts(alpm_list_t *noextract);
> diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
> index 813f439..504157d 100644
> --- a/lib/libalpm/handle.c
> +++ b/lib/libalpm/handle.c
> @@ -53,6 +53,23 @@ pmhandle_t *_alpm_handle_new()
>  	return(handle);
>  }
>  
> +void postinstallactionfree(void *data)
> +{
> +	postinstallaction_t *postinstallaction=data;
> +
> +	if(postinstallaction->pkgname != NULL)
> +	{
> +		free(postinstallaction->pkgname);
> +	}
> +
> +	if(postinstallaction->action != NULL)
> +	{
> +		free(postinstallaction->action);
> +	}
> +
> +	free(postinstallaction);
> +}
> +
>  void _alpm_handle_free(pmhandle_t *handle)
>  {
>  	ALPM_LOG_FUNC;
> @@ -84,6 +101,8 @@ void _alpm_handle_free(pmhandle_t *handle)
>  	FREELIST(handle->noextract);
>  	FREELIST(handle->ignorepkg);
>  	FREELIST(handle->ignoregrp);
> +	alpm_list_free_inner(handle->postinstallactions, postinstallactionfree);
> +	alpm_list_free(handle->postinstallactions);
>  	FREE(handle);
>  }
>  
> @@ -453,6 +472,52 @@ int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
>  	return(0);
>  }
>  
> +int SYMEXPORT alpm_option_add_postinstallaction(const char *pkg, const char *action)
> +{
> +	postinstallaction_t *postinstallaction=0;
> +
> +	postinstallaction=malloc(sizeof(postinstallaction_t));
> +
> +	if(postinstallaction == NULL) {
> +		return(1);
> +	}
> +
> +	postinstallaction->pkgname = strdup(pkg);
> +	postinstallaction->action= strdup(action);
> +
> +	handle->postinstallactions = alpm_list_add(handle->postinstallactions, postinstallaction);
> +
> +	return(0);
> +}
> +
> +/* Duplicated here for now, cleanup needed */
> +static int postinstallcompare(const void *postinstalldata, const void *pkgname)
> +{
> +	const postinstallaction_t *postinstallaction=postinstalldata;
> +
> +	if( (pkgname != NULL) && (postinstallaction->pkgname != NULL) && (strcmp(postinstallaction->pkgname, pkgname) == 0)) {
> +		return(0);
> +	}
> +
> +	return(1);
> +}
> +
> +int SYMEXPORT alpm_option_remove_postinstallaction(const char *pkg)
> +{
> +	postinstallaction_t *postinstallaction=0;
> +
> +	handle->postinstallactions=alpm_list_remove(handle->postinstallactions, pkg, postinstallcompare, (void *)&postinstallaction );
> +
> +	if( postinstallaction != NULL) {
> +		free(postinstallaction->pkgname);
> +		free(postinstallaction->action);
> +		free(postinstallaction);
> +		return(1);
> +	}
> +
> +	return(0);
> +}
> +
>  void SYMEXPORT alpm_option_add_noextract(const char *pkg)
>  {
>  	handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
> diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h
> index ad7666d..c53e7f6 100644
> --- a/lib/libalpm/handle.h
> +++ b/lib/libalpm/handle.h
> @@ -28,6 +28,11 @@
>  #include "alpm.h"
>  #include "trans.h"
>  
> +typedef struct _postinstallaction_t {
> +	char *pkgname;
> +	char *action;
> +} postinstallaction_t;
> +
>  typedef struct _pmhandle_t {
>  	/* internal usage */
>  	pmdb_t *db_local;       /* local db pointer */
> @@ -53,6 +58,7 @@ typedef struct _pmhandle_t {
>  	alpm_list_t *noextract;   /* List of files NOT to extract */
>  	alpm_list_t *ignorepkg;   /* List of packages to ignore */
>  	alpm_list_t *ignoregrp;   /* List of groups to ignore */
> +	alpm_list_t *postinstallactions;   /* List of packages to perform actions postinstall */
>  
>  	/* options */
>  	unsigned short usesyslog;    /* Use syslog instead of logfile? */ /* TODO move to frontend */
> diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
> index 59916d6..1f1371d 100644
> --- a/src/pacman/pacman.c
> +++ b/src/pacman/pacman.c
> @@ -549,6 +549,24 @@ static void option_add_syncfirst(const char *name) {
>  	config->syncfirst = alpm_list_add(config->syncfirst, strdup(name));
>  }
>  
> +/* helper for being used with setrepeatingoption, additional parsing done here*/
> +static void option_add_postinstallaction(const char *string) {
> +	char *name = (char *)string;
> +	char *action = 0;
> +
> +	action=strchr(string,':');
> +
> +	if( action != NULL)	{
> +		*action = '\0';
> +		action++;
> +
> +		pm_printf(PM_LOG_DEBUG, "config: Postinstallaction package %s action: %s\n", name, action);
> +
> +		alpm_option_add_postinstallaction(name, action);
> +	}
> +
> +}
> +
>  /** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm
>   * settings. Refactored out of the parseconfig code since all of them did
>   * the exact same thing and duplicated code.
> @@ -710,6 +728,8 @@ static int _parseconfig(const char *file, const char *givensection,
>  						setrepeatingoption(ptr, "HoldPkg", option_add_holdpkg);
>  					} else if(strcmp(key, "SyncFirst") == 0) {
>  						setrepeatingoption(ptr, "SyncFirst", option_add_syncfirst);
> +					} else if(strcmp(key, "PostInstallAction") == 0) {
> +						setrepeatingoption(ptr, "PostInstallAction", option_add_postinstallaction);
>  					} else if(strcmp(key, "DBPath") == 0) {
>  						/* don't overwrite a path specified on the command line */
>  						if(!config->dbpath) {
>   



_______________________________________________
pacman-dev mailing list
pacman-dev at archlinux.org
http://www.archlinux.org/mailman/listinfo/pacman-dev


More information about the pacman-dev mailing list