_                               _           
(_)_ __ ___  _ __ ___  _   _  __| | _____  __
| | '_ ` _ \| '_ ` _ \| | | |/ _` |/ _ \ \/ /
| | | | | | | | | | | | |_| | (_| |  __/>  < 
|_|_| |_| |_|_| |_| |_|\__,_|\__,_|\___/_/\_\

Skrypt aktualizacji - plik wersji

Zmiany wprowadzane do immudex są rozpisywane w postaci skryptu. Program ten nazwany jest plikiem wersji, ze względu na to, że jego nazwą jest numer kolejnej wersji dystrybucji. Pliki wersji są tworzone od momentu pierwszych poprawek, aż do daty wydania tej wersji systemu. Plik wersji składa się z definicji funkcji, które poźniej są wkorzystywane do utworzenia listy instrukcji, która wprowadzi wszystkie zmiany przeznaczone dla tej wersji immudex. Poniżej znajduje się przykładowy plik wersji (testing, wersja 0.1.9).

#!/bin/bash

function update_packages() {
  dhclient; 
  apt update;
  apt upgrade -y;
}

function install_packages() {
  apt install $@ -y;
}

function get_immudex_testing_project() {
  if [ ! -d ~/immudex-testing ]; then
    cd;
    git clone https://github.com/xf0r3m/immudex-testing.git;
  fi
}

function recreate_users() {
  userdel -r user;
  userdel -r xf0r3m;

  useradd -m -s /bin/bash user;
  if [ ! -f /home/user/.vimrc ]; then
    cp -rvv /etc/skel/.??* /home/user;
    cp -rvv /etc/skel/?* /home/user;
    mkdir /home/user/.local;
    tar -xvf ~/immudex-testing/files/017/local_user.tar -C /home/user/.local;
    rm /home/user/.face;
    cp /usr/share/images/desktop-base/immudex_xfce_greeter_logo.png /home/user/.face;
    chown -R user:user /home/user;
  fi
  echo "user:user1" | chpasswd;

  useradd -m -s /bin/bash xf0r3m;
  if [ ! -f /home/xf0r3m/.vimrc ]; then
    cp -rvv /etc/skel/.??* /home/xf0r3m;
    cp -rvv /etc/skel/?* /home/xf0r3m;
    mkdir /home/xf0r3m/.local;
    tar -xvf ~/immudex-testing/files/017/local_xf0r3m.tar -C /home/xf0r3m/.local;
    rm /home/xf0r3m/.face;
    cp /usr/share/images/desktop-base/immudex_xfce_greeter_logo.png /home/xf0r3m/.face;
    chown -R xf0r3m:xf0r3m /home/xf0r3m;
  fi
  echo "xf0r3m:xf0r3m1" | chpasswd;

  usermod -aG libvirt,libvirt-qemu xf0r3m;
  usermod -aG libvirt,libvirt-qemu user;
}

function tidy() {
  apt-get clean;
  apt-get clean;
  apt-get autoremove -y;
  apt-get autoclean;
  rm -rf ~/immudex-testing;
  echo > ~/.bash_history;
  history -c   
}

function set_default_wallpaper() {
  rm /usr/share/images/desktop-base/default;
  ln -s /usr/share/images/desktop-base/$1 /usr/share/images/desktop-base/default;
}

function set_notifier_packages() {
  cp -vv ~/immudex-testing/files/011/Notifier\ -\ packages.desktop /home/xf0r3m/.config/autostart;
  chown xf0r3m:xf0r3m /home/xf0r3m/.config/autostart/Notifier\ -\ packages.desktop;
}

VERSION=$(echo $0 | cut -d "." -f 1);
if [ ! "$VERSION" ]; then echo -e "\e[31mUpdate failed!\e[0m"; exit 1; fi;

update_packages;
install_packages gimp isolinux;

get_immudex_testing_project;

cp -vv ~/immudex-testing/images/${VERSION}/abandoned_hospital_bower.png /usr/share/images/desktop-base;

sed -i 's/no_trespass_abandon.jpeg/abandoned_hospital_bower.png/' /etc/lightdm/lightdm-gtk-greeter.conf;

rm /etc/apt/source.list;

tidy;

Niektóre pliki wersji mogą być bardzo ubogie. Zawierać dwie trzy instrukcje i to dzięki użyciu funkcji, w których zawarto typowe i powtarzalne czynności wykowane podczas każdej aktualizacji, takie jak aktualizacja zainstalowanego oprogramowania czy posprzątanie po sobie. Po warunku określającym, czy aktualizacj w ogóle powiedzie się if [ ! "$VERSION ];... rozpoczyna się seria czynności definiujących tę wersję systemu.

Uruchomienia tego pliku dokonuje się w środowisku zmienionego katalogu głónego, po przez wywołanie powłoki BASH, podając ten plik jako argument. Na przykład:

$ sudo chroot immudex-testing/64/chroot bash 019.sh

Przyglądając się temu strukturze tego skryptu, od razu rzuca się w oczy potencjał optymalizacyjny. Na początku musimy sobie jednak odpowiedzieć na jedno pytanie. Skąd biorą się te definicje funkcji? Definicje funkcji są składowane wraz plikami wersji w tym samym katalogu pod postacią pliku szablonu (template.sh). To jeśli definicje znajdują się w odrębnym pliku to zamiast je kopiować można je przecież załadować do pliku za pomocą polecenia source lub instrukcji kropki (.). Tu pojawia się problem, którego wolelibyśmy uniknąć a mianowicie kopiowana kolejnych plików do rootfs. I go unikniemy wykorzystując to co już mamy dostępne.

Zamiast zaczynać plik serii definicji funkcji, pobierzemy je z repozytorium:

dhclient;
cd;
if [ -x /usr/bin/git ]; then git clone https://github.com/xf0r3m/immudex-testing.git;
else apt install git && git clone https://github.com/xf0r3m/immudex-testing.git;
fi

Teraz plik szablonu (plik z definicjami) możemy załadować do pliku wersji.

source ~/immudex-testing/versions/template.sh;

Teraz od tej linii rozpoczyna się plik wersji. Warto też dodać, że funkcja odpowiedzialna za sklonowanie repozytorium przestaje być potrzebna, ponieważ zrobi to teraz każdy plik wersji na początku wykonania. Warto dopisać do początku polecenie dhclient aby odświerzyć połączenie sieciowe. Przedstawiony na początku materiału przykład po optymalizacji prezentuje się w taki o to sposób.

dhclient;
cd;
if [ -x /usr/bin/git ]; then git clone https://github.com/xf0r3m/immudex-testing.git;
else apt install git && git clone https://github.com/xf0r3m/immudex-testing.git;
fi
source ~/immudex-testing/versions/template.sh;
update_packages;
install_packages gimp isolinux;

cp -vv ~/immudex-testing/images/${VERSION}/abandoned_hospital_bower.png /usr/share/images/desktop-base;

sed -i 's/no_trespass_abandon.jpeg/abandoned_hospital_bower.png/' /etc/lightdm/lightdm-gtk-greeter.conf;

rm /etc/apt/source.list;

tidy;

Podsumowując pliki wersji to nic innego jak skrypty, które wdrażają zmiany przeznaczone dla tej wersji systemu.

~xf0r3m