Eric, I see nothing about these changes to do.c that couldn't be
accomplished inside the portage-specific functions. If I'm
overlooking something, could you please clarify the issue for me?
If it does require something specific, I think we might be better off
making an intermediary function that calls a pkgmgr-specific routine
to alter the package info prior to adding to a list. For instance,
this would be useful for freebsd -- just not so useful that I wanted
to add that abstraction just for freebsd. But if we find that most
pkgmgrs need it, then...
On Jul 20, 2007, at 5:14 PM, [EMAIL PROTECTED] wrote:
> This patch updates Portage package manager support to the new code
> introduced in 2.2.1. Portage support was broken by that patch,
> this restores it, while making several improvements (like moving
> from equery to qlist for drastic speed improvements).
>
> Note: a lot of Portage-specific code was introduced to do.c; this
> code is essential here because the package code has to modify the
> package name given to it. This could be handled in package.c if
> the complete Package* object was passed to PackageCheck(). I'll
> work on a patch for this later.
>
> Index: cfengine-trunk/src/do.c
> ===================================================================
> --- cfengine-trunk.orig/src/do.c
> +++ cfengine-trunk/src/do.c
> @@ -2738,6 +2738,7 @@ void CheckPackages()
> /* pkgmgr_none will always be the highest number in the enum so set
> the array size with that */
> struct Item *pending_pkgs = NULL;
> + char *wholepackage = NULL;
> enum pkgmgrs prev_pkgmgr = pkgmgr_none;
> enum pkgactions prev_action = pkgaction_none;
>
> @@ -2778,8 +2779,31 @@ for (ptr = VPKG; ptr != NULL; ptr=ptr->n
> AddMultipleClasses(ptr->defines);
> if (ptr->action == pkgaction_remove)
> {
> - PackageList(ptr->name, ptr->pkgmgr, ptr->ver, ptr->cmp,
> &pending_pkgs);
> - AppendItem(&pending_pkgs, ptr->name, NULL);
> + if (ptr->pkgmgr == pkgmgr_portage && (ptr->ver)[0])
> + {
> + /* Portage doesn't use a list, just the package atom */
> + int wholesize = 2 + strlen(ptr->name) + strlen(ptr-
> >ver) + strlen(CMPSENSEOPERAND[ptr->cmp]);
> + wholepackage = (char *) malloc(wholesize);
> + strncpy(wholepackage, CMPSENSEOPERAND[ptr->cmp],
> wholesize - 1);
> + strncat(wholepackage, ptr->name, wholesize - strlen
> (wholepackage) - 1);
> + strncat(wholepackage, "-", wholesize - strlen
> (wholepackage) - 1);
> + strncat(wholepackage, ptr->ver, wholesize - strlen
> (wholepackage) - 1);
> +
> + /* Replace pkg->name with package atom */
> + free(ptr->name);
> + ptr->name = wholepackage;
> + wholepackage = NULL;
> +
> + AppendItem(&pending_pkgs, ptr->name, NULL);
> + }
> + else if (ptr->pkgmgr == pkgmgr_portage)
> + {
> + AppendItem(&pending_pkgs, ptr->name, NULL);
> + }
> + else
> + {
> + PackageList(ptr->name, ptr->pkgmgr, ptr->ver, ptr-
> >cmp, &pending_pkgs);
> + }
>
> /* Some package managers operate best doing things one at
> a time. */
> if ( (ptr->pkgmgr == pkgmgr_freebsd) || (ptr->pkgmgr ==
> pkgmgr_sun) )
> @@ -2798,6 +2822,22 @@ for (ptr = VPKG; ptr != NULL; ptr=ptr->n
> AddMultipleClasses(ptr->elsedef);
> if (ptr->action == pkgaction_install)
> {
> + if (ptr->pkgmgr == pkgmgr_portage && (ptr->ver)[0])
> + {
> + /* Portage wants the version in the package atom */
> + int wholesize = 2 + strlen(ptr->name) + strlen(ptr-
> >ver) + strlen(CMPSENSEOPERAND[ptr->cmp]);
> + wholepackage = (char *) malloc(wholesize);
> + strncpy(wholepackage, CMPSENSEOPERAND[ptr->cmp],
> wholesize - 1);
> + strncat(wholepackage, ptr->name, wholesize - strlen
> (wholepackage) - 1);
> + strncat(wholepackage, "-", wholesize - strlen
> (wholepackage) - 1);
> + strncat(wholepackage, ptr->ver, wholesize - strlen
> (wholepackage) - 1);
> +
> + /* Replace pkg->name with package atom */
> + free(ptr->name);
> + ptr->name = wholepackage;
> + wholepackage = NULL;
> + }
> +
> AppendItem(&pending_pkgs, ptr->name, NULL);
>
> /* Some package managers operate best doing things one at
> a time. */
> Index: cfengine-trunk/src/package.c
> ===================================================================
> --- cfengine-trunk.orig/src/package.c
> +++ cfengine-trunk/src/package.c
> @@ -246,7 +246,7 @@ switch(pkgmgr)
> Verbose("InstallPackage(): using '%s'\n", instcmd);
> if (DONTDO)
> {
> - Verbose("--skipping because DONTDO is enabled.");
> + Verbose("--skipping because DONTDO is enabled.\n");
> result = 1;
> }
> else
> @@ -337,6 +337,18 @@ int RemovePackage(enum pkgmgrs pkgmgr, s
> }
> break;
>
> + /* Portage */
> + case pkgmgr_portage:
> + if (!GetMacroValue(CONTEXTID,"PortageRemoveCommand"))
> + {
> + strncpy(rawdelcmd, "/usr/bin/emerge -C %s", 21 );
> + }
> + else
> + {
> + strncpy(rawdelcmd, GetMacroValue
> (CONTEXTID,"PortageRemoveCommand"),CF_BUFSIZE);
> + }
> + break;
> +
> /* Default */
> default:
> Verbose("Package removal not yet implemented for this
> package manager.");
> @@ -348,7 +360,7 @@ int RemovePackage(enum pkgmgrs pkgmgr, s
> Verbose("RemovePackage(): using '%s'\n", delcmd);
> if (DONTDO)
> {
> - Verbose("--skipping because DONTDO is enabled.");
> + Verbose("--skipping because DONTDO is enabled.\n");
> result = 1;
> }
> else
> @@ -448,7 +460,6 @@ int BuildCommandLine(char *resolvedcmd,
> strncpy(cmd_ptr, cmd_tail, &resolvedcmd[CF_BUFSIZE*2] -
> cmd_ptr);
> }
> }
> - Verbose("Resolved command is '%s'\n", resolvedcmd );
> return 1;
> }
>
> @@ -1326,27 +1337,21 @@ int v,r,m,f;
>
> int PortagePackageCheck(char *package,char *version,enum cmpsense
> cmp)
>
> -{ FILE *pp;
> - struct Item *ebuildlist = NULL;
> - struct Item *ebuild;
> - enum cmpsense result;
> - int match = 0;
> - char *comparehead = NULL;
> - char *comparetail = NULL;
> - char *installedhead = NULL;
> - char *installedtail = NULL;
> -
> - /* Yes, it's an ugly python one-liner that does something
> beautiful */
> -
> -snprintf(VBUFF,CF_BUFSIZE,"/usr/bin/python -c 'import portage, re,
> sys; "
> - "[sys.stdout.write(re.sub(\"\\w*?\\-\\w*?\\/([a-zA-Z0-9_
> +]|\\-(?![0-9]))*\\-\", \"\", package, 1) + "
> - "\"\\n\") for package in portage.db[\"/\"][\"vartree
> \"].dbapi.match("
> - "\"%s\")]'", package);
> +{ FILE *pp;
> + struct Item *ebuildlist = NULL;
> + struct Item *ebuild;
> + int match = 0;
> + char *result = NULL;
> +
> +/* Search for installed versions of package */
> +snprintf(VBUFF,CF_BUFSIZE,"/usr/bin/qlist -IevC %s",package);
>
> if ((pp = cfpopen(VBUFF, "r")) == NULL)
> {
> - Verbose("Could not execute the equery command. Assuming
> package not installed.\n");
> - return 0;
> + snprintf(OUTPUT,CF_BUFSIZE,"Could not execute the qlist
> command. "
> + "Is portage-utils installed?\n");
> + CfLog(cferror,OUTPUT,"");
> + return -1;
> }
>
> while(!feof(pp))
> @@ -1361,14 +1366,7 @@ while(!feof(pp))
> }
> }
>
> -/* Non-zero exit status means that we could not find the package, so
> - * zero the list and bail. */
> -
> -if (cfpclose(pp) != 0)
> - {
> - DeleteItemList(ebuildlist);
> - ebuildlist = NULL;
> - }
> +cfpclose(pp);
>
> if (ebuildlist == NULL)
> {
> @@ -1376,145 +1374,92 @@ if (ebuildlist == NULL)
> return 0;
> }
>
> -
> Verbose("PortageCheckPackage(): Requested %s %s %s\n", package,
> CMPSENSETEXT[cmp],(version[0] ? version : "ANY"));
>
> -/* If no version was specified, just return 1, because if we got
> this far
> - * some package by that name exists. */
> -
> +/* If no version was specified, return successful (found
> something) */
> if (!version[0])
> {
> DeleteItemList(ebuildlist);
> return 1;
> }
>
> -/* The rule here will be: if any package in the list matches, then
> the
> - * first one to match wins, and we bail out. */
> -
> -
> +/* Iterate through all installed versions until match is found */
> for (ebuild = ebuildlist; ebuild != NULL; ebuild=ebuild->next)
> - {
> - char *ebuildver;
> - ebuildver = ebuild->name;
> -
> - Verbose("PortageCheckPackage(): Trying installed version %s\n",
> ebuildver);
> -
> - /* Start out assuming the comparison will be equal. */
> - result = cmpsense_eq;
> -
> - comparehead = version;
> - comparetail = NULL;
> - installedhead = ebuildver;
> - installedtail = NULL;
> -
> - /* Iterate over version portions delimited by `-' */
> - while (result == cmpsense_eq)
> - {
> - if (*comparehead == '\0' && *installedhead == '\0')
> - {
> - /* No substrings remain, break from while */
> - break;
> - }
> - else if (*comparehead == '\0')
> - {
> - /* Installed version has more version substrings than
> given */
> - result = cmpsense_gt;
> - }
> - else if (*installedhead == '\0')
> - {
> - /* Installed version has less version substrings than
> given */
> - result = cmpsense_lt;
> - }
> - else
> - {
> - /* New substring in both to test */
> - comparetail = strchr(comparehead, '-');
> - installedtail = strchr(installedhead, '-');
> -
> - /* Throw a \0 over the `-' so just the substring is tested.
> - * If the tail is less than the head, we must be at last
> substring,
> - * as no `-'s were found (so the `\0' is already there) */
> - if (comparetail > comparehead) *comparetail = '\0';
> - if (installedtail > installedhead) *installedtail = '\0';
> -
> - switch (rpmvercmp(installedhead, comparehead))
> - {
> - case 1:
> - result = cmpsense_gt;
> - break;
> - case -1:
> - result = cmpsense_lt;
> - break;
> - }
> -
> - if (comparetail > comparehead)
> - {
> - /* Restore `-' at tail and move head just past it */
> - *comparetail = '-';
> - comparehead = comparetail + 1;
> - }
> - else
> - {
> - /* Move head to the end of the line (`\0') */
> - comparehead = comparehead + strlen(comparehead);
> - }
> - if (installedtail > installedhead)
> - {
> - /* Restore `-' at tail and move head just past it */
> - *installedtail = '-';
> - installedhead = installedtail + 1;
> - }
> - else
> - {
> - /* Move head to the end of the line (`\0') */
> - installedhead = installedhead + strlen(installedhead);
> - }
> - }
> - }
> -
> - Verbose("Comparison result: %s\n",CMPSENSETEXT[result]);
> -
> - switch(cmp)
> - {
> - case cmpsense_gt:
> - match = (result == cmpsense_gt);
> - break;
> - case cmpsense_ge:
> - match = (result == cmpsense_gt || result == cmpsense_eq);
> - break;
> - case cmpsense_lt:
> - match = (result == cmpsense_lt);
> - break;
> - case cmpsense_le:
> - match = (result == cmpsense_lt || result == cmpsense_eq);
> - break;
> - case cmpsense_eq:
> - match = (result == cmpsense_eq);
> - break;
> - case cmpsense_ne:
> - match = (result != cmpsense_eq);
> - break;
> - }
> -
> - /* If we find a match, just return it now, and don't bother
> checking
> - * other ebuilds */
> + {
>
> - if (match)
> - {
> - DeleteItemList(ebuildlist);
> - return 1;
> - }
> - }
> + Verbose("PortageCheckPackage(): Trying installed version %s\n",
> ebuild->name);
> +
> + /* Run comparison tool to do the grunt work */
> + snprintf(VBUFF,CF_BUFSIZE,"/usr/bin/qatom -cC %s %s-%s", ebuild-
> >name, package, version);
> +
> + if ((pp = cfpopen(VBUFF, "r")) == NULL)
> + {
> + snprintf(OUTPUT,CF_BUFSIZE,"Could not execute the qatom
> command. "
> + "Is portage-utils installed?\n");
> + CfLog(cferror,OUTPUT,"");
> + continue;
> + }
> +
> + if (feof(pp))
> + {
> + snprintf(OUTPUT,CF_BUFSIZE,"Internal error! No output from %
> s.",VBUFF);
> + CfLog(cferror,OUTPUT,"");
> + continue;
> + }
> +
> + /* Format of output is `package < package' */
> + *VBUFF = '\0';
> + ReadLine(VBUFF,CF_BUFSIZE,pp);
> + Verbose("PortagePackageCheck(): Result %s\n",VBUFF);
> + cfpclose(pp);
> +
> + /* Find first space, give up otherwise */
> + result = strchr(VBUFF, ' ');
> + if (result == NULL) continue;
> +
> + /* Relocate to right of space (the comparison symbol) */
> + ++result;
> +
> + switch(cmp)
> + {
> + case cmpsense_gt:
> + match = (*result == *CMPSENSEOPERAND[cmpsense_gt]);
> + break;
> + case cmpsense_ge:
> + match = (*result == *CMPSENSEOPERAND[cmpsense_gt] ||
> + *result == *CMPSENSEOPERAND[cmpsense_eq]);
> + break;
> + case cmpsense_lt:
> + match = (*result == *CMPSENSEOPERAND[cmpsense_lt]);
> + break;
> + case cmpsense_le:
> + match = (*result == *CMPSENSEOPERAND[cmpsense_lt] ||
> + *result == *CMPSENSEOPERAND[cmpsense_eq]);
> + break;
> + case cmpsense_eq:
> + match = (*result == *CMPSENSEOPERAND[cmpsense_eq]);
> + break;
> + case cmpsense_ne:
> + match = (*result != *CMPSENSEOPERAND[cmpsense_eq]);
> + break;
> + }
>
> -/* if we manage to make it out of the loop, we did not find a
> match. */
> + /* Return successful on finding a match */
> + if (match)
> + {
> + DeleteItemList(ebuildlist);
> + return 1;
> + }
> + }
>
> +/* No match found, return false */
> DeleteItemList(ebuildlist);
> return 0;
> }
>
> int PortagePackageList(char *package, char *version, enum cmpsense
> cmp, struct Item **pkglist)
> {
> - return 0; /* not implemented yet */
> +return 0; /* unused! */
> }
>
> /
> *********************************************************************/
>
> --
> Eric Searcy
> OSU Open Source Lab
>
> _______________________________________________
> Bug-cfengine mailing list
> [email protected]
> https://cfengine.org/mailman/listinfo/bug-cfengine
--
Jo Rhett
senior geek
Silicon Valley Colocation
Support Phone: 408-400-0550
_______________________________________________
Bug-cfengine mailing list
[email protected]
https://cfengine.org/mailman/listinfo/bug-cfengine