plover/razor.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Jul 09 08:23:50 2009 +0100 (2009-07-09)
changeset 0 49fc8f60e4a5
child 2 1f06562182cb
permissions -rw-r--r--
Initial checkin
     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     struct razor_set *set;
   103     enum razor_install_action action;
   104     struct razor_rpm *rpm;
   105     const char *name,*version,*arch;
   106     char *s,*file;
   107     int count;
   108     ii=razor_set_create_install_iterator(system,next);
   109     printf("Running Transaction\n");
   110     while (razor_install_iterator_next(ii,&set,&package,&action,&count))
   111     {
   112 	if (action==RAZOR_INSTALL_ACTION_REMOVE)
   113 	{
   114 	    razor_package_get_details(set,package,RAZOR_DETAIL_NAME,&name,
   115 	      RAZOR_DETAIL_LAST);
   116 	    printf("  Removing : %s ",name);
   117 	    if (razor_package_remove(set,package,install_root,0)<0)
   118 		printf(
   119 		  "\nWarning: one or more errors occurred while removing %s",
   120 		  name);
   121 	    printf("\n");
   122 	}
   123 	else
   124 	{
   125 	    razor_package_get_details(set,package,RAZOR_DETAIL_NAME,&name,
   126 	      RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
   127 	      RAZOR_DETAIL_LAST);
   128 	    printf("  Installing : %s ",name);
   129 	    s=rpm_filename(name,version,arch);
   130 	    file=plover_strconcat(base,"/rpms/",s,NULL);
   131 	    free(s);
   132 	    rpm=razor_rpm_open(file);
   133 	    if (!rpm)
   134 	    {
   135 		fprintf(stderr,"failed to open rpm %s\n",file);
   136 		free(file);
   137 		razor_install_iterator_destroy(ii);
   138 		return -1;
   139 	    }
   140 	    if (relocations)
   141 		razor_rpm_set_relocations(rpm,relocations);
   142 	    razor_transaction_fixup_package(trans,package,rpm);
   143 	    if (razor_rpm_install(rpm,install_root,1)<0)
   144 	    {
   145 		fprintf(stderr,"failed to install rpm %s\n",file);
   146 		razor_rpm_close(rpm);
   147 		free(file);
   148 		razor_install_iterator_destroy(ii);
   149 		return -1;
   150 	    }
   151 	    razor_rpm_close(rpm);
   152 	    free(file);
   153 	    printf("\n");
   154 	}
   155     }
   156     razor_install_iterator_destroy(ii);
   157     return 0;
   158 }
   159 
   160 static int plover_mark_package_for_update(struct razor_transaction *trans,
   161   struct razor_set *set,const char *pkg)
   162 {
   163     struct razor_package_iterator *pi;
   164     struct razor_package *package;
   165     const char *name;
   166     int retval=-1;
   167     pi=razor_package_iterator_create(set);
   168     while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
   169       RAZOR_DETAIL_LAST))
   170     {
   171 	if (!strcmp(name,pkg))
   172 	{
   173 	    razor_transaction_update_package(trans,package);
   174 	    retval=0;
   175 	    break;
   176 	}
   177     }
   178     razor_package_iterator_destroy(pi);
   179     return retval;
   180 }
   181 
   182 int plover_install(const char *base,const char *prefix,char **pkgs)
   183 {
   184     int i;
   185     char *s;
   186     char *install_root;
   187     struct razor_root *root;
   188     struct razor_set *system,*set,*upstream,*next;
   189     struct razor_transaction *trans;
   190     struct razor_relocations *relocations;
   191     install_root=getenv("RAZOR_ROOT");
   192     if (!install_root)
   193 	install_root="";
   194     if (prefix)
   195     {
   196 	relocations=razor_relocations_create();
   197 	razor_relocations_add(relocations,"/usr",prefix);
   198     }
   199     /*
   200      * Calling razor_root_open() on a system that hasn't yet had
   201      * razor_root_create() run generates a confusing error message
   202      * on stderr. Avoid this by trying to open it R/O first which
   203      * fails without generating any error.
   204      */
   205     set=razor_root_open_read_only(install_root);
   206     if (set)
   207 	razor_set_destroy(set);
   208     else
   209 	razor_root_create(install_root);
   210     root=razor_root_open(install_root);
   211     if (!root)
   212 	return -1;
   213     system=razor_root_get_system_set(root);
   214     if (!system)
   215     {
   216 	razor_root_close(root);
   217 	return -1;
   218     }
   219     s=plover_strconcat(base,"/repodata",NULL);
   220     if (!s)
   221     {
   222 	razor_root_close(root);
   223 	return -1;
   224     }
   225     if (chdir(s)<0)
   226     {
   227 	perror(s);
   228 	free(s);
   229 	razor_root_close(root);
   230 	return -1;
   231     }
   232     free(s);
   233     set=plover_razor_set_create_from_yum(base);
   234     if (!set)
   235     {
   236 	razor_root_close(root);
   237 	return -1;
   238     }
   239     upstream=plover_relocate_packages(set,base,relocations);
   240     razor_set_destroy(set);
   241     trans=razor_transaction_create(system,upstream);
   242     for(i=0;pkgs[i];i++)
   243 	if (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 static int plover_mark_packages_for_removal(struct razor_transaction *trans,
   267   struct razor_set *set,const char *pkg)
   268 {
   269     struct razor_package_iterator *pi;
   270     struct razor_package *package;
   271     const char *name;
   272     int retval=pkg?-1:0;
   273     pi=razor_package_iterator_create(set);
   274     while (razor_package_iterator_next(pi,&package,RAZOR_DETAIL_NAME,&name,
   275       RAZOR_DETAIL_LAST))
   276     {
   277 	if (!pkg || !strcmp(name,pkg))
   278 	{
   279 	    razor_transaction_remove_package(trans,package);
   280 	    retval=0;
   281 	}
   282     }
   283     razor_package_iterator_destroy(pi);
   284     return retval;
   285 }
   286 
   287 int plover_remove(char **pkgs)
   288 {
   289     int i;
   290     char *install_root;
   291     struct razor_root *root;
   292     struct razor_set *system,*set,*upstream,*next;
   293     struct razor_transaction *trans;
   294     install_root=getenv("RAZOR_ROOT");
   295     if (!install_root)
   296 	install_root="";
   297     set=razor_root_open_read_only(install_root);
   298     if (!set)
   299 	return 0;
   300     razor_set_destroy(set);
   301     root=razor_root_open(install_root);
   302     if (!root)
   303 	return -1;
   304     system=razor_root_get_system_set(root);
   305     if (!system)
   306     {
   307 	razor_root_close(root);
   308 	return -1;
   309     }
   310     upstream=razor_set_create_without_root();
   311     trans=razor_transaction_create(system,upstream);
   312     if (pkgs)
   313 	for(i=0;pkgs[i];i++)
   314 	{
   315 	    if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
   316 	    {
   317 		fprintf(stderr,"%s: Package not found\n",pkgs[i]);
   318 		razor_transaction_destroy(trans);
   319 		razor_set_destroy(upstream);
   320 		razor_set_destroy(system);
   321 		razor_root_close(root);
   322 		return -1;
   323 	    }
   324 	}
   325     else
   326 	plover_mark_packages_for_removal(trans,system,NULL);
   327     razor_transaction_resolve(trans);
   328     if (razor_transaction_describe(trans)>0)
   329     {
   330 	razor_transaction_destroy(trans);
   331 	razor_set_destroy(upstream);
   332 	razor_set_destroy(system);
   333 	razor_root_close(root);
   334 	return -1;
   335     }
   336     next=razor_transaction_commit(trans);
   337     plover_run_transaction(trans,NULL,install_root,system,next,NULL);
   338     razor_root_update(root,next);
   339     razor_transaction_destroy(trans);
   340     razor_set_destroy(next);
   341     razor_set_destroy(upstream);
   342     return razor_root_commit(root);
   343 }