1.1 --- a/src/main.c Thu Nov 10 10:35:21 2011 +0000
1.2 +++ b/src/main.c Thu Feb 09 20:43:58 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)