kitoy.me/public/sauvegarde-orangepi/index.html

581 lines
59 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="/base.css" type="text/css">
<title> kitoy.me </title>
<title> kitoy.me </title>
</head>
<body>
<div class="title">
<h1 style="text-align:center;"> kitoy.me </h1>
</div>
<div class="menugauche">
<div class="toggle" id="toggle" onclick="menu-expand()">
<h2 id="plus"> Menu </h2>
</div>
<div class="menu" id="menu">
<a href="https:&#x2F;&#x2F;kitoy.me">
<img src="/img/Blog-icon.svg" alt="Le blog" />
<p> Le blog </p>
</a>
<a href="https:&#x2F;&#x2F;losprimos.eu">
<img src="/img/music.svg" alt="Le blog" />
<p> Azul </p>
</a>
<a href="https:&#x2F;&#x2F;kitoy.me/rss.xml">
<img src="/img/resese.svg" alt="Suivez le blog par RSS" />
<p> RSS </p>
</a>
<a href="https:&#x2F;&#x2F;kitoy.me/contact/">
<img src="/img/mail.svg" alt="Contact" />
<p> Me contacter </p>
</a>
</div>
</div>
<div class="articles">
<h1> Sauvegarde système de l&#x27;Orangepi sous debian&#x2F;yunohost. </h1>
<h2 class="description">
Sauvegarder le système de sa carte ARM OrangePi avec debian sur clé usb
</h2>
<hr />
<h3 id="le-probleme">Le problème</h3>
<p>Ou plutôt les problèmes, car il peut y en avoir plusieurs; par exemple le
système sur la carte ne boot plus. On a fait une bêtise, on la débranché car on
a voulu la déplacer ou le fil s'est débranché par accident, et aller cette fois
là c'est la galère. C'est généralement long et fastidieux de récupérer les
données sur sa carte SD ou autre, j'ai donc fait un script qui fait une
sauvegarde globale du système sur un disque ou une clé usb que l'on devra
autoriser auparavant, histoire que dès que l'on branche une clé usb, ça n'envoie
pas les données dessus. Il y a bien évidement des solutions de sauvegarde en
ligne mais ayant une connexion avec peu de débit, ça peut prendre beaucoup de
temps, la connexion peut couper et alors c'est des complications, pour moi ce n'était pas très adapté.</p>
<h3 id="le-principe">Le principe</h3>
<p>Le principe c'est que le script a deux fonctionnalitées
Une pour ajouter les supports de stockages où la sauvegarde sera envoyé. Le script formate la partition et il ajoute l'UUID à la liste des clés ou disques autorisé a recevoir les données. Pour l'utiliser on lancera la commande ./saveonmedia create
Une pour écouter avec udev les medias branchés et réaliser la sauvegarde quand elle reconnaît L'UUID d'un disque. On lancera la commande ./saveonmedia make
Pour la liste, un bête fichier texte suffit pour ajouter les supports de stockage lignes par lignes, on se basera sur les UUID des partitions sur le disque qui sont normalement identifier de manière unique. Pour réaliser la sauvegarde le script lancera un script bash qui est généralement plus pratique si l'on veut ajouter des taches à effectuer ou personnaliser le truc un peu comme on veut.</p>
<pre style="background-color:#272822;">
<span style="color:#f8f8f2;">
</span><span style="color:#75715e;">#!/usr/bin/python3
# -*- coding: utf-8 -*-
</span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">pyudev
</span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">subprocess
</span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">sys
</span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">os
</span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">socket
</span><span style="color:#f92672;">from </span><span style="color:#f8f8f2;">email.mime.text </span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">MIMEText
</span><span style="color:#f92672;">from </span><span style="color:#f8f8f2;">subprocess </span><span style="color:#f92672;">import </span><span style="color:#f8f8f2;">Popen, PIPE
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">print_help</span><span style="color:#f8f8f2;">():
</span><span style="color:#66d9ef;">print </span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;&quot;&quot;
##### saveonusb Sauvergarde sur support USB ####
! A executer avec l&#39;utilisateur avec des droits root (sudo) ou en root !
Pour autoriser un disque (clé usb, disque usb)
Lancez la commande :
./saveonusb create
Pour effectuer l&#39;ecoute puis la sauvegarde:
./saveonusb make
&quot;&quot;&quot;</span><span style="color:#f8f8f2;">)
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">send_msg</span><span style="color:#f8f8f2;">(</span><span style="font-style:italic;color:#fd971f;">subject</span><span style="color:#f8f8f2;">, </span><span style="font-style:italic;color:#fd971f;">message</span><span style="color:#f8f8f2;">):
</span><span style="color:#75715e;"># Permet d&#39;envoyer des mail a root via sendmail.
</span><span style="color:#f8f8f2;">msg </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">MIMEText(message)
msg[</span><span style="color:#e6db74;">&quot;From&quot;</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;sauvegarde@&quot;</span><span style="color:#f92672;">+</span><span style="color:#f8f8f2;">socket.gethostname()
msg[</span><span style="color:#e6db74;">&quot;To&quot;</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;root@&quot;</span><span style="color:#f92672;">+</span><span style="color:#f8f8f2;">socket.gethostname()
msg[</span><span style="color:#e6db74;">&quot;Subject&quot;</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subject
p </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">Popen([</span><span style="color:#e6db74;">&quot;/usr/sbin/sendmail&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#e6db74;">&quot;-t&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#e6db74;">&quot;-oi&quot;</span><span style="color:#f8f8f2;">], </span><span style="font-style:italic;color:#fd971f;">stdin</span><span style="color:#f92672;">=</span><span style="color:#f8f8f2;">PIPE, </span><span style="font-style:italic;color:#fd971f;">universal_newlines</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">True</span><span style="color:#f8f8f2;">)
p.communicate(msg.as_string())
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">clean_df_out</span><span style="color:#f8f8f2;">(</span><span style="font-style:italic;color:#fd971f;">df_out</span><span style="color:#f8f8f2;">):
</span><span style="color:#75715e;"># Ici on tri les enleve les partitions de la sortir de df qui ne sont pas des supports
# de stockages
#
</span><span style="color:#f8f8f2;">df_out </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">df_out.split(</span><span style="color:#e6db74;">&#39;</span><span style="color:#ae81ff;">\n</span><span style="color:#e6db74;">&#39;</span><span style="color:#f8f8f2;">)
lines</span><span style="color:#f92672;">=</span><span style="color:#f8f8f2;">[]
</span><span style="color:#f92672;">for </span><span style="color:#f8f8f2;">line </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">df_out:
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">line[</span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:</span><span style="color:#ae81ff;">4</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&#39;/dev&#39;</span><span style="color:#f8f8f2;">:
lines.append(line)
line_clean </span><span style="color:#f92672;">= </span><span style="font-style:italic;color:#66d9ef;">list</span><span style="color:#f8f8f2;">()
lines_clean </span><span style="color:#f92672;">= </span><span style="font-style:italic;color:#66d9ef;">list</span><span style="color:#f8f8f2;">()
</span><span style="color:#75715e;"># On crée la liste des champs de df
</span><span style="color:#f92672;">for </span><span style="color:#f8f8f2;">line </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">lines:
line </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">line.split(</span><span style="color:#e6db74;">&#39; &#39;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">for </span><span style="color:#f8f8f2;">champ </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">line:
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">champ </span><span style="color:#f92672;">!= </span><span style="color:#e6db74;">&#39;&#39;</span><span style="color:#f8f8f2;">:
line_clean.append(champ)
lines_clean.append(line_clean.copy())
line_clean.clear()
</span><span style="color:#f92672;">return </span><span style="color:#f8f8f2;">lines_clean
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">getMinSpaceRequirement</span><span style="color:#f8f8f2;">():
</span><span style="color:#75715e;"># df -k A ce schema de sorti
# Filesystem | 1K-blocks | Used | Avail | Capacity | Mounted on
#
# Pour obtenir l&#39;espace minimum on suppose que l&#39;on veut sauvegarder toutes les
# données de tout les supports de stockages.
</span><span style="color:#f8f8f2;">df </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.check_output([</span><span style="color:#e6db74;">&#39;/bin/df&#39;</span><span style="color:#f8f8f2;">, </span><span style="color:#e6db74;">&#39;-k&#39;</span><span style="color:#f8f8f2;">]).decode(</span><span style="color:#e6db74;">&#39;utf8&#39;</span><span style="color:#f8f8f2;">)
df_list </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">clean_df_out(df)
</span><span style="color:#66d9ef;">print </span><span style="color:#f8f8f2;">(df_list)
space_used </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">0
</span><span style="color:#f92672;">for </span><span style="color:#f8f8f2;">line </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">df_list:
space_used </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">space_used </span><span style="color:#f92672;">+ </span><span style="font-style:italic;color:#66d9ef;">int</span><span style="color:#f8f8f2;">(line[</span><span style="color:#ae81ff;">2</span><span style="color:#f8f8f2;">])
</span><span style="color:#f92672;">return </span><span style="color:#f8f8f2;">space_used
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">get_uuid</span><span style="color:#f8f8f2;">(</span><span style="font-style:italic;color:#fd971f;">device</span><span style="color:#f8f8f2;">):
cmd </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.check_output([</span><span style="color:#e6db74;">&#39;sudo&#39;</span><span style="color:#f8f8f2;">, </span><span style="color:#e6db74;">&#39;blkid&#39;</span><span style="color:#f8f8f2;">, device])
cmd </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">cmd.decode(</span><span style="color:#e6db74;">&#39;utf-8&#39;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">for </span><span style="color:#f8f8f2;">line </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">cmd.split(</span><span style="color:#e6db74;">&#39; &#39;</span><span style="color:#f8f8f2;">):
</span><span style="color:#f92672;">if </span><span style="color:#e6db74;">&#39;UUID=&#39; </span><span style="color:#f92672;">== </span><span style="color:#f8f8f2;">line[</span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:</span><span style="color:#ae81ff;">5</span><span style="color:#f8f8f2;">]:
</span><span style="color:#f92672;">return </span><span style="color:#f8f8f2;">line[</span><span style="color:#ae81ff;">6</span><span style="color:#f8f8f2;">:</span><span style="color:#66d9ef;">len</span><span style="color:#f8f8f2;">(line)</span><span style="color:#f92672;">-</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">]
</span><span style="color:#f92672;">return </span><span style="color:#e6db74;">&#39;&#39;
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">make_save</span><span style="color:#f8f8f2;">(</span><span style="font-style:italic;color:#fd971f;">save_directory</span><span style="color:#f8f8f2;">, </span><span style="font-style:italic;color:#fd971f;">storages</span><span style="color:#f8f8f2;">):
context </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">pyudev.Context()
monitor </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">pyudev.Monitor.from_netlink(context)
monitor.filter_by(</span><span style="color:#e6db74;">&#39;block&#39;</span><span style="color:#f8f8f2;">)
done </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">False
</span><span style="color:#f92672;">with </span><span style="color:#66d9ef;">open </span><span style="color:#f8f8f2;">(storages, </span><span style="color:#e6db74;">&#39;r&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">as </span><span style="color:#f8f8f2;">f:
medias_save </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">f.read().splitlines()
</span><span style="color:#f92672;">while not</span><span style="color:#f8f8f2;">(done):
device </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">monitor.poll()
</span><span style="color:#f92672;">if </span><span style="color:#e6db74;">&#39;ID_FS_TYPE&#39; </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">device </span><span style="color:#f92672;">and </span><span style="color:#f8f8f2;">device.action </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&quot;add&quot;</span><span style="color:#f8f8f2;">:
</span><span style="color:#66d9ef;">print </span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;device: </span><span style="color:#ae81ff;">{0}</span><span style="color:#e6db74;"> medias: </span><span style="color:#ae81ff;">{1}</span><span style="color:#e6db74;">&quot;</span><span style="color:#f8f8f2;">.format(device.get(</span><span style="color:#e6db74;">&#39;ID_FS_UUID&#39;</span><span style="color:#f8f8f2;">), medias_save))
</span><span style="color:#f92672;">if </span><span style="color:#e6db74;">&quot;ynh_save&quot; </span><span style="color:#f92672;">== </span><span style="color:#f8f8f2;">device.get(</span><span style="color:#e6db74;">&#39;ID_FS_LABEL&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">and </span><span style="color:#f8f8f2;">device.get(</span><span style="color:#e6db74;">&#39;ID_FS_UUID&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">medias_save:
</span><span style="color:#66d9ef;">print </span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;La sauvegarde a commencé&quot;</span><span style="color:#f8f8f2;">)
send_msg(</span><span style="color:#e6db74;">&quot;Une sauvegarde a été lancé&quot;</span><span style="color:#f8f8f2;">,</span><span style="color:#e6db74;">&quot;Ne retirez pas votre disque ou clé usb. Merçi.&quot;</span><span style="color:#f8f8f2;">)
retcode </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.call(</span><span style="color:#e6db74;">&quot;mount &quot; </span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">device.device_node </span><span style="color:#f92672;">+ </span><span style="color:#e6db74;">&quot; &quot;</span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">save_directory, </span><span style="font-style:italic;color:#fd971f;">shell</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">True</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">retcode </span><span style="color:#f92672;">!= </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Bon ... ça s&#39;est mal passé&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot;Impossible de monter la clé USB :( &quot;&quot;&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
retcode </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.call( save_script </span><span style="color:#f92672;">+ </span><span style="color:#e6db74;">&quot; &quot; </span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">save_directory, </span><span style="font-style:italic;color:#fd971f;">shell</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">True</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">retcode </span><span style="color:#f92672;">!= </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Bon ... ça s&#39;est mal passé&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot;Le script de sauvegarde a remonté une erreur,
comment dire ... je le ferai autrement moi &quot;&quot;&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
retcode </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.call(</span><span style="color:#e6db74;">&quot;umount &quot; </span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">device.device_node, </span><span style="font-style:italic;color:#fd971f;">shell</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">True</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">retcode </span><span style="color:#f92672;">!= </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Bon ... ça s&#39;est a peu près bien passé&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot;Ça a monté le support et tout, le script pas de problèmes,
mais ca démonte pas le support correctement le script ne peut rien faire seul vous pouvez
voir ce qu&#39;il se passe&quot;&quot;&quot;
</span><span style="color:#f92672;">else</span><span style="color:#f8f8f2;">:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Confirmation de sauvegarde&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot;Votre sauvegarde est prête vous pouvez retirer votre
support de stockage en toute sécurité. Rebranchez ce même support quand vous
souhaitez effectuer une sauvergarde. Attention! Toutes modifications de la partiton
rendra le support invalide&quot;&quot;&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
</span><span style="font-style:italic;color:#66d9ef;">def </span><span style="color:#a6e22e;">create_key_save</span><span style="color:#f8f8f2;">(</span><span style="font-style:italic;color:#fd971f;">storages</span><span style="color:#f8f8f2;">):
context </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">pyudev.Context()
monitor </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">pyudev.Monitor.from_netlink(context)
monitor.filter_by(</span><span style="color:#e6db74;">&#39;block&#39;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">with </span><span style="color:#66d9ef;">open </span><span style="color:#f8f8f2;">(storages, </span><span style="color:#e6db74;">&#39;r&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">as </span><span style="color:#f8f8f2;">f:
medias_save </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">f.read().splitlines()
done </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">False
</span><span style="color:#f92672;">while not</span><span style="color:#f8f8f2;">(done):
device </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">monitor.poll()
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">device.device_type </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&quot;partition&quot; </span><span style="color:#f92672;">and </span><span style="color:#f8f8f2;">device.action </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&quot;add&quot;</span><span style="color:#f8f8f2;">:
</span><span style="color:#f92672;">if </span><span style="color:#e6db74;">&quot;ynh_save&quot; </span><span style="color:#f92672;">== </span><span style="color:#f8f8f2;">device.get(</span><span style="color:#e6db74;">&#39;ID_FS_LABEL&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">and </span><span style="color:#f8f8f2;">device.get(</span><span style="color:#e6db74;">&#39;ID_FS_UUID&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">in </span><span style="color:#f8f8f2;">medias_save:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Ce support de stockage est déjà initialisé&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Il n&#39;est pas nécéssaire d&#39;initialisé ce périphérique&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
</span><span style="color:#f92672;">else</span><span style="color:#f8f8f2;">:
size </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.check_output(</span><span style="color:#e6db74;">&quot;fdisk -s &quot; </span><span style="color:#f92672;">+
</span><span style="color:#f8f8f2;">device.device_node,
</span><span style="font-style:italic;color:#fd971f;">shell</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">True</span><span style="color:#f8f8f2;">)
size </span><span style="color:#f92672;">= </span><span style="font-style:italic;color:#66d9ef;">int</span><span style="color:#f8f8f2;">(size)
size_requirement </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">getMinSpaceRequirement()
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">size </span><span style="color:#f92672;">&gt; </span><span style="color:#f8f8f2;">size_requirement:
done </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">True
</span><span style="color:#f8f8f2;">retcode </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">subprocess.call(</span><span style="color:#e6db74;">&quot;mkfs.ext4&quot; </span><span style="color:#f92672;">+ </span><span style="color:#e6db74;">&quot; -F -L ynh_save&quot; </span><span style="color:#f92672;">+
</span><span style="color:#e6db74;">&quot; &quot;</span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">device.device_node, </span><span style="font-style:italic;color:#fd971f;">shell</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">True</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">retcode </span><span style="color:#f92672;">!= </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Impossible de formatter la clé&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot; Il y a eu un problème durant le formatage de la clé&quot;&quot;&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
</span><span style="color:#75715e;"># On récupere le nouvel uuid
</span><span style="color:#f92672;">with </span><span style="color:#66d9ef;">open </span><span style="color:#f8f8f2;">(storages, </span><span style="color:#e6db74;">&#39;a&#39;</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">as </span><span style="color:#f8f8f2;">f:
f.write(get_uuid(device.device_node)</span><span style="color:#f92672;">+ </span><span style="color:#e6db74;">&#39;</span><span style="color:#ae81ff;">\n</span><span style="color:#e6db74;">&#39;</span><span style="color:#f8f8f2;">)
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Autorisation d&#39;un support de sauvegarde&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot; Vous venez de créer un support pour votre sauvegarde.
Cela s&#39;est deroulé normalement. Pour effectuer une sauvegarde maintenant
rebrancher votre support de stockage; un mail vous signalera quand vous pourrez
enlevez votre support en toute sécurité.&quot;&quot;&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
done </span><span style="color:#f92672;">= </span><span style="color:#ae81ff;">True
</span><span style="color:#f92672;">else</span><span style="color:#f8f8f2;">:
subject </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;Votre support de stockage est de taille insufisante !&quot;
</span><span style="color:#f8f8f2;">message </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;&quot;&quot;Il n&#39;y a pas assez d&#39;espace disque sur le support que
vous venez de brancher; essayer avec une media de plus grande capacité (minimum &quot;&quot;&quot; </span><span style="color:#f92672;">+
</span><span style="font-style:italic;color:#66d9ef;">str</span><span style="color:#f8f8f2;">(size_requirement</span><span style="color:#f92672;">/</span><span style="color:#ae81ff;">1000000</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">+ </span><span style="color:#e6db74;">&quot;Gb)&quot;
</span><span style="color:#f8f8f2;">send_msg(subject, message)
save_directory </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;/media/save&quot;
</span><span style="color:#f8f8f2;">save_script </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;/etc/saveonusb/scripts/save.sh&quot;
</span><span style="color:#f8f8f2;">conf_path </span><span style="color:#f92672;">= </span><span style="color:#e6db74;">&quot;/etc/saveonusb/&quot;
</span><span style="color:#f8f8f2;">storages </span><span style="color:#f92672;">= </span><span style="color:#f8f8f2;">conf_path</span><span style="color:#f92672;">+</span><span style="color:#e6db74;">&quot;storages&quot;
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">os.geteuid() </span><span style="color:#f92672;">!= </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">:
</span><span style="color:#f92672;">raise </span><span style="font-style:italic;color:#66d9ef;">OSError</span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;Ce programme doit s&#39;executer avec les droits root&quot;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if not</span><span style="color:#f8f8f2;">(os.path.exists(save_directory)):
</span><span style="color:#f92672;">raise </span><span style="font-style:italic;color:#66d9ef;">OSError</span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;Le repertoire &quot;</span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">save_directory </span><span style="color:#f92672;">+</span><span style="color:#e6db74;">&quot; n&#39;existe pas&quot;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if not</span><span style="color:#f8f8f2;">(os.path.exists(conf_path)):
</span><span style="color:#f92672;">raise </span><span style="font-style:italic;color:#66d9ef;">OSError</span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;Le repertoire &quot;</span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">conf_path </span><span style="color:#f92672;">+</span><span style="color:#e6db74;">&quot; n&#39;existe pas&quot;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if not</span><span style="color:#f8f8f2;">(os.path.isfile(save_script)):
</span><span style="color:#f92672;">raise </span><span style="font-style:italic;color:#66d9ef;">OSError</span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;Le fichier &quot;</span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">save_script </span><span style="color:#f92672;">+</span><span style="color:#e6db74;">&quot; n&#39;existe pas&quot;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if not</span><span style="color:#f8f8f2;">(os.path.isfile(storages)):
</span><span style="color:#f92672;">raise </span><span style="font-style:italic;color:#66d9ef;">OSError</span><span style="color:#f8f8f2;">(</span><span style="color:#e6db74;">&quot;Le fichier &quot;</span><span style="color:#f92672;">+ </span><span style="color:#f8f8f2;">storages </span><span style="color:#f92672;">+</span><span style="color:#e6db74;">&quot; n&#39;existe pas&quot;</span><span style="color:#f8f8f2;">)
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">len</span><span style="color:#f8f8f2;">(sys.argv) </span><span style="color:#f92672;">&gt; </span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">:
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">sys.argv[</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&#39;create&#39;</span><span style="color:#f8f8f2;">:
create_key_save(storages)
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">sys.argv[</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&#39;make&#39;</span><span style="color:#f8f8f2;">:
make_save(save_directory, storages)
</span><span style="color:#f92672;">if </span><span style="color:#f8f8f2;">sys.argv[</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&#39;--help&#39; </span><span style="color:#f92672;">or </span><span style="color:#f8f8f2;">sys.argv[</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">] </span><span style="color:#f92672;">== </span><span style="color:#e6db74;">&#39;-h&#39;</span><span style="color:#f8f8f2;">:
print_help()
</span><span style="color:#f92672;">else</span><span style="color:#f8f8f2;">:
print_help()
</span></pre>
<p>On installe pyudev:</p>
<pre style="background-color:#272822;">
<span style="color:#f8f8f2;"> apt install python3-pyudev
</span></pre>
<p>On créé les répertoires et les fichiers nécessaires:</p>
<pre style="background-color:#272822;">
<span style="color:#f8f8f2;">mkdir /media/save
mkdir</span><span style="font-style:italic;color:#fd971f;"> -p</span><span style="color:#f8f8f2;"> /etc/saveonusb/scripts
touch /etc/saveonusb/storages </span><span style="color:#f92672;">&amp;&amp; </span><span style="color:#f8f8f2;">touch /etc/saveonusb/scripts/save.sh
chmod +x /etc/saveonusb/scripts/save.sh
</span></pre>
<p>Je me suis fait tout d'abord un petit script afin de générer
une image prête a être flasher sur une carte SD </p>
<pre style="background-color:#272822;">
<span style="color:#f8f8f2;">
</span><span style="color:#75715e;">#!/bin/bash
</span><span style="color:#66d9ef;">set </span><span style="font-style:italic;color:#fd971f;">-e
</span><span style="color:#75715e;">#set -x
#Implementer un TRAC error avec exit qui clean quand ca foire
# Implementer des logs
#Fonction pour check les programmes nécéssaire.
#lance apt install quand les programmes manques
# modprobe loop
# Test les medias disponibles et passer en parametre le disk a monter pour mettre l&#39;image
# Demande confirmation pour commencer tout les étapes ou a toutes les étapes
</span><span style="color:#f8f8f2;">_apt_install_dep()
{
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;on passe ici avec $1 comme argument&quot;
</span><span style="color:#f92672;">case </span><span style="color:#f8f8f2;">$1 </span><span style="color:#f92672;">in</span><span style="color:#f8f8f2;">
truncate</span><span style="color:#f92672;">)
</span><span style="color:#f8f8f2;">apt-get</span><span style="font-style:italic;color:#fd971f;"> -y</span><span style="color:#f8f8f2;"> install</span><span style="font-style:italic;color:#fd971f;"> --no-install-recommends</span><span style="color:#f8f8f2;"> coreutils
;;
mkfs.ext4</span><span style="color:#f92672;">)
</span><span style="color:#f8f8f2;">apt-get</span><span style="font-style:italic;color:#fd971f;"> -y</span><span style="color:#f8f8f2;"> install</span><span style="font-style:italic;color:#fd971f;"> --no-install-recommends</span><span style="color:#f8f8f2;"> e2fsprogs
;;
</span><span style="color:#f92672;">*)
</span><span style="color:#f8f8f2;">apt-get</span><span style="font-style:italic;color:#fd971f;"> -y</span><span style="color:#f8f8f2;"> install</span><span style="font-style:italic;color:#fd971f;"> --no-install-recommends </span><span style="color:#f8f8f2;">$1
;;
</span><span style="color:#f92672;">esac
</span><span style="color:#f8f8f2;">}
</span><span style="color:#a6e22e;">check_dep</span><span style="color:#f8f8f2;">()
{
bins</span><span style="color:#f92672;">=</span><span style="color:#f8f8f2;">(dd truncate rsync parted mkfs.ext4 )
</span><span style="color:#f92672;">for</span><span style="color:#f8f8f2;"> i </span><span style="color:#f92672;">in </span><span style="color:#e6db74;">&quot;${bins[@]}&quot;</span><span style="color:#f92672;">; do
if ! </span><span style="color:#f8f8f2;">which </span><span style="color:#e6db74;">&quot;${i}&quot; </span><span style="color:#f92672;">&amp;&gt;</span><span style="color:#f8f8f2;"> /dev/null</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;${i} command is required&quot;
</span><span style="color:#f8f8f2;">_apt_install_dep ${i}
</span><span style="color:#f92672;">fi
done
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;check_dep ok&quot;
</span><span style="color:#f8f8f2;">}
</span><span style="color:#a6e22e;">create_img</span><span style="color:#f8f8f2;">() {
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">folder</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">image</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$2
</span><span style="color:#75715e;"># Espace utilisé sur /
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">usage</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$(df</span><span style="font-style:italic;color:#fd971f;"> -BM </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">grep ^/dev </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">head</span><span style="font-style:italic;color:#fd971f;"> -1 </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">awk &#39;{print $3}&#39; </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">tr</span><span style="font-style:italic;color:#fd971f;"> -cd </span><span style="color:#e6db74;">&#39;[0-9]. \n&#39;)
</span><span style="color:#75715e;"># Espace libre
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">avaible</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$(df</span><span style="font-style:italic;color:#fd971f;"> -BM </span><span style="color:#e6db74;">$folder </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">grep ^/dev </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">head</span><span style="font-style:italic;color:#fd971f;"> -1 </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">awk &#39;{print $4}&#39; </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">tr</span><span style="font-style:italic;color:#fd971f;"> -cd </span><span style="color:#e6db74;">&#39;[0-9]. \n&#39;)
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[[ </span><span style="color:#f8f8f2;">$usage </span><span style="font-style:italic;color:#fd971f;">-gt </span><span style="color:#f8f8f2;">$avaible </span><span style="color:#66d9ef;">]]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;No space left&quot;
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;Required: $usage MB &quot;
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;Free space in $folder : $avaible MB &quot;
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1
</span><span style="color:#f92672;">fi
</span><span style="color:#75715e;">#On laisse 1024M d&#39;espace libre sur l&#39;image
</span><span style="color:#f8f8f2;"> local image_size=$(($usage</span><span style="color:#f92672;">+</span><span style="color:#ae81ff;">1024</span><span style="color:#f8f8f2;">))</span><span style="color:#e6db74;">&#39;M&#39;
</span><span style="color:#f8f8f2;">truncate</span><span style="font-style:italic;color:#fd971f;"> -s </span><span style="color:#f8f8f2;">$image_size $folder/$image
}
</span><span style="color:#a6e22e;">prepare_part</span><span style="color:#f8f8f2;">() {
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">loop</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">folder</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$2
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">image</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$3
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">mount_image</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$4
</span><span style="color:#f8f8f2;">losetup $loop $folder/$image
parted</span><span style="font-style:italic;color:#fd971f;"> -s </span><span style="color:#f8f8f2;">$loop</span><span style="color:#f92672;"> --</span><span style="color:#f8f8f2;"> mklabel msdos
parted</span><span style="font-style:italic;color:#fd971f;"> -s </span><span style="color:#f8f8f2;">$loop</span><span style="color:#f92672;"> --</span><span style="color:#f8f8f2;"> mkpart primary ext4 8192s -1s
</span><span style="color:#75715e;">#La carte ne boot pas avec la ligne en dessous
#parted -s $loop align-check optimal 1
</span><span style="color:#f8f8f2;"> partprobe $loop
mkfs.ext4 $loop</span><span style="color:#e6db74;">&quot;p1&quot;
</span><span style="color:#f8f8f2;">mkdir $mount_image
mount $loop</span><span style="color:#e6db74;">&quot;p1&quot; </span><span style="color:#f8f8f2;">$mount_image
}
</span><span style="color:#a6e22e;">copy_files</span><span style="color:#f8f8f2;">() {
</span><span style="color:#75715e;"># Stopper les services avant de copie
# Vérifier que les partitions soient montées
# Afficher le point de montage de la partition
# On redirige la sortie du programme vers /dev/null et la sortie erreur (2) sur la sortie standard
# On ne verra que les erreurs des fichiers ou la copie a posé problème
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">mount_image</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f8f8f2;">rsync</span><span style="font-style:italic;color:#fd971f;"> -avrltD --delete --exclude</span><span style="color:#f92672;">=</span><span style="color:#f8f8f2;">{/dev/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">,/proc/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">,/sys/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">,/media/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">,/mnt/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">,/run/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">,/tmp/</span><span style="color:#f92672;">*</span><span style="color:#f8f8f2;">} / $mount_image </span><span style="color:#f92672;">&gt;</span><span style="color:#f8f8f2;"> /dev/null </span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">1
</span><span style="color:#f8f8f2;">}
</span><span style="color:#75715e;">#Modify fstab
</span><span style="color:#a6e22e;">change_fstab</span><span style="color:#f8f8f2;">() {
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">mount_image</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">old_uuid</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$(blkid</span><span style="font-style:italic;color:#fd971f;"> -o</span><span style="color:#e6db74;"> export `mount </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">grep</span><span style="font-style:italic;color:#fd971f;"> -w</span><span style="color:#e6db74;"> / </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">awk &#39;{print $1}&#39;` </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">grep ^UUID)
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">new_uuid</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$(blkid</span><span style="font-style:italic;color:#fd971f;"> -o</span><span style="color:#e6db74;"> export `mount </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">grep</span><span style="font-style:italic;color:#fd971f;"> -w</span><span style="color:#e6db74;"> /media/$IMAGE </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">awk &#39;{print $1}&#39;` </span><span style="color:#f92672;">| </span><span style="color:#e6db74;">grep ^UUID)
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;old_uuid: $old_uuid&quot;
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;new_uuid: $new_uuid&quot;
</span><span style="color:#f8f8f2;">sed</span><span style="font-style:italic;color:#fd971f;"> -i</span><span style="color:#f8f8f2;"> s/$old_uuid/$new_uuid/ $MOUNT_IMAGE/etc/fstab
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="font-style:italic;color:#fd971f;">-e </span><span style="color:#f8f8f2;">$MOUNT_IMAGE/boot/armbianEnv.txt </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#f8f8f2;">sed</span><span style="font-style:italic;color:#fd971f;"> -i</span><span style="color:#f8f8f2;"> s/$old_uuid/$new_uuid/ $MOUNT_IMAGE/boot/armbianEnv.txt
</span><span style="color:#f92672;">fi
</span><span style="color:#f8f8f2;">}
</span><span style="color:#a6e22e;">write_mbr</span><span style="color:#f8f8f2;">() {
</span><span style="color:#75715e;"># On cherche le uboot_sunxi_with_spl.bin selon si on est sur armbian ou non
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">$uboot_mbr
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">$loop
loop</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f8f8f2;">uboot_mbr</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$2
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f92672;">! </span><span style="font-style:italic;color:#fd971f;">-f </span><span style="color:#f8f8f2;">$uboot_mbr </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1</span><span style="color:#f92672;">;
fi
</span><span style="color:#75715e;"># on Efface la zone pour le mbr
</span><span style="color:#f8f8f2;"> dd if=/dev/zero of=$loop bs=1k count=1023 seek=1 status=noxfer </span><span style="color:#f92672;">&gt;</span><span style="color:#f8f8f2;"> /dev/null </span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">1</span><span style="color:#f92672;">;
</span><span style="color:#75715e;"># on flash le mbr
</span><span style="color:#f8f8f2;">dd if=$uboot_mbr of=$loop bs=1024 seek=8 status=noxfer </span><span style="color:#f92672;">&gt;</span><span style="color:#f8f8f2;"> /dev/null </span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">1</span><span style="color:#f92672;">;
</span><span style="color:#f8f8f2;">}
</span><span style="color:#a6e22e;">clean</span><span style="color:#f8f8f2;">() {
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">loop</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f92672;">local </span><span style="color:#f8f8f2;">mount_image</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$2
</span><span style="color:#f8f8f2;">sync
umount $mount_image
losetup</span><span style="font-style:italic;color:#fd971f;"> -d </span><span style="color:#f8f8f2;">$loop
rmdir $mount_image
}
</span><span style="color:#75715e;">## Début du script
</span><span style="color:#a6e22e;">show_usage</span><span style="color:#f8f8f2;">() {
cat </span><span style="color:#f92672;">&lt;&lt; EOF</span><span style="color:#e6db74;">
Ce script génère une image qui peut être flasher sur une carte SD pour les cartes
Olimex LIME LIME2 et orange pi pc (plus)
$(basename $0)
-d Dossier où sera stocké l&#39;image
-u uboot_sunxi_with_spl.bin
EOF</span><span style="background-color:#f92672;color:#f8f8f0;">
</span><span style="color:#e6db74;">
</span><span style="color:#f8f8f2;"> exit 1
}
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f92672;">! </span><span style="color:#f8f8f2;">$(id</span><span style="font-style:italic;color:#fd971f;"> -u</span><span style="color:#f8f8f2;">) </span><span style="color:#f92672;">=</span><span style="color:#f8f8f2;"> 0 </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;L&#39;utilisateur doit être root&quot;
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1
</span><span style="color:#f92672;">fi
</span><span style="color:#75715e;">## Possibilité d&#39;aller chercher le uboot_sunxi_with_spl.bin sur une adresse http
#Check arguments
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f8f8f2;">$# </span><span style="font-style:italic;color:#fd971f;">-eq</span><span style="color:#f8f8f2;"> 0 </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#f8f8f2;">show_usage
</span><span style="color:#f92672;">fi
</span><span style="color:#75715e;"># Gérer les options https://www.tutorialspoint.com/unix_commands/getopt.htm
</span><span style="color:#f92672;">while </span><span style="color:#66d9ef;">getopts </span><span style="color:#e6db74;">&quot;:d:u:h&quot;</span><span style="color:#f8f8f2;"> opt</span><span style="color:#f92672;">; do
case </span><span style="color:#f8f8f2;">$opt </span><span style="color:#f92672;">in</span><span style="color:#f8f8f2;">
d</span><span style="color:#f92672;">)
</span><span style="color:#f8f8f2;">FOLDER</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$OPTARG
</span><span style="color:#f8f8f2;">;;
u</span><span style="color:#f92672;">)
</span><span style="color:#f8f8f2;">UBOOT_MBR</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$OPTARG
</span><span style="color:#f8f8f2;">;;
h </span><span style="color:#f92672;">| *)
</span><span style="color:#f8f8f2;">show_usage</span><span style="color:#f92672;">;
</span><span style="color:#f8f8f2;">;;
</span><span style="color:#f92672;">esac
done
if </span><span style="color:#66d9ef;">[ </span><span style="font-style:italic;color:#fd971f;">-z </span><span style="color:#f8f8f2;">$FOLDER </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#f8f8f2;">show_usage
</span><span style="color:#f92672;">fi
if </span><span style="color:#66d9ef;">[ </span><span style="color:#f92672;">! </span><span style="font-style:italic;color:#fd971f;">-d </span><span style="color:#f8f8f2;">$FOLDER </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;$FOLDER isn&#39;t a directory&quot;</span><span style="color:#f92672;">;
</span><span style="color:#75715e;">#echo &quot;Le dossier $FOLDER n&#39;existe pas&quot;
</span><span style="color:#f8f8f2;">show_usage
</span><span style="color:#f92672;">fi
if </span><span style="color:#66d9ef;">[ </span><span style="font-style:italic;color:#fd971f;">-z </span><span style="color:#f8f8f2;">$UBOOT_MBR </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#f8f8f2;">show_usage
</span><span style="color:#f92672;">fi
if </span><span style="color:#66d9ef;">[ </span><span style="color:#f92672;">! </span><span style="font-style:italic;color:#fd971f;">-f </span><span style="color:#f8f8f2;">$UBOOT_MBR </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;This file $UBOOT_MBR doesn&#39;t exist&quot;</span><span style="color:#f92672;">;
</span><span style="color:#f8f8f2;">show_usage
</span><span style="color:#f92672;">fi
</span><span style="color:#f8f8f2;">IMAGE</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">snapshot_</span><span style="color:#f8f8f2;">`date +%Y%m%d`.img
LOOP</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$(losetup</span><span style="font-style:italic;color:#fd971f;"> -f</span><span style="color:#e6db74;">)
</span><span style="color:#f8f8f2;">MOUNT_IMAGE</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">&quot;/media/&quot;$IMAGE
</span><span style="color:#f8f8f2;">check_dep
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;check_dep : OK&quot;
</span><span style="color:#75715e;">#On crée un image de la taille minimale avec 1024M de place disponible.
</span><span style="color:#f8f8f2;">create_img $FOLDER $IMAGE
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;create_img: OK&quot;
</span><span style="color:#75715e;">#On crée l&#39;interface Loop et les partitions qui vont bien
</span><span style="color:#f8f8f2;">prepare_part $LOOP $FOLDER $IMAGE $MOUNT_IMAGE
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;prepare_part: OK&quot;
</span><span style="color:#75715e;">#On copie la /
</span><span style="color:#f8f8f2;">copy_files $MOUNT_IMAGE
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;copy_file: OK&quot;
</span><span style="color:#75715e;">#
</span><span style="color:#f8f8f2;">change_fstab $MOUNT_IMAGE
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;change_fstab: OK&quot;
</span><span style="color:#75715e;">#On écrit le MBR
</span><span style="color:#f8f8f2;">write_mbr $LOOP $UBOOT_MBR
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;write_uboot: OK&quot;
</span><span style="color:#75715e;">#demonte l&#39;image et detache l&#39;interface loop
</span><span style="color:#f8f8f2;">clean $LOOP $MOUNT_IMAGE
</span></pre>
<p>je copie ce script dans /usr/local/bin/make_img
chmod +x /usr/local/bin/make_img</p>
<p>Puis dans mon fichier /etc/saveonusb/script/save.sh</p>
<pre style="background-color:#272822;">
<span style="color:#f8f8f2;">
DIR_SAVE</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f92672;">! </span><span style="font-style:italic;color:#fd971f;">-d </span><span style="color:#e6db74;">&quot;$DIR_SAVE&quot; </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;Le repertoire $DIR_SAVE n&#39;existe pas&quot; </span><span style="color:#ae81ff;">1</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">;
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1</span><span style="color:#f92672;">;
fi
</span><span style="color:#f8f8f2;">/usr/local/bin/make_img</span><span style="font-style:italic;color:#fd971f;"> -f </span><span style="color:#f8f8f2;">$DIR_SAVE</span><span style="font-style:italic;color:#fd971f;"> -u</span><span style="color:#f8f8f2;"> /usr/lib/linux-u-boot-next-orangepipcplus_5.90_armhf/u-boot-sunxi-with-spl.bin
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f8f8f2;">$? </span><span style="font-style:italic;color:#fd971f;">-eq</span><span style="color:#f8f8f2;"> 1 </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;Il y a eu une erreur durant la copie des fichiers&quot; </span><span style="color:#ae81ff;">1</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">;
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1</span><span style="color:#f92672;">;
fi
</span><span style="color:#f8f8f2;">{% endhighlight %}
Version pour les personnes qui sont sous yunohost:
{% highlight bash %}
</span><span style="color:#75715e;">#!/bin/bash
</span><span style="color:#f8f8f2;">DIR_SAVE</span><span style="color:#f92672;">=</span><span style="color:#e6db74;">$1
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f92672;">! </span><span style="font-style:italic;color:#fd971f;">-d </span><span style="color:#e6db74;">&quot;$DIR_SAVE&quot; </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;Le repertoire $DIR_SAVE n&#39;existe pas&quot; </span><span style="color:#ae81ff;">1</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">;
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1</span><span style="color:#f92672;">;
fi
</span><span style="color:#f8f8f2;">/usr/bin/yunohost backup create</span><span style="font-style:italic;color:#fd971f;"> -o </span><span style="color:#f8f8f2;">$DIR_SAVE
</span><span style="color:#f92672;">if </span><span style="color:#66d9ef;">[ </span><span style="color:#f8f8f2;">$? </span><span style="font-style:italic;color:#fd971f;">-eq</span><span style="color:#f8f8f2;"> 1 </span><span style="color:#66d9ef;">]</span><span style="color:#f92672;">; then
</span><span style="color:#66d9ef;">echo </span><span style="color:#e6db74;">&quot;Il y a eu une erreur pendant l&#39;exécution de yunohost backup&quot; </span><span style="color:#ae81ff;">1</span><span style="color:#f92672;">&gt;&amp;</span><span style="color:#ae81ff;">2</span><span style="color:#f92672;">;
</span><span style="color:#66d9ef;">exit</span><span style="color:#f8f8f2;"> 1</span><span style="color:#f92672;">;
fi
</span></pre>
<p>Il y a biensur des choses à améliorer, mais c'est fonctionnel. On pourrait par exemple avoir plusieurs scripts ou vérifier si le support de sauvergarde a encore la place suffisante. Mais pour mes besoins ça me suffit. Une fonction pour la restauration ça serait pas mal aussi :).</p>
</div>
<footer><span class="copyleft">©</span> kitoy.me <br/> Site généré avec <a href="https://getzola.org/"> Zola </a> </footer>
<script src="https:&#x2F;&#x2F;kitoy.me&#x2F;js&#x2F;menu.js" ></script>
</body>
</html>