Fix bug causing scripts to be run at the wrong time 0.5.2
authorJ. Ali Harlow <ali@juiblex.co.uk>
Wed Feb 01 12:49:13 2012 +0000 (2012-02-01)
changeset 412810d9ba06afd
parent 411 b1dcf22c0418
child 413 4c0b7471e73e
child 414 404c18183801
Fix bug causing scripts to be run at the wrong time
src/main.c
     1.1 --- a/src/main.c	Wed Feb 01 12:47:50 2012 +0000
     1.2 +++ b/src/main.c	Wed Feb 01 12:49:13 2012 +0000
     1.3 @@ -48,12 +48,18 @@
     1.4  
     1.5  #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     1.6  
     1.7 +enum update_pass_type {
     1.8 +    UPDATE_PASS_PRE_REMOVE,
     1.9 +    UPDATE_PASS_MAIN,
    1.10 +    UPDATE_PASS_POST_INSTALL,
    1.11 +};
    1.12 +
    1.13  static int
    1.14  update_packages(struct razor_transaction *trans,
    1.15  		struct razor_install_iterator *ii, struct razor_set *system,
    1.16  		struct razor_set *next, struct razor_atomic *atomic,
    1.17  		struct razor_relocations *relocations,
    1.18 -		enum razor_stage_type stage);
    1.19 +		enum update_pass_type stage);
    1.20  
    1.21  static struct razor_package_iterator *
    1.22  create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
    1.23 @@ -657,22 +663,24 @@
    1.24  
    1.25  	next = razor_transaction_commit(trans);
    1.26  	ii = razor_set_create_install_iterator(system, next);
    1.27 -	update_packages(trans, ii, system, next, atomic, NULL,
    1.28 -			RAZOR_STAGE_SCRIPTS_PRE);
    1.29 -	update_packages(trans, ii, system, next, atomic, NULL,
    1.30 -			RAZOR_STAGE_FILES);
    1.31 +	retval = update_packages(trans, ii, system, next, atomic, NULL,
    1.32 +				 UPDATE_PASS_PRE_REMOVE);
    1.33 +	if (retval)
    1.34 +		fprintf(stderr, "Remove aborted\n");
    1.35 +	else {
    1.36 +		update_packages(trans, ii, system, next, atomic, NULL,
    1.37 +				UPDATE_PASS_MAIN);
    1.38  
    1.39 -	razor_root_update(root, next);
    1.40 +		razor_root_update(root, next);
    1.41  
    1.42 -	(void)razor_root_commit(root);
    1.43 -	retval = razor_atomic_commit(atomic);
    1.44 -	if (retval)
    1.45 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
    1.46 -	else
    1.47 -		update_packages(trans, ii, system, next, atomic, NULL,
    1.48 -				RAZOR_STAGE_SCRIPTS_POST);
    1.49 +		(void)razor_root_commit(root);
    1.50 +		retval = razor_atomic_commit(atomic);
    1.51 +		if (retval)
    1.52 +			fprintf(stderr, "%s\n",
    1.53 +				razor_atomic_get_error_msg(atomic));
    1.54 +	}
    1.55 +
    1.56  	razor_install_iterator_destroy(ii);
    1.57 -
    1.58  	razor_transaction_destroy(trans);
    1.59  	razor_atomic_destroy(atomic);
    1.60  	razor_set_unref(system);
    1.61 @@ -980,28 +988,80 @@
    1.62  	return retval;
    1.63  }
    1.64  
    1.65 +/*
    1.66 + * In the most general case, there should be three passes:
    1.67 + *
    1.68 + * 1) For each package to be removed, run %preun
    1.69 + *
    1.70 + * 2) For each package:
    1.71 + *	If the package is to be installed, run %pre
    1.72 + *	Update the files on disk
    1.73 + *	If the package has been removed, run %postun
    1.74 + *
    1.75 + * 3) For each packge installed, run %post
    1.76 + *
    1.77 + * This guarantees that:
    1.78 + *   a)	Save where dependency loops make it impossible, at the time
    1.79 + *	%pre is run, all required packages are installed (although
    1.80 + *	their %post script may not have been run). We should support
    1.81 + *	Requires(%pre) to allow packagers to describe their requirements
    1.82 + *	more accurately and avoid unnecessary dependency loops.
    1.83 + *   b)	At the time %preun is run, all required packages are installed.
    1.84 + *	Supporting Requires(%preun) would make this more complicated
    1.85 + *	since we might have to install a package in order to remove
    1.86 + *	another one. For now, treating Requires(%preun) as Requires
    1.87 + *	seems more sensible.
    1.88 + *   c)	At the time %post is run, all required packages are installed.
    1.89 + *	Supporting Requires(%post) would allow us to remove a package
    1.90 + *	that was only needed to install another, but there seems no
    1.91 + *	obvious advantage.
    1.92 + *   d)	Save where dependency loops make it impossible, at the time
    1.93 + *	%postun is run, all required packages are installed. Again,
    1.94 + *	we should support Requires(%postun) to avoid unnecessary
    1.95 + *	dependency loops.
    1.96 + *
    1.97 + * Notes:
    1.98 + *	rpm treats %pre and %preun script failures as fatal errors
    1.99 + *	and %post and %postun failures as warnings.
   1.100 + */
   1.101  static int
   1.102  update_packages(struct razor_transaction *trans,
   1.103  		struct razor_install_iterator *ii, struct razor_set *system,
   1.104  		struct razor_set *next, struct razor_atomic *atomic,
   1.105  		struct razor_relocations *relocations,
   1.106 -		enum razor_stage_type stage)
   1.107 +		enum update_pass_type pass)
   1.108  {
   1.109  	struct razor_package *package;
   1.110  	enum razor_install_action action;
   1.111  	int retval = 0, count;
   1.112 +	enum razor_stage_type remove_stage, add_stage;
   1.113 +
   1.114 +	switch (pass) {
   1.115 +	case UPDATE_PASS_PRE_REMOVE:
   1.116 +		add_stage = 0;
   1.117 +		remove_stage = RAZOR_STAGE_SCRIPTS_PRE;
   1.118 +		break;
   1.119 +	case UPDATE_PASS_MAIN:
   1.120 +		add_stage = RAZOR_STAGE_SCRIPTS_PRE | RAZOR_STAGE_FILES;
   1.121 +		remove_stage = RAZOR_STAGE_FILES | RAZOR_STAGE_SCRIPTS_POST;
   1.122 +		break;
   1.123 +	case UPDATE_PASS_POST_INSTALL:
   1.124 +		add_stage = RAZOR_STAGE_SCRIPTS_POST;
   1.125 +		remove_stage = 0;
   1.126 +		break;
   1.127 +	}
   1.128  
   1.129  	razor_install_iterator_rewind(ii);
   1.130  
   1.131 -	while (!retval && razor_install_iterator_next(ii, &package,
   1.132 -						      &action, &count)) {
   1.133 -		if (action == RAZOR_INSTALL_ACTION_ADD)
   1.134 +	while (!retval && razor_install_iterator_next(ii, &package, &action,
   1.135 +						      &count)) {
   1.136 +		if (action == RAZOR_INSTALL_ACTION_ADD && add_stage)
   1.137  			retval = install_package(trans, next, atomic, package,
   1.138 -						 relocations, count, stage);
   1.139 -		else if (action == RAZOR_INSTALL_ACTION_REMOVE)
   1.140 +						 relocations, count, add_stage);
   1.141 +		else if (action == RAZOR_INSTALL_ACTION_REMOVE && remove_stage)
   1.142  			retval = razor_package_remove(system, next, atomic,
   1.143  						      package, install_root,
   1.144 -						      count, stage);
   1.145 +						      count, remove_stage);
   1.146  	}
   1.147  
   1.148  	return retval;
   1.149 @@ -1139,22 +1199,29 @@
   1.150  
   1.151  	ii = razor_set_create_install_iterator(system, next);
   1.152  
   1.153 -	update_packages(trans, ii, system, next, atomic, relocations,
   1.154 -			RAZOR_STAGE_SCRIPTS_PRE);
   1.155 -	update_packages(trans, ii, system, next, atomic, relocations,
   1.156 -			RAZOR_STAGE_FILES);
   1.157 +	retval = update_packages(trans, ii, system, next, atomic, relocations,
   1.158 +				 UPDATE_PASS_PRE_REMOVE);
   1.159 +	if (retval)
   1.160 +		fprintf(stderr, "%s aborted\n",
   1.161 +			do_update ? "Update" : "Install");
   1.162 +	else {
   1.163 +		update_packages(trans, ii, system, next, atomic, relocations,
   1.164 +				UPDATE_PASS_MAIN);
   1.165  
   1.166 -	razor_root_update(root, next);
   1.167 +		razor_root_update(root, next);
   1.168  
   1.169 -	razor_set_unref(upstream);
   1.170 +		razor_set_unref(upstream);
   1.171  
   1.172 -	(void)razor_root_commit(root);
   1.173 -	retval = razor_atomic_commit(atomic);
   1.174 -	if (retval)
   1.175 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   1.176 -	else
   1.177 -		update_packages(trans, ii, system, next, atomic, relocations,
   1.178 -				RAZOR_STAGE_SCRIPTS_POST);
   1.179 +		(void)razor_root_commit(root);
   1.180 +		retval = razor_atomic_commit(atomic);
   1.181 +		if (retval)
   1.182 +			fprintf(stderr, "%s\n",
   1.183 +				razor_atomic_get_error_msg(atomic));
   1.184 +		else
   1.185 +			(void)update_packages(trans, ii, system, next, atomic,
   1.186 +					      relocations,
   1.187 +					      UPDATE_PASS_POST_INSTALL);
   1.188 +	}
   1.189  
   1.190  	razor_transaction_destroy(trans);
   1.191  	if (relocations)