plover/razor.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Oct 01 20:38:39 2009 +0100 (2009-10-01)
changeset 6 e8c9cc792c5d
parent 3 868db5c1f2d7
child 13 b0a35bae4961
permissions -rw-r--r--
Fix bug causing setup to install already existing packages
     1 /*
     2  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     3  * Copyright (C) 2008  Red Hat, Inc
     4  * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
     5  *
     6  * This program is free software; you can redistribute it and/or modify
     7  * it under the terms of the GNU General Public License as published by
     8  * the Free Software Foundation; either version 2 of the License, or
     9  * (at your option) any later version.
    10  *
    11  * This program is distributed in the hope that it will be useful,
    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  * GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along
    17  * with this program; if not, write to the Free Software Foundation, Inc.,
    18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    19  */
    20 
    21 #include <stdlib.h>
    22 #include <stdio.h>
    23 #include <stdarg.h>
    24 #include <string.h>
    25 #include <unistd.h>
    26 #include <razor.h>
    27 #include "config.h"
    28 #include "plover/plover.h"
    29 
    30 static char *rpm_filename(const char *name,const char *version,const char *arch)
    31 {
    32     const char *v;
    33     v=strchr(version,':');	      /* Skip epoch */
    34     if (v)
    35 	v++;
    36     else
    37 	v=version;
    38     return plover_strconcat(name,"-",v,".",arch,".rpm",NULL);
    39 }
    40 
    41 struct razor_set *plover_relocate_packages(struct razor_set *set,
    42   const char *base,struct razor_relocations *relocations)
    43 {
    44     struct razor_importer *importer;
    45     struct razor_property_iterator *prop_iter;
    46     struct razor_package_iterator *pkg_iter;
    47     struct razor_file_iterator *file_iter;
    48     struct razor_package *package;
    49     struct razor_property *property;
    50     struct razor_rpm *rpm;
    51     const char *name,*version,*arch,*summary,*desc,*url,*license;
    52     char *s,*file;
    53     uint32_t flags;
    54     importer=razor_importer_create();
    55     pkg_iter=razor_package_iterator_create(set);
    56     while (razor_package_iterator_next(pkg_iter,&package,RAZOR_DETAIL_NAME,
    57       &name,RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
    58       RAZOR_DETAIL_SUMMARY,&summary,RAZOR_DETAIL_DESCRIPTION,&desc,
    59       RAZOR_DETAIL_URL,&url,RAZOR_DETAIL_LICENSE,&license,RAZOR_DETAIL_LAST))
    60     {
    61 	s=rpm_filename(name,version,arch);
    62 	file=plover_strconcat(base,"/rpms/",s,NULL);
    63 	free(s);
    64 	rpm=razor_rpm_open(file);
    65 	if (!rpm)
    66 	{
    67 	    fprintf(stderr,"failed to open rpm %s\n",file);
    68 	    razor_package_iterator_destroy(pkg_iter);
    69 	    razor_importer_destroy(importer);
    70 	    free(file);
    71 	    return NULL;
    72 	}
    73 	free(file);
    74 	razor_relocations_set_rpm(relocations,rpm);
    75 	razor_rpm_close(rpm);
    76 	razor_importer_begin_package(importer,name,version,arch);
    77 	razor_importer_add_details(importer,summary,desc,url,license);
    78 	prop_iter=razor_property_iterator_create(set,package);
    79 	while (razor_property_iterator_next(prop_iter,&property,&name,&flags,
    80 	  &version))
    81 	    razor_importer_add_property(importer,name,flags,version);
    82 	razor_property_iterator_destroy(prop_iter);
    83 	file_iter=razor_file_iterator_create(set,package,0);
    84 	while (razor_file_iterator_next(file_iter,&name))
    85 	{
    86 	    name=razor_relocations_apply(relocations,name);
    87 	    razor_importer_add_file(importer,name);
    88 	}
    89 	razor_file_iterator_destroy(file_iter);
    90 	razor_importer_finish_package(importer);
    91     }
    92     razor_package_iterator_destroy(pkg_iter);
    93     return razor_importer_finish(importer);
    94 }
    95 
    96 int plover_run_transaction(struct razor_transaction *trans,const char *base,
    97   const char *install_root,struct razor_set *system,struct razor_set *next,
    98   struct razor_relocations *relocations)
    99 {
   100     struct razor_install_iterator *ii;
   101     struct razor_package *package;
   102     enum razor_install_action action;
   103     struct razor_rpm *rpm;
   104     const char *name,*version,*arch;
   105     char *s,*file;
   106     int count;
   107     ii=razor_set_create_install_iterator(system,next);
   108     printf("Running Transaction\n");
   109     while (razor_install_iterator_next(ii,&package,&action,&count))
   110     {
   111 	if (action==RAZOR_INSTALL_ACTION_REMOVE)
   112 	{
   113 	    razor_package_get_details(system,package,RAZOR_DETAIL_NAME,&name,
   114 	      RAZOR_DETAIL_LAST);
   115 	    printf("  Removing : %s ",name);
   116 	    if (razor_package_remove(system,next,package,install_root,count)<0)
   117 		printf(
   118 		  "\nWarning: one or more errors occurred while removing %s",
   119 		  name);
   120 	    printf("\n");
   121 	}
   122 	else
   123 	{
   124 	    razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
   125 	      RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
   126 	      RAZOR_DETAIL_LAST);
   127 	    printf("  Installing : %s ",name);
   128 	    s=rpm_filename(name,version,arch);
   129 	    file=plover_strconcat(base,"/rpms/",s,NULL);
   130 	    free(s);
   131 	    rpm=razor_rpm_open(file);
   132 	    if (!rpm)
   133 	    {
   134 		fprintf(stderr,"failed to open rpm %s\n",file);
   135 		free(file);
   136 		razor_install_iterator_destroy(ii);
   137 		return -1;
   138 	    }
   139 	    if (relocations)
   140 		razor_rpm_set_relocations(rpm,relocations);
   141 	    razor_transaction_fixup_package(trans,package,rpm);
   142 	    if (razor_rpm_install(rpm,install_root,1)<0)
   143 	    {
   144 		fprintf(stderr,"failed to install rpm %s\n",file);
   145 		razor_rpm_close(rpm);
   146 		free(file);
   147 		razor_install_iterator_destroy(ii);
   148 		return -1;
   149 	    }
   150 	    razor_rpm_close(rpm);
   151 	    free(file);
   152 	    printf("\n");
   153 	}
   154     }
   155     razor_install_iterator_destroy(ii);
   156     return 0;
   157 }
   158 
   159 static int plover_mark_package_for_update(struct razor_transaction *trans,
   160   struct razor_set *set,const char *pkg)
   161 {
   162     struct razor_package_iterator *pi;
   163     struct razor_package *package;
   164     const char *name;
   165     int retval=-1;
   166     pi=razor_package_iterator_create(set);
   167     while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
   168       RAZOR_DETAIL_LAST))
   169     {
   170 	if (!strcmp(name,pkg))
   171 	{
   172 	    razor_transaction_update_package(trans,package);
   173 	    retval=0;
   174 	    break;
   175 	}
   176     }
   177     razor_package_iterator_destroy(pi);
   178     return retval;
   179 }
   180 
   181 int plover_install(const char *base,const char *prefix,char **pkgs)
   182 {
   183     int i;
   184     char *s;
   185     char *install_root;
   186     struct razor_root *root;
   187     struct razor_set *system,*set,*upstream,*next;
   188     struct razor_transaction *trans;
   189     struct razor_relocations *relocations;
   190     install_root=getenv("RAZOR_ROOT");
   191     if (!install_root)
   192 	install_root="";
   193     if (prefix)
   194     {
   195 	relocations=razor_relocations_create();
   196 	razor_relocations_add(relocations,"/usr",prefix);
   197     }
   198     /*
   199      * Calling razor_root_open() on a system that hasn't yet had
   200      * razor_root_create() run generates a confusing error message
   201      * on stderr. Avoid this by trying to open it R/O first which
   202      * fails without generating any error.
   203      */
   204     set=razor_root_open_read_only(install_root);
   205     if (set)
   206 	razor_set_destroy(set);
   207     else
   208 	razor_root_create(install_root);
   209     root=razor_root_open(install_root);
   210     if (!root)
   211 	return -1;
   212     system=razor_root_get_system_set(root);
   213     if (!system)
   214     {
   215 	razor_root_close(root);
   216 	return -1;
   217     }
   218     s=plover_strconcat(base,"/repodata",NULL);
   219     if (!s)
   220     {
   221 	razor_root_close(root);
   222 	return -1;
   223     }
   224     if (chdir(s)<0)
   225     {
   226 	perror(s);
   227 	free(s);
   228 	razor_root_close(root);
   229 	return -1;
   230     }
   231     free(s);
   232     set=plover_razor_set_create_from_yum(base);
   233     if (!set)
   234     {
   235 	razor_root_close(root);
   236 	return -1;
   237     }
   238     upstream=plover_relocate_packages(set,base,relocations);
   239     razor_set_destroy(set);
   240     trans=razor_transaction_create(system,upstream);
   241     for(i=0;pkgs[i];i++)
   242 	if (plover_mark_package_for_update(trans,system,pkgs[i]) &&
   243 	  plover_mark_package_for_update(trans,upstream,pkgs[i]))
   244 	{
   245 	    fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   246 	    razor_root_close(root);
   247 	    return -1;
   248 	}
   249     razor_transaction_resolve(trans);
   250     if (razor_transaction_describe(trans)>0)
   251     {
   252 	razor_root_close(root);
   253 	return -1;
   254     }
   255     next=razor_transaction_commit(trans);
   256     plover_run_transaction(trans,base,install_root,system,next,relocations);
   257     razor_root_update(root,next);
   258     razor_transaction_destroy(trans);
   259     razor_set_destroy(next);
   260     razor_set_destroy(upstream);
   261     if (prefix)
   262 	razor_relocations_destroy(relocations);
   263     return razor_root_commit(root);
   264 }
   265 
   266 int plover_update(const char *base,const char *prefix,char **pkgs)
   267 {
   268     int i;
   269     char *install_root,*s;
   270     struct razor_root *root;
   271     struct razor_set *system,*set,*upstream,*next;
   272     struct razor_transaction *trans;
   273     struct razor_relocations *relocations;
   274     install_root=getenv("RAZOR_ROOT");
   275     if (!install_root)
   276 	install_root="";
   277     if (prefix)
   278     {
   279 	relocations=razor_relocations_create();
   280 	razor_relocations_add(relocations,"/usr",prefix);
   281     }
   282     set=razor_root_open_read_only(install_root);
   283     if (!set)
   284 	return 0;
   285     razor_set_destroy(set);
   286     root=razor_root_open(install_root);
   287     if (!root)
   288 	return -1;
   289     system=razor_root_get_system_set(root);
   290     if (!system)
   291     {
   292 	razor_root_close(root);
   293 	return -1;
   294     }
   295     s=plover_strconcat(base,"/repodata",NULL);
   296     if (!s)
   297     {
   298 	razor_root_close(root);
   299 	return -1;
   300     }
   301     if (chdir(s)<0)
   302     {
   303 	perror(s);
   304 	free(s);
   305 	razor_root_close(root);
   306 	return -1;
   307     }
   308     free(s);
   309     set=plover_razor_set_create_from_yum(base);
   310     if (!set)
   311     {
   312 	razor_root_close(root);
   313 	return -1;
   314     }
   315     upstream=plover_relocate_packages(set,base,relocations);
   316     razor_set_destroy(set);
   317     trans=razor_transaction_create(system,upstream);
   318     if (pkgs)
   319 	for(i=0;pkgs[i];i++)
   320 	{
   321 	    if (plover_mark_package_for_update(trans,system,pkgs[i]))
   322 	    {
   323 		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   324 		razor_transaction_destroy(trans);
   325 		razor_set_destroy(upstream);
   326 		razor_set_destroy(system);
   327 		razor_root_close(root);
   328 		return -1;
   329 	    }
   330 	}
   331     else
   332 	razor_transaction_update_all(trans);
   333     razor_transaction_resolve(trans);
   334     if (razor_transaction_describe(trans)>0)
   335     {
   336 	razor_transaction_destroy(trans);
   337 	razor_set_destroy(upstream);
   338 	razor_set_destroy(system);
   339 	razor_root_close(root);
   340 	return -1;
   341     }
   342     next=razor_transaction_commit(trans);
   343     plover_run_transaction(trans,base,install_root,system,next,relocations);
   344     razor_root_update(root,next);
   345     razor_transaction_destroy(trans);
   346     razor_set_destroy(next);
   347     razor_set_destroy(upstream);
   348     return razor_root_commit(root);
   349 }
   350 
   351 static int plover_mark_packages_for_removal(struct razor_transaction *trans,
   352   struct razor_set *set,const char *pkg)
   353 {
   354     struct razor_package_iterator *pi;
   355     struct razor_package *package;
   356     const char *name;
   357     int retval=pkg?-1:0;
   358     pi=razor_package_iterator_create(set);
   359     while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
   360       RAZOR_DETAIL_LAST))
   361     {
   362 	if (!pkg || !strcmp(name,pkg))
   363 	{
   364 	    razor_transaction_remove_package(trans,package);
   365 	    retval=0;
   366 	}
   367     }
   368     razor_package_iterator_destroy(pi);
   369     return retval;
   370 }
   371 
   372 int plover_remove(char **pkgs)
   373 {
   374     int i;
   375     char *install_root;
   376     struct razor_root *root;
   377     struct razor_set *system,*set,*upstream,*next;
   378     struct razor_transaction *trans;
   379     install_root=getenv("RAZOR_ROOT");
   380     if (!install_root)
   381 	install_root="";
   382     set=razor_root_open_read_only(install_root);
   383     if (!set)
   384 	return 0;
   385     razor_set_destroy(set);
   386     root=razor_root_open(install_root);
   387     if (!root)
   388 	return -1;
   389     system=razor_root_get_system_set(root);
   390     if (!system)
   391     {
   392 	razor_root_close(root);
   393 	return -1;
   394     }
   395     upstream=razor_set_create_without_root();
   396     trans=razor_transaction_create(system,upstream);
   397     if (pkgs)
   398 	for(i=0;pkgs[i];i++)
   399 	{
   400 	    if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
   401 	    {
   402 		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   403 		razor_transaction_destroy(trans);
   404 		razor_set_destroy(upstream);
   405 		razor_set_destroy(system);
   406 		razor_root_close(root);
   407 		return -1;
   408 	    }
   409 	}
   410     else
   411 	plover_mark_packages_for_removal(trans,system,NULL);
   412     razor_transaction_resolve(trans);
   413     if (razor_transaction_describe(trans)>0)
   414     {
   415 	razor_transaction_destroy(trans);
   416 	razor_set_destroy(upstream);
   417 	razor_set_destroy(system);
   418 	razor_root_close(root);
   419 	return -1;
   420     }
   421     next=razor_transaction_commit(trans);
   422     plover_run_transaction(trans,NULL,install_root,system,next,NULL);
   423     razor_root_update(root,next);
   424     razor_transaction_destroy(trans);
   425     razor_set_destroy(next);
   426     razor_set_destroy(upstream);
   427     return razor_root_commit(root);
   428 }