Добавить в избранное | Сделать стартовой страницей

Большая Linux библиотека для пользователей OS Linux и ПО для нее
Есть что сказать? Нужен совет? Посети наш форум.


При поддержке
Продвижение сайта
Создание сайта
Администрирование сервера
настройка сервера
Администрирование сервера
настройка сервера
Администрирование сервера
аренда сервера


Как я обновлял дистрибутив по диалапу.

Автор : Sir Raorn

0. Intro...

После покупки нового домашнего компа захотелось поставить на него последнего Сизифа. Spring2001 взлетел просто на ура (cusl2-c bp на i815ep), с работы я принес свое зеркало Sisyphus'а, apt-get dist-upgrade и можно считать, что жизнь удалась.

Прошло недели две, в Сизифе появилось много новых обновлений, но тащить опять домой полное дерево, да еще и на чужом винте не очень весело, тащить свой комп на работу тоже не хотелось. Остается диалап, но на 1200 мне пришлось бы обновляться лет триста. На работе есть CD-RW, к которой у меня неограниченный доступ, и 700-метровая RW болванка, на которую при всем желании не поместится четыре с половиной гига Сизифа.

Итак, учитывая, что Сизиф - не просто свалка файлов, а репозитарий пакетов, и меня в основном интересуют только каталоги RPMS и SRPMS, у меня получились такие исходные данные:

  • есть два дерева - "старое" и "новое", требуется "старое" дерево обновить до "нового".
  • дома и на работе зеркало сизифа лежит в одном месте, у меня это /var/ftp/pub/distributions/ALTLinux/{Sisyphus,updates,etc...}
  • два файла с одинаковыми именами считаются одинаковыми.
  • при обновлении какого-нибудь пакета, "старый" файл удаляется, и вместо него появляется "новый".
  • файлы base/* обновляются всегда.

1. Дома. Часть первая.

Для начала надо узнать, что конкретно находится дома, для этого я воспользовался такой командой:

$ tree -afin /var/ftp/pub/distributions/ALTLinux | grep ^/ | sort > home.list

После чего home.list был благополучно унесен на работу.

2. На работе.

Выясним, что же у нас творится с Сизифом:

$ tree -afin /var/ftp/pub/distributions/ALTLinux | grep ^/ | sort > current.list

Теперь надо узнать, что появилось нового и что пропало старого. Для этого вполне подойдет diff (так как патч мы никуда накладывать не будем, зафиксируем только изменения):

$ diff -U0 home.list current.list > distrib.diff

В файле distrib.diff то, "старые" файлы идут с префиксом '-', а "новые" - с префиксом "+". Рисуем простенький фильтр на перле:

#!/usr/bin/perl

open NEW, ">newfiles" or die;
open OLD, ">oldfiles" or die;

while(<>) {
        chomp;
        ($w, $f) = ($_ =~ /(.)(\S+)/);
        next if $w !~ /[+-]/;
        next if $f !~ /^\//;
        if ($w =~ /-/) {
                print OLD $f."\n";
        } else {
                print NEW $f."\n";
        }
}

close OLD;
close NEW;

... и скармливаем ему наш distrib.diff. Таким образом в файле oldfiles у нас то, что надо дома удалить, а в newfiles то, что надо тыда скопировать.

Копируем:

$ tar cPf updates.tar `cat newfiles`

... и base/*

$ tar cPf base.tar /var/ftp/pub/distributions/ALTLinux/Sisyphus/i586/Mandrake/base/*

После чего updates.tar, base.tar и oldfiles записываются на болванку и благополучно уносятся домой.

3. Дома. Часть вторая.

Монтируем диск...

$ mount /mnt/cdrom
$ cd /mnt/cdrom

... и рутом удаляем "старые файлы"...

$ su
Password:
# rm -f `cat oldfiles`
# rm -f /var/ftp/pub/distributions/ALTLinux/Sisyphus/i586/Mandrake/base/*

... а потом копируем "новые":

# tar xPf updates.tar
# tar xPf base.tar

После чего apt-get update && apt-get dist-upgrade и вуаля :-)

4. Занимаемся оптимизьмом...

Юниксоиды - народ ленивый, им проще потратить два часа на написание скрипта, который за две минуты сделает получасовую работу.

Все-таки, что делать, если мы хотим точное зеркало, причем неизвестно, сколько у нас разных base/*? Возьмем вместо tree... find и md5sum:

$ find /var/ftp/pub/distributions/ALTLinux -type f -print | sort | xargs md5sum > home.list

... это дома...

$ find /var/ftp/pub/distributions/ALTLinux -type f -print | sort | xargs md5sum > current.list

... а это на работе. И соответственно изменим genlists.pl:

-   ($w, $f) = ($_ =~ /(.)(\S+)/);
+       ($w, $f) = ($_ =~ /(.)[0-9a-f]{32}\s+(\S+)/);

таким образом у нас получилась "оффлайновая версия" rsync :-)

5. Избавляемся от временных файлов.

Вот за что я люблю *никс, так это за длинные команды с кучей пайпов :-) "На работе" вместо создания current.list перенаправим вывод find сразу на diff, с diff'а на наш скрипт genlists (в виде perl -e '' :-), в скрипте вместо создания newfiles будем печатать их на stdout и отдадим сразу tar'у.

А чтобы "дома" не создавать файллист руками, добавим в скрипт парочку command-line параметров :-)

#!/bin/sh

Usage() {
        cat <&2
fi

file=""
dir=""
what=""

case "$1" in
        --genlist)
                what="list";
                shift
                ;;
        --genupdate)
                what="update";
                shift
                ;;
        *)
                Usage 1 1>&2
                ;;
esac

file="$1"
dir="$2"

case $what in
        list)
                find "$dir" -type f -print | \
                sort | \
                xargs md5sum > "$file"
                ;;
        update)
                find /var/ftp/pub/distributions/ALTLinux -type f -print | \
                sort | \
                xargs md5sum | \
                diff -U0 "$file" - | \
                perl -e '
open OLD, ">rmold.sh" or die;
print OLD "#!/bin/sh\n";

while(<>) {
        chomp;
        ($w, $f) = ($_ =~ /(.)[0-9a-f]{32}\s+(\S+)/);
        next if $w !~ /[+-]/;
        if ($w =~ /-/) {
                print OLD "rm -f ".$f."\n";
        } else {
                print $f."\n";
        }
}

close OLD;
' | \
                tar cPf update.tar -T -
                ;;
esac

Ну а если мы хотим совсем универсальный скрипт для "оффлайнового rsync'а", то после xargs md5sum можно воткнуть sed -e 's# $dir# #', но это уже будет домашним заданием :-)


Верхняя Пышма | межкомнатные двери, распродажа