src/main.c
changeset 419 891991677a7f
parent 412 810d9ba06afd
child 421 408c66ad463d
     1.1 --- a/src/main.c	Wed Feb 01 12:49:13 2012 +0000
     1.2 +++ b/src/main.c	Thu Feb 09 20:45:27 2012 +0000
     1.3 @@ -1,7 +1,7 @@
     1.4  /*
     1.5   * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     1.6   * Copyright (C) 2008  Red Hat, Inc
     1.7 - * Copyright (C) 2009, 2011  J. Ali Harlow <ali@juiblex.co.uk>
     1.8 + * Copyright (C) 2009, 2011-2012  J. Ali Harlow <ali@juiblex.co.uk>
     1.9   *
    1.10   * This program is free software; you can redistribute it and/or modify
    1.11   * it under the terms of the GNU General Public License as published by
    1.12 @@ -48,18 +48,16 @@
    1.13  
    1.14  #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
    1.15  
    1.16 -enum update_pass_type {
    1.17 -    UPDATE_PASS_PRE_REMOVE,
    1.18 -    UPDATE_PASS_MAIN,
    1.19 -    UPDATE_PASS_POST_INSTALL,
    1.20 -};
    1.21 -
    1.22  static int
    1.23  update_packages(struct razor_transaction *trans,
    1.24  		struct razor_install_iterator *ii, struct razor_set *system,
    1.25  		struct razor_set *next, struct razor_atomic *atomic,
    1.26  		struct razor_relocations *relocations,
    1.27 -		enum update_pass_type stage);
    1.28 +		enum razor_stage_type stage);
    1.29 +static int
    1.30 +update_system(const char *install_root, struct razor_relocations *relocations,
    1.31 +	      struct razor_transaction *trans, struct razor_set *system,
    1.32 +	      struct razor_set *next, const char *verb);
    1.33  
    1.34  static struct razor_package_iterator *
    1.35  create_iterator_from_argv(struct razor_set *set, int argc, const char *argv[])
    1.36 @@ -619,24 +617,22 @@
    1.37  static int
    1.38  command_remove(int argc, const char *argv[])
    1.39  {
    1.40 -	struct razor_root *root;
    1.41  	struct razor_set *system, *upstream, *next;
    1.42  	struct razor_transaction *trans;
    1.43  	struct razor_atomic *atomic;
    1.44 -	struct razor_install_iterator *ii;
    1.45  	int i, retval;
    1.46  
    1.47  	atomic = razor_atomic_open("Remove packages");
    1.48  
    1.49 -	root = razor_root_open(install_root, atomic);
    1.50 -	system = razor_set_ref(razor_root_get_system_set(root));
    1.51 +	system = razor_root_open_read_only(install_root, atomic);
    1.52  	if (system == NULL) {
    1.53  		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
    1.54 -		razor_root_close(root);
    1.55  		razor_atomic_destroy(atomic);
    1.56  		return 1;
    1.57  	}
    1.58  
    1.59 +	razor_atomic_destroy(atomic);
    1.60 +
    1.61  	upstream = razor_set_create_without_root();
    1.62  	trans = razor_transaction_create(system, upstream);
    1.63  	razor_set_unref(upstream);
    1.64 @@ -645,8 +641,6 @@
    1.65  			fprintf(stderr, "no match for %s\n", argv[i]);
    1.66  			razor_transaction_destroy(trans);
    1.67  			razor_set_unref(system);
    1.68 -			razor_root_close(root);
    1.69 -			razor_atomic_destroy(atomic);
    1.70  			return 1;
    1.71  		}
    1.72  	}
    1.73 @@ -656,33 +650,15 @@
    1.74  	if (retval) {
    1.75  		razor_transaction_destroy(trans);
    1.76  		razor_set_unref(system);
    1.77 -		razor_root_close(root);
    1.78 -		razor_atomic_destroy(atomic);
    1.79  		return 1;
    1.80  	}
    1.81  
    1.82  	next = razor_transaction_commit(trans);
    1.83 -	ii = razor_set_create_install_iterator(system, next);
    1.84 -	retval = update_packages(trans, ii, system, next, atomic, NULL,
    1.85 -				 UPDATE_PASS_PRE_REMOVE);
    1.86 -	if (retval)
    1.87 -		fprintf(stderr, "Remove aborted\n");
    1.88 -	else {
    1.89 -		update_packages(trans, ii, system, next, atomic, NULL,
    1.90 -				UPDATE_PASS_MAIN);
    1.91  
    1.92 -		razor_root_update(root, next);
    1.93 +	retval = update_system(install_root, NULL, trans, system, next,
    1.94 +			       "Remove");
    1.95  
    1.96 -		(void)razor_root_commit(root);
    1.97 -		retval = razor_atomic_commit(atomic);
    1.98 -		if (retval)
    1.99 -			fprintf(stderr, "%s\n",
   1.100 -				razor_atomic_get_error_msg(atomic));
   1.101 -	}
   1.102 -
   1.103 -	razor_install_iterator_destroy(ii);
   1.104  	razor_transaction_destroy(trans);
   1.105 -	razor_atomic_destroy(atomic);
   1.106  	razor_set_unref(system);
   1.107  	razor_set_unref(next);
   1.108  
   1.109 @@ -826,7 +802,7 @@
   1.110  
   1.111  	ii = razor_set_create_install_iterator(system, next);
   1.112  	while (razor_install_iterator_next(ii, &package, &action, &count)) {
   1.113 -		if (action == RAZOR_INSTALL_ACTION_REMOVE)
   1.114 +		if (action != RAZOR_INSTALL_ACTION_ADD)
   1.115  			continue;
   1.116  
   1.117  		razor_package_get_details(next, package,
   1.118 @@ -989,108 +965,118 @@
   1.119  }
   1.120  
   1.121  /*
   1.122 - * In the most general case, there should be three passes:
   1.123 - *
   1.124 - * 1) For each package to be removed, run %preun
   1.125 - *
   1.126 - * 2) For each package:
   1.127 - *	If the package is to be installed, run %pre
   1.128 - *	Update the files on disk
   1.129 - *	If the package has been removed, run %postun
   1.130 - *
   1.131 - * 3) For each packge installed, run %post
   1.132 - *
   1.133 - * This guarantees that:
   1.134 - *   a)	Save where dependency loops make it impossible, at the time
   1.135 - *	%pre is run, all required packages are installed (although
   1.136 - *	their %post script may not have been run). We should support
   1.137 - *	Requires(%pre) to allow packagers to describe their requirements
   1.138 - *	more accurately and avoid unnecessary dependency loops.
   1.139 - *   b)	At the time %preun is run, all required packages are installed.
   1.140 - *	Supporting Requires(%preun) would make this more complicated
   1.141 - *	since we might have to install a package in order to remove
   1.142 - *	another one. For now, treating Requires(%preun) as Requires
   1.143 - *	seems more sensible.
   1.144 - *   c)	At the time %post is run, all required packages are installed.
   1.145 - *	Supporting Requires(%post) would allow us to remove a package
   1.146 - *	that was only needed to install another, but there seems no
   1.147 - *	obvious advantage.
   1.148 - *   d)	Save where dependency loops make it impossible, at the time
   1.149 - *	%postun is run, all required packages are installed. Again,
   1.150 - *	we should support Requires(%postun) to avoid unnecessary
   1.151 - *	dependency loops.
   1.152 - *
   1.153 - * Notes:
   1.154 - *	rpm treats %pre and %preun script failures as fatal errors
   1.155 - *	and %post and %postun failures as warnings.
   1.156 + * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
   1.157 + * is met (in which case the action is consumed).
   1.158   */
   1.159  static int
   1.160  update_packages(struct razor_transaction *trans,
   1.161  		struct razor_install_iterator *ii, struct razor_set *system,
   1.162  		struct razor_set *next, struct razor_atomic *atomic,
   1.163  		struct razor_relocations *relocations,
   1.164 -		enum update_pass_type pass)
   1.165 +		enum razor_stage_type stage)
   1.166  {
   1.167  	struct razor_package *package;
   1.168  	enum razor_install_action action;
   1.169  	int retval = 0, count;
   1.170 -	enum razor_stage_type remove_stage, add_stage;
   1.171 -
   1.172 -	switch (pass) {
   1.173 -	case UPDATE_PASS_PRE_REMOVE:
   1.174 -		add_stage = 0;
   1.175 -		remove_stage = RAZOR_STAGE_SCRIPTS_PRE;
   1.176 -		break;
   1.177 -	case UPDATE_PASS_MAIN:
   1.178 -		add_stage = RAZOR_STAGE_SCRIPTS_PRE | RAZOR_STAGE_FILES;
   1.179 -		remove_stage = RAZOR_STAGE_FILES | RAZOR_STAGE_SCRIPTS_POST;
   1.180 -		break;
   1.181 -	case UPDATE_PASS_POST_INSTALL:
   1.182 -		add_stage = RAZOR_STAGE_SCRIPTS_POST;
   1.183 -		remove_stage = 0;
   1.184 -		break;
   1.185 -	}
   1.186 -
   1.187 -	razor_install_iterator_rewind(ii);
   1.188  
   1.189  	while (!retval && razor_install_iterator_next(ii, &package, &action,
   1.190  						      &count)) {
   1.191 -		if (action == RAZOR_INSTALL_ACTION_ADD && add_stage)
   1.192 -			retval = install_package(trans, next, atomic, package,
   1.193 -						 relocations, count, add_stage);
   1.194 -		else if (action == RAZOR_INSTALL_ACTION_REMOVE && remove_stage)
   1.195 -			retval = razor_package_remove(system, next, atomic,
   1.196 -						      package, install_root,
   1.197 -						      count, remove_stage);
   1.198 +		if (action == RAZOR_INSTALL_ACTION_ADD) {
   1.199 +			if (install_package(trans, next, atomic, package,
   1.200 +					    relocations, count, stage))
   1.201 +				retval = -1;
   1.202 +		} else if (action == RAZOR_INSTALL_ACTION_REMOVE) {
   1.203 +			if (razor_package_remove(system, next, atomic, package,
   1.204 +						 install_root, count, stage))
   1.205 +				retval = -1;
   1.206 +		} else if (action == RAZOR_INSTALL_ACTION_COMMIT)
   1.207 +				retval = 1;
   1.208  	}
   1.209  
   1.210  	return retval;
   1.211  }
   1.212  
   1.213  static int
   1.214 +update_system(const char *install_root, struct razor_relocations *relocations,
   1.215 +	      struct razor_transaction *trans, struct razor_set *system,
   1.216 +	      struct razor_set *next, const char *verb)
   1.217 +{
   1.218 +	struct razor_root *root;
   1.219 +	struct razor_set *set;
   1.220 +	struct razor_atomic *atomic;
   1.221 +	struct razor_install_iterator *ii;
   1.222 +	int r, retval = 0;
   1.223 +	char *description;
   1.224 +	size_t pos;
   1.225 +
   1.226 +	description = razor_concat(verb, " packages", NULL);
   1.227 +
   1.228 +	ii = razor_set_create_install_iterator(system, next);
   1.229 +
   1.230 +	do {
   1.231 +		pos = razor_install_iterator_tell(ii);
   1.232 +
   1.233 +		atomic = razor_atomic_open(description);
   1.234 +
   1.235 +		root = razor_root_open(install_root, atomic);
   1.236 +		if (root == NULL) {
   1.237 +			fprintf(stderr, "%s\n",
   1.238 +				razor_atomic_get_error_msg(atomic));
   1.239 +			razor_atomic_destroy(atomic);
   1.240 +			retval = 1;
   1.241 +			break;
   1.242 +		}
   1.243 +
   1.244 +		r = update_packages(trans, ii, system, next, atomic,
   1.245 +				    relocations, RAZOR_STAGE_SCRIPTS_PRE);
   1.246 +		if (r < 0) {
   1.247 +			fprintf(stderr, "%s aborted\n", verb);
   1.248 +			razor_atomic_destroy(atomic);
   1.249 +			retval = r;
   1.250 +		} else {
   1.251 +			razor_install_iterator_seek(ii, pos);
   1.252 +			r = update_packages(trans, ii, system, next, atomic,
   1.253 +					    relocations, RAZOR_STAGE_FILES);
   1.254 +
   1.255 +			if (r == 1) {
   1.256 +				set = razor_install_iterator_commit_set(ii);
   1.257 +				razor_root_update(root, set);
   1.258 +				razor_set_unref(set);
   1.259 +			} else if (r == 0)
   1.260 +				razor_root_update(root, next);
   1.261 +
   1.262 +			(void)razor_root_commit(root);
   1.263 +			retval = razor_atomic_commit(atomic);
   1.264 +			if (retval) {
   1.265 +				fprintf(stderr, "%s\n",
   1.266 +					razor_atomic_get_error_msg(atomic));
   1.267 +				razor_atomic_destroy(atomic);
   1.268 +			} else {
   1.269 +				razor_install_iterator_seek(ii, pos);
   1.270 +				update_packages(trans, ii, system, next,
   1.271 +						atomic, relocations,
   1.272 +						RAZOR_STAGE_SCRIPTS_POST);
   1.273 +			}
   1.274 +		}
   1.275 +
   1.276 +		razor_atomic_destroy(atomic);
   1.277 +	} while(!retval && r == 1);
   1.278 +
   1.279 +	free(description);
   1.280 +
   1.281 +	return retval;
   1.282 +}
   1.283 +
   1.284 +static int
   1.285  command_install_or_update(int argc, const char *argv[], int do_update)
   1.286  {
   1.287 -	struct razor_root *root;
   1.288  	struct razor_relocations *relocations=NULL;
   1.289  	struct razor_set *system, *upstream, *next, *set;
   1.290  	struct razor_transaction *trans;
   1.291  	struct razor_atomic *atomic;
   1.292 -	struct razor_install_iterator *ii;
   1.293  	int i, retval, len, dependencies = 1;
   1.294  	char *oldpath;
   1.295  
   1.296 -	if (do_update)
   1.297 -		atomic = razor_atomic_open("Update packages");
   1.298 -	else
   1.299 -		atomic = razor_atomic_open("Install packages");
   1.300 -
   1.301 -	root = razor_root_open(install_root, atomic);
   1.302 -	if (root == NULL) {
   1.303 -		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   1.304 -		razor_atomic_destroy(atomic);
   1.305 -		return 1;
   1.306 -	}
   1.307 -
   1.308  	for (i = 0; i < argc; i++) {
   1.309  		if (strcmp(argv[i], "--no-dependencies") == 0)
   1.310  			dependencies = 0;
   1.311 @@ -1119,10 +1105,14 @@
   1.312  			break;
   1.313  	}
   1.314  
   1.315 +	if (do_update)
   1.316 +		atomic = razor_atomic_open("Update packages");
   1.317 +	else
   1.318 +		atomic = razor_atomic_open("Install packages");
   1.319 +
   1.320  	upstream = razor_set_open(rawhide_repo_filename, atomic);
   1.321  	if (upstream == NULL) {
   1.322  		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   1.323 -		razor_root_close(root);
   1.324  		razor_atomic_destroy(atomic);
   1.325  		return 1;
   1.326  	}
   1.327 @@ -1132,7 +1122,6 @@
   1.328  		if (set == NULL) {
   1.329  			fprintf(stderr, "%s\n",
   1.330  				razor_atomic_get_error_msg(atomic));
   1.331 -			razor_root_close(root);
   1.332  			razor_atomic_destroy(atomic);
   1.333  			razor_set_unref(upstream);
   1.334  			return 1;
   1.335 @@ -1141,7 +1130,7 @@
   1.336  		upstream = set;
   1.337  	}
   1.338  
   1.339 -	system = razor_set_ref(razor_root_get_system_set(root));
   1.340 +	system = razor_root_open_read_only(install_root, atomic);
   1.341  
   1.342  	trans = razor_transaction_create(system, upstream);
   1.343  
   1.344 @@ -1156,7 +1145,6 @@
   1.345  			razor_transaction_destroy(trans);
   1.346  			razor_set_unref(upstream);
   1.347  			razor_set_unref(system);
   1.348 -			razor_root_close(root);
   1.349  			razor_atomic_destroy(atomic);
   1.350  			return 1;
   1.351  		}
   1.352 @@ -1168,23 +1156,24 @@
   1.353  			razor_transaction_destroy(trans);
   1.354  			razor_set_unref(upstream);
   1.355  			razor_set_unref(system);
   1.356 -			razor_root_close(root);
   1.357  			razor_atomic_destroy(atomic);
   1.358  			return 1;
   1.359  		}
   1.360  	}
   1.361  
   1.362  	if (razor_atomic_create_dir(atomic, "rpms",
   1.363 -				    S_IRWXU | S_IRWXG | S_IRWXO)) {
   1.364 +				    S_IRWXU | S_IRWXG | S_IRWXO) ||
   1.365 +	    razor_atomic_commit(atomic)) {
   1.366  		fprintf(stderr, "%s\n", razor_atomic_get_error_msg(atomic));
   1.367  		razor_transaction_destroy(trans);
   1.368  		razor_set_unref(upstream);
   1.369  		razor_set_unref(system);
   1.370 -		razor_root_close(root);
   1.371  		razor_atomic_destroy(atomic);
   1.372  		return 1;
   1.373  	}
   1.374  
   1.375 +	razor_atomic_destroy(atomic);
   1.376 +
   1.377  	next = razor_transaction_commit(trans);
   1.378  
   1.379  	if (download_packages(system, next) < 0) {
   1.380 @@ -1192,43 +1181,18 @@
   1.381  		razor_transaction_destroy(trans);
   1.382  		razor_set_unref(upstream);
   1.383  		razor_set_unref(system);
   1.384 -		razor_root_close(root);
   1.385  		razor_atomic_destroy(atomic);
   1.386                  return 1;
   1.387          }
   1.388  
   1.389 -	ii = razor_set_create_install_iterator(system, next);
   1.390 +	retval = update_system(install_root, relocations, trans, system, next,
   1.391 +			       do_update ? "Update" : "Install");
   1.392  
   1.393 -	retval = update_packages(trans, ii, system, next, atomic, relocations,
   1.394 -				 UPDATE_PASS_PRE_REMOVE);
   1.395 -	if (retval)
   1.396 -		fprintf(stderr, "%s aborted\n",
   1.397 -			do_update ? "Update" : "Install");
   1.398 -	else {
   1.399 -		update_packages(trans, ii, system, next, atomic, relocations,
   1.400 -				UPDATE_PASS_MAIN);
   1.401 -
   1.402 -		razor_root_update(root, next);
   1.403 -
   1.404 -		razor_set_unref(upstream);
   1.405 -
   1.406 -		(void)razor_root_commit(root);
   1.407 -		retval = razor_atomic_commit(atomic);
   1.408 -		if (retval)
   1.409 -			fprintf(stderr, "%s\n",
   1.410 -				razor_atomic_get_error_msg(atomic));
   1.411 -		else
   1.412 -			(void)update_packages(trans, ii, system, next, atomic,
   1.413 -					      relocations,
   1.414 -					      UPDATE_PASS_POST_INSTALL);
   1.415 -	}
   1.416 +	razor_set_unref(upstream);
   1.417  
   1.418  	razor_transaction_destroy(trans);
   1.419  	if (relocations)
   1.420  		razor_relocations_destroy(relocations);
   1.421 -	razor_install_iterator_destroy(ii);
   1.422 -
   1.423 -	razor_atomic_destroy(atomic);
   1.424  
   1.425  	razor_set_unref(next);
   1.426  	razor_set_unref(system);