plover/razor.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Aug 13 19:01:16 2009 +0100 (2009-08-13)
changeset 3 868db5c1f2d7
parent 2 1f06562182cb
child 6 e8c9cc792c5d
permissions -rw-r--r--
Add an update command
     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,upstream,pkgs[i]))
   243 	{
   244 	    fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   245 	    razor_root_close(root);
   246 	    return -1;
   247 	}
   248     razor_transaction_resolve(trans);
   249     if (razor_transaction_describe(trans)>0)
   250     {
   251 	razor_root_close(root);
   252 	return -1;
   253     }
   254     next=razor_transaction_commit(trans);
   255     plover_run_transaction(trans,base,install_root,system,next,relocations);
   256     razor_root_update(root,next);
   257     razor_transaction_destroy(trans);
   258     razor_set_destroy(next);
   259     razor_set_destroy(upstream);
   260     if (prefix)
   261 	razor_relocations_destroy(relocations);
   262     return razor_root_commit(root);
   263 }
   264 
   265 int plover_update(const char *base,const char *prefix,char **pkgs)
   266 {
   267     int i;
   268     char *install_root,*s;
   269     struct razor_root *root;
   270     struct razor_set *system,*set,*upstream,*next;
   271     struct razor_transaction *trans;
   272     struct razor_relocations *relocations;
   273     install_root=getenv("RAZOR_ROOT");
   274     if (!install_root)
   275 	install_root="";
   276     if (prefix)
   277     {
   278 	relocations=razor_relocations_create();
   279 	razor_relocations_add(relocations,"/usr",prefix);
   280     }
   281     set=razor_root_open_read_only(install_root);
   282     if (!set)
   283 	return 0;
   284     razor_set_destroy(set);
   285     root=razor_root_open(install_root);
   286     if (!root)
   287 	return -1;
   288     system=razor_root_get_system_set(root);
   289     if (!system)
   290     {
   291 	razor_root_close(root);
   292 	return -1;
   293     }
   294     s=plover_strconcat(base,"/repodata",NULL);
   295     if (!s)
   296     {
   297 	razor_root_close(root);
   298 	return -1;
   299     }
   300     if (chdir(s)<0)
   301     {
   302 	perror(s);
   303 	free(s);
   304 	razor_root_close(root);
   305 	return -1;
   306     }
   307     free(s);
   308     set=plover_razor_set_create_from_yum(base);
   309     if (!set)
   310     {
   311 	razor_root_close(root);
   312 	return -1;
   313     }
   314     upstream=plover_relocate_packages(set,base,relocations);
   315     razor_set_destroy(set);
   316     trans=razor_transaction_create(system,upstream);
   317     if (pkgs)
   318 	for(i=0;pkgs[i];i++)
   319 	{
   320 	    if (plover_mark_package_for_update(trans,system,pkgs[i]))
   321 	    {
   322 		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   323 		razor_transaction_destroy(trans);
   324 		razor_set_destroy(upstream);
   325 		razor_set_destroy(system);
   326 		razor_root_close(root);
   327 		return -1;
   328 	    }
   329 	}
   330     else
   331 	razor_transaction_update_all(trans);
   332     razor_transaction_resolve(trans);
   333     if (razor_transaction_describe(trans)>0)
   334     {
   335 	razor_transaction_destroy(trans);
   336 	razor_set_destroy(upstream);
   337 	razor_set_destroy(system);
   338 	razor_root_close(root);
   339 	return -1;
   340     }
   341     next=razor_transaction_commit(trans);
   342     plover_run_transaction(trans,base,install_root,system,next,relocations);
   343     razor_root_update(root,next);
   344     razor_transaction_destroy(trans);
   345     razor_set_destroy(next);
   346     razor_set_destroy(upstream);
   347     return razor_root_commit(root);
   348 }
   349 
   350 static int plover_mark_packages_for_removal(struct razor_transaction *trans,
   351   struct razor_set *set,const char *pkg)
   352 {
   353     struct razor_package_iterator *pi;
   354     struct razor_package *package;
   355     const char *name;
   356     int retval=pkg?-1:0;
   357     pi=razor_package_iterator_create(set);
   358     while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
   359       RAZOR_DETAIL_LAST))
   360     {
   361 	if (!pkg || !strcmp(name,pkg))
   362 	{
   363 	    razor_transaction_remove_package(trans,package);
   364 	    retval=0;
   365 	}
   366     }
   367     razor_package_iterator_destroy(pi);
   368     return retval;
   369 }
   370 
   371 int plover_remove(char **pkgs)
   372 {
   373     int i;
   374     char *install_root;
   375     struct razor_root *root;
   376     struct razor_set *system,*set,*upstream,*next;
   377     struct razor_transaction *trans;
   378     install_root=getenv("RAZOR_ROOT");
   379     if (!install_root)
   380 	install_root="";
   381     set=razor_root_open_read_only(install_root);
   382     if (!set)
   383 	return 0;
   384     razor_set_destroy(set);
   385     root=razor_root_open(install_root);
   386     if (!root)
   387 	return -1;
   388     system=razor_root_get_system_set(root);
   389     if (!system)
   390     {
   391 	razor_root_close(root);
   392 	return -1;
   393     }
   394     upstream=razor_set_create_without_root();
   395     trans=razor_transaction_create(system,upstream);
   396     if (pkgs)
   397 	for(i=0;pkgs[i];i++)
   398 	{
   399 	    if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
   400 	    {
   401 		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   402 		razor_transaction_destroy(trans);
   403 		razor_set_destroy(upstream);
   404 		razor_set_destroy(system);
   405 		razor_root_close(root);
   406 		return -1;
   407 	    }
   408 	}
   409     else
   410 	plover_mark_packages_for_removal(trans,system,NULL);
   411     razor_transaction_resolve(trans);
   412     if (razor_transaction_describe(trans)>0)
   413     {
   414 	razor_transaction_destroy(trans);
   415 	razor_set_destroy(upstream);
   416 	razor_set_destroy(system);
   417 	razor_root_close(root);
   418 	return -1;
   419     }
   420     next=razor_transaction_commit(trans);
   421     plover_run_transaction(trans,NULL,install_root,system,next,NULL);
   422     razor_root_update(root,next);
   423     razor_transaction_destroy(trans);
   424     razor_set_destroy(next);
   425     razor_set_destroy(upstream);
   426     return razor_root_commit(root);
   427 }