[TIP] apt cache aufräumen

Alles rund um die Installation Eures Linuxsystems, sowie die Updatefunktionen des Systems und das Paketmanagement

Moderator: Moderatoren

Gesperrt
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
Beiträge: 6506
Registriert: 21. Jun 2004, 13:01

[TIP] apt cache aufräumen

Beitrag von oc2pus » 14. Dez 2004, 13:27

hier mal ein kleines Tool um den apt cache (normalerweise /var/cache/apt/*) etwas aufzuräumen.

Es ist eine Kombination aus einem Python-Script und einem kleinen C-Programm zum Versionsvergleich.
Ich habe diese beiden Tools einfach mal kombiniert :)

Teil 1: Python Script apt-smartclean.py

Code: Alles auswählen

#! /usr/bin/python
#  GPL v2 code. Radim Kolar <hsn/at/cybermail.net>
#  http://home.tiscali.cz/~cz210552/
#  modified for rpm Distris by oc2pus
#
#  APT-SMARTCLEAN
#
#  This programs cleans APT package cache directory. Unlike apt-get autoclean,
#  it leaves in cache directory only last version of package even if this
#  package is no longer available for download. This is less aggressive
#  cleaning than autoclean does.
#
#  ARGUMENTS -s  ... dry run
#
#  Changelog
#
#    VERSION 1 - 18 Aug 2003 First version
#    VERSION 1.1 - 14 Dec 2004 modifications for rpm based distris

import os
import sys

def cleanaptcache(dryrun=0,dirs=('/var/cache/apt/archives/','/var/cache/apt/archives/partial/')):
    for dir in dirs:
       packages={} # versions
       fnames={}   # file names
       for file in os.listdir(dir):
	  if file[-4:] != '.rpm': continue
	  parsed=file.split('_')
	  if len(parsed) != 3: continue
	  parsed[1]=parsed[1].replace('%3a',':')
	  if packages.has_key(parsed[0]):
	      print 'Found',parsed[0],parsed[1],'have',packages[parsed[0]]
              # 1:  a is newer than b
              # 0:  a and b are the same version
              # -1: b is newer than a 
              #  2: wrong arguments number	      
	      argz=['rvc',parsed[1],packages[parsed[0]]]
	      rc=os.spawnvp(os.P_WAIT,'./rvc',argz)
	      if rc==0: 
		 print "skipping",fnames[parsed[0]]
	         continue
	      if rc==255:
		 print "\tDeleting",dir+file
		 if not dryrun: os.unlink(dir+file)
		 continue
	      elif rc==1:
		 print "\tDeleting",dir+fnames[parsed[0]]
		 if not dryrun: os.unlink(dir+fnames[parsed[0]])
		 
	  packages[parsed[0]]=parsed[1]
	  fnames[parsed[0]]=file

if __name__=="__main__":
    sys.stdout.write("Running on SuSE\n")
    sys.stdout.flush()
    if len(sys.argv)>1 and sys.argv[1]=='-s':
	dryrun=1
	print "Dry run is enabled. Not deleting anything."
    else:
	dryrun=0
    cleanaptcache(dryrun)
Teil 2a: C-Programm rvc.c

Code: Alles auswählen

/* 
 * $Id: rvc.c,v 1.5 2002/10/27 18:27:23 luigi Exp $
 ******
 * rvc.c - RPM Version Compare 
 * Given two strings representing a different version and release 
 * of a single rpm package, it returns which one is newer or, 
 * alternatively, an error.
 * 
 * parameters 
 *        two strings (a and b) structured in the following way:
 *        <RPM_version>-<RPM_release>. 
 * 
 * return values
 *        1: a is newer than b
 *        0: a and b are the same version
 *       -1: b is newer than a 
 *        2: wrong arguments number
 * 
 * The assumption the two strings to compare are "logically coherent" 
 * is made, otherwise you will probably end up being told that b is 
 * newer than a (something which happens in this kind of situation)..
 * The rpmvercmp function is "borrowed" from the Redhat package manager 
 * (RPM 4.1), as are all the inline functions in the header file 
 * (rpmvercmp.h).
 *
 ******
 *
 *   Copyright 2002 Luigi Bitonti
 *   
 *   Copyright 2002 Redhat Inc.
 *
 *   This file is part of rvc (RPM version compare).
 *
 *   rvc is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   rvc is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with rvc; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */


#include "rvc.h"


int 
main(int argc, char **argv)
{

    /* We need exactly two arguments for the comparison */
    if (argc != 3)
    {
      fprintf(stderr, "Usage: %s <RPM_versionA>-<RPM_releaseA> <RPM_versionB>-<RPM_releaseB>", argv[0]);
      return 2;
    }

    return rpmvercmp(argv[1], argv[2]);      
}


/* compare alpha and numeric segments of two versions */
/* return 1: a is newer than b */
/*        0: a and b are the same version */
/*       -1: b is newer than a */
int 
rpmvercmp(const char * a, const char * b)
{
    char oldch1, oldch2;
    char * str1, * str2;
    char * one, * two;
    int rc;
    int isnum;

    /* easy comparison to see if versions are identical */
    if (!strcmp(a, b)) return 0;

    str1 = alloca(strlen(a) + 1);
    str2 = alloca(strlen(b) + 1);

    strcpy(str1, a);
    strcpy(str2, b);

    one = str1;
    two = str2;

    /* loop through each version segment of str1 and str2 and compare them */
    while (*one && *two)
    {
	while (*one && !xisalnum(*one)) one++;
	while (*two && !xisalnum(*two)) two++;

	str1 = one;
	str2 = two;

	/* grab first completely alpha or completely numeric segment */
	/* leave one and two pointing to the start of the alpha or numeric */
	/* segment and walk str1 and str2 to end of segment */
	if (xisdigit(*str1))
	{
	    while (*str1 && xisdigit(*str1)) str1++;
	    while (*str2 && xisdigit(*str2)) str2++;
	    isnum = 1;
	} else {
	    while (*str1 && xisalpha(*str1)) str1++;
	    while (*str2 && xisalpha(*str2)) str2++;
	    isnum = 0;
	}

	/* save character at the end of the alpha or numeric segment */
	/* so that they can be restored after the comparison */
	oldch1 = *str1;
	*str1 = '\0';
	oldch2 = *str2;
	*str2 = '\0';

	/* take care of the case where the two version segments are */
	/* different types: one numeric, the other alpha (i.e. empty) */
	if (one == str1) return -1;	/* arbitrary */
	if (two == str2) return -1;

	if (isnum)
	{
	    /* this used to be done by converting the digit segments */
	    /* to ints using atoi() - it's changed because long  */
	    /* digit segments can overflow an int - this should fix that. */

	    /* throw away any leading zeros - it's a number, right? */
	    while (*one == '0') one++;
	    while (*two == '0') two++;

	    /* whichever number has more digits wins */
	    if (strlen(one) > strlen(two)) return 1;
	    if (strlen(two) > strlen(one)) return -1;
	}

	/* strcmp will return which one is greater - even if the two */
	/* segments are alpha or if they are numeric.  don't return  */
	/* if they are equal because there might be more segments to */
	/* compare */
	rc = strcmp(one, two);
	if (rc < 0) 
	    return -1;
	else if (rc > 0)
	    return 1;

	/* restore character that was replaced by null above */
	*str1 = oldch1;
	one = str1;
	*str2 = oldch2;
	two = str2;
    }

    /* this catches the case where all numeric and alpha segments have */
    /* compared identically but the segment sepparating characters were */
    /* different */
    if ((!*one) && (!*two)) return 0;

    /* whichever version still has characters left over wins */
    if (!*one) return -1; else return 1;
}
Teil 2b: rvc.h

Code: Alles auswählen

/*
 * $Id: rvc.h,v 1.4 2002/10/27 18:28:00 luigi Exp $
 **
 * rvc.h - include file for rvc.c
 *
 *   Copyright 2002 Luigi Bitonti
 *   
 *   Copyright 2002 Redhat Inc.
 *
 *   This file is part of rvc (RPM version compare).
 *
 *   rvc is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   rvc is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with rvc; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>


int rpmvercmp(const char *, const char *);


static inline int xislower(int c) {
    return (c >= 'a' && c <= 'z');
}

static inline int xisupper(int c) {
    return (c >= 'A' && c <= 'Z');
}

static inline int xisalpha(int c) {
    return (xislower(c) || xisupper(c));
}

static inline int xisdigit(int c) {
    return (c >= '0' && c <= '9');
}

static inline int xisalnum(int c) {
    return (xisalpha(c) || xisdigit(c));
}

static inline int xisblank(int c) {
    return (c == ' ' || c == '\t');
}

static inline int xisspace(int c) {
    return (xisblank(c) || c == '\n' || c == '\r' || c == '\f' || c == '\v');
}

static inline int xtolower(int c) {
    return ((xisupper(c)) ? (c | ('a' - 'A')) : c);
}

static inline int xtoupper(int c) {
    return ((xislower(c)) ? (c & ~('a' - 'A')) : c);
}
Teil 2c: Makefile

Code: Alles auswählen

# $Id: Makefile,v 1.2 2003/03/06 17:54:19 luigi Exp $
# Makefile for rvc (RPM version compare)

CC = gcc
CFLAGS = -Wall

all : rvc

rvc : rvc.c  rvc.h
	${CC}  ${CFLAGS}  -o  $@  $<

Installation:
Das C-Programm wird umgewandelt mit dem Aufruf make. Dadurch wird ein Programm rvc erstellt.
Wer seinen apt-cache in einem anderen Verzeichnis stehen hat als /var/apt/cache sollte in dem Python-Script den Pfad anpassen.
Beide Programmteile dann nach /usr/local/bin kopieren
cp rvc /usr/local/bin
cp apt-smartclean.py /usr/local/bin

Der Aufruf

Code: Alles auswählen

apt-smartclean.py -s
zeigt an was obsolet im Cache rumsteht. Mit dem Aufruf

Code: Alles auswählen

apt-smartclean.py
werden die obsoleten RPMs aus dem cache gelöscht.

Ich finde ein schönes Beispiel wie man zwei vorhandene Tools einfach kombiniert und schnell ein brauchbares Ergebnis erzielt.

Dieses Script hat für mich wunderbar funktioniert. Aber ich übernehme keine Haftung für die Anwendung und evtl Schäden an eurem System.
Zuletzt geändert von oc2pus am 17. Jan 2005, 16:40, insgesamt 4-mal geändert.
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User

Werbung:
Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
Beiträge: 6506
Registriert: 21. Jun 2004, 13:01

Beitrag von oc2pus » 15. Dez 2004, 13:18

Hier noch eine Alternative:

1.) Download des Python-Scriptes von hier:
http://home.tiscali.cz:8080/~cz210552/d ... rtclean.py

2.) diesen Patch als apt-smartclean-rpm.diff abspeichern:

Code: Alles auswählen

--- apt-smartclean.py   2004-12-15 11:29:45.384724472 +0100
+++ apt-smartclean-rpm.py       2004-12-15 11:30:28.928104872 +0100
@@ -24,7 +24,7 @@
        packages={} # versions
        fnames={}   # file names
        for file in os.listdir(dir):
-         if file[-4:] != '.deb': continue
+         if file[-4:] != '.rpm': continue
          parsed=file.split('_')
          if len(parsed) != 3: continue
          parsed[1]=parsed[1].replace('%3a',':')
@@ -47,7 +47,7 @@

 if __name__=="__main__":
     #working dpkg test
-    sys.stdout.write("Running on Debian-")
+    sys.stdout.write("Running on SuSE-")
     sys.stdout.flush()
     rc=os.spawnlp(os.P_WAIT,'dpkg','dpkg','--print-architecture')
     if rc!=0:
3.) mit patch -p0 < apt-smartclean-rpm.diff das Script patchen
damit wird das portierte dpkg von debian für den Versionsvergleich genutzt.

4.) mit apt install deb das Paket deb installieren

5.) apt-smartclean.py installieren
cp apt-smartclean.py /usr/local/bin
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User

Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
Beiträge: 6506
Registriert: 21. Jun 2004, 13:01

Beitrag von oc2pus » 15. Dez 2004, 18:49

Zuletzt geändert von oc2pus am 19. Jul 2006, 17:49, insgesamt 3-mal geändert.
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User

Benutzeravatar
michael_33
Member
Member
Beiträge: 70
Registriert: 20. Jul 2004, 09:58

Beitrag von michael_33 » 22. Dez 2004, 16:01

Hallo,

kannst Du das bitte noch für suse9.0 reinstellen, dann kann ich es nähmlich auch gebrauchen ... 8)

thx
michael
.| 2.6.15-gentoo-r1 | .. fluxbox 0.9.14 ..|.
.| AMD Athlon(tm) XP 2400+ | GSA-4040B | Elitegroup K7S5A | Matrox Millennium G400 |.

Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
Beiträge: 6506
Registriert: 21. Jun 2004, 13:01

Beitrag von oc2pus » 22. Dez 2004, 16:20

michael_33 hat geschrieben:kannst Du das bitte noch für suse9.0 reinstellen, dann kann ich es nähmlich auch gebrauchen ... 8)
nein kann ich leider nicht ;)
aber da es ein noarch.rpm ist, kannst du es downloaden und manuell installieren.

oder du nimmst das src.rpm und wandelst es in ein rpm um für 9.0

oder du kopierst die sourcen von oben ...
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User

Benutzeravatar
Tux-Manni
Member
Member
Beiträge: 172
Registriert: 12. Jun 2004, 18:46
Wohnort: Ludwigsburg

Beitrag von Tux-Manni » 22. Jan 2005, 18:54

Hallo

Gibt es ev eine readme zu apt-smartclean? Hab es per apt installiert, inklusive deb. Allerdings scheint das nicht zu laufen.
Oder fehlt dazu noch etwas?
Zum anderen: reicht nicht auch ein rm /var/cache/apt/archives/*.rpm ?

Danke für Aufklärung
Manni
Suse 10 / KDE 3.5.1 Level "a"
Kernel 2.6.13-15.8-default
xorg 6.9.0-3.1
Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.7.12) Gecko/20050920 Firefox/1.0.7 SUSE/1.0.7-0.1

Benutzeravatar
oc2pus
Ultimate Guru
Ultimate Guru
Beiträge: 6506
Registriert: 21. Jun 2004, 13:01

Beitrag von oc2pus » 23. Jan 2005, 09:45

Tux-Manni hat geschrieben:Gibt es ev eine readme zu apt-smartclean? Hab es per apt installiert, inklusive deb. Allerdings scheint das nicht zu laufen.
Oder fehlt dazu noch etwas?
Zum anderen: reicht nicht auch ein rm /var/cache/apt/archives/*.rpm ?
nein gibt es nicht. Wofür auch ...
apt-smartclean -s ==> Simulation, was entfernt würde
apt-smartclean ==> es wird gelöscht

apt-smartclean sorgt dafür das im Cache die jeweils aktuellste RPM Version übrigbleibt, unabhängig davon ob apt diese Version noch erreichen kann auf einem Server!

rm /var/cache/apt/archives/*.rpm löscht alles im cache. Nette Idee, aber mach dir mal den Sinn eines cache klar ;)
tell people what you want to do, and they'll probably help you to do it.
PackMan
LinWiki : Das Wiki für Linux User

Gesperrt

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste