L'espace... Cifiste

Parce que la terre est dure ;)

Astuce : Installation de Proxmox par clé USB, no cdrom found

Si comme moi vous vous trouvez avec un message d'erreur lors du boot de proxmox pour une future installation, il existe une solution simple pour palier à celle-ci ne nécessitant rien de plus que l'utilitaire DD, (c)fdsik et cp :

Si ce n'est déjà fait, il faut avoir copié l'image de proxmox via l'utilitaire dd :

dd if=proxmox-3.2.iso of=/dev/sdX bs=1MB

Ceci fait, lancez cfdisk et créez une seconde partition (format de votre choix, ici fat32).

Puis formatez la, montez la et enfin, copiez l'image ISO de proxmox dessus :

mkfs.vfat /dev/sdX2
mount /dev/sdX2 /mnt
cp prxomox-3.2.iso /mnt/

Maintenant bootez sur la clé et lancez proxmox en mode debug :

boot : debug

Une fois arrivé au prompt, après le message d'erreur, montez votre seconde partition dans /mnt :

mount /dev/sdX2 /mnt

Et ensuite, montez l'image ISO :

mount -t9660 /mnt/proxmox-3.2.iso /mnt

Chrootez* vous dedans :

chroot /mnt

et enfin, lancez le script d'installation :

sbin/unconfigured.sh

Vous devriez arriver sur l'écran d'installation de proxmox.

 

* Du verbe chrooter


Référence :

http://upshell.wordpress.com/2011/11/25/install-proxmox-with-usb/

Écrit le lundi 14 avril 2014,0 commentaire(s).

Astuce : libvirt, déplacer le répertoire par défaut

dans un terminal en root :

virsh pool-start default
virsh pool-destroy default
virsh pool-undefine default
virsh pool-define-as --name default --type dir --target /new/path/to/default
virsh pool-autostart default
virsh pool-build default
virsh pool-start default

Via http://opennodecloud.com/forum/index.php?topic=192.0

Écrit le mercredi 19 mars 2014,0 commentaire(s).

ClamWin et ClamSentinel : Utilisation en mode client <-> serveur

 

Sommaire :

  1. Introduction,
  2. Installation de base,
  3. Préparation des programmes partagés,
  4. Création des scripts utilisateurs,
  5. Configuration des programmes sources,
  6. Initialisations des programmes,
  7. Test des clients,
  8. Optimisation futures,
  9. Références.

Introduction :

Récement j'ai été confronté à un problème de faux positif avec le valeureux clamwin, ne vous pas aller sur chaque poste pour paramétrer une whitelist des applications à ne pas scanner, je me suis mis en réflexion d'installer cet outil en mode client serveur (sachant qu'il ne fonctionne pas dans cette optique). Après quelques triturages de cerveau et tests, le résultat est au dela de mes attentes !

En effet, à partir de simples configuration je suis parvenu à faire fonctionner ClamWin et ClamSentinel via le serveur.

Les intérêts sont multiples :

- Les mises à jours ne se font que sur le serveur,

- Les logs et les fichiers de quarantaines sont écrits sur le serveur (par poste),

- Le fichier de configuration est commun pour tous les clients, ainsi les options / whitelist ne sont configurés qu'une seule fois.

Installation de base

Installer ClamWin et ClamSentinel avec les options par défaut sans télécharger la base virale.

Préparation des programmes partagés :

Tout d'abord télécharger la dernière version de Clamwin1 et ClamSentinel2

Créer un répertoire ClamWin et partager le avec les options suivantes :

- Tout le monde : Contrôle total;

Et les autorisations NTFS suivantes :

- Utilisateurs authentifiés :
> Modifier
> Lecture et exécution
> Affichage du contenu du dossier
> Lecture
> Ecriture

 

Aller dans le répertoire ou ClamWin a été installé et copier les répertoires bin et lib dans le répertoire partagé créé précédement3.

Toujours dans le répertoire partagé, créer les dossiers suivants :

- computers

- db

Ouvrer le fichier de configuration bin\ClamWin.conf et modifier le premier paramètre :

standalone = 1

Qui va rendre autonome l'application (ne va pas créer de fichier de conf sur les postes)

Puis les lignes comme suit :

logfile = %CLAMWINPATH%\computers\%COMPUTERNAME%\log\ClamWin.log
freshclam = %CLAMWINPATH%\bin\freshclam.exe
clamscan = %CLAMWINPATH%\bin\clamscan.exe
quarantinedir = %CLAMWINPATH%\computers\%COMPUTERNAME%\quarantine
database =%CLAMWINPATH%\db

et plus loin :

dbupdatelogfile = %CLAMWINPATH%\log\ClamUpdateLog.txt

Pour que les clients ne soient pas informés des mises à jour et qu'ils ne fassent pas d'update des bases virales

[Updates]
checkversion = 0
checkversionurl = http://clamwin.sourceforge.net/clamwinver.php
warnoutofdate = 0
enable = 0
dbupdatelogfile = \\192.168.1.103\ClamWin$\log\ClamUpdateLog.txt
dbmirror = database.clamav.net
updateonlogon = 0
frequency = Daily
weekday = 2
time = 00:00:00

Ensuite, rendez-vous dans "bin\Microsoft.VC80.CRT" et copier tous les fichiers (sauf le manifest) dans le répertoire parent "bin".

Occupons nous de ClamSentinel :

Il faut dans un premier temps copier les deux exécutables de clamSentinel dans le répertoire partagé bin

- ClamSentinel.exe

- SentinelRecover.exe

Puis copier le fichier de configuration de celui-ci dans bin également, pour faire simple, utiliser l'outil de recherche sur c: pour ClamSentinel.ini

Et modifier ce fichier comme ceci4 :

;***** on Windows 98/ME
;PathClamWin=%CLAMWINPATH%\bin\

;***** on Windows NT/XP/2000, Vista, Windows 7
PathClamWin=%CLAMWINPATH%\bin\

;***** on ClamWin Portable
;PathClamWin=%CLAMWINPATH%\bin\

Et pour finir :

;### Path for logs files. If empty is used the logfile path defined into ClamWin.conf
PathLog=%CLAMWINPATH%\computers\%COMPUTERNAME%\log\

Création des scripts utilisateurs :

Maintenant, pour lancer ClamWin et ClamSentinel au démarrage des postes, il nous faut un script de logon qui va créer si nécessaire les bons répertoires pour la quarantaine et les logs :

ClamWin.bat :

set CLAMWINPATH=\\cheminUNC\ClamWin$
md "%CLAMWINPATH%\computers\%COMPUTERNAME%"
md "%CLAMWINPATH%\computers\%COMPUTERNAME%\log"
md "%CLAMWINPATH%\computers\%COMPUTERNAME%\quarantine"
start %CLAMWINPATH%\bin\ClamTray.exe
start %CLAMWINPATH%\bin\ClamSentinel.exe

Et il ne reste plus qu'à appeler ce script au tout début des scripts utilisateur (partie à revoir, ne serait-il pas plus pertinent de le faire via les paramètres de l'ordinateur ?)

user.bat :

call %~dp0ZClamWin.bat

Configuration des programmes sources :

Enfin, il reste à configurer le ClamWin du serveur, c'est lui qui va récupérer les MAJ et les mettre dans le bon répertoire. Pour cela, il faut d'abord arrêter ClamWin et ClamSentinel puis retourner dans le répertoire de l'installation et modifier le fichier ClamWin.conf de la sorte :

Tout d'abord :

standalone = 1

Et ensuite (remplacer f: par votre lettre de lecteur ;) ) :

database = F:\ClamWin\db

Initialisations des programmes :

Relancer ClamTray puis télécharger la base de données initiale. Si tout c'est bien passé, elle devrait être enregistrée dans le répertoire db du partage ClamWin$

Test des clients :

Il ne reste plus qu'à démarrer un poste client pour confirmer le lancement des exécutables et c'est terminé.

Au fur et à mesure des postes clients allumés, les logs et fichiers de quarantaine vont êtres enregistrés dans le répertoire "computers" par nom d'ordinateur.

À ce stade, ClawWin et ClamSentinel fonctionnent en mode "client serveur".

Pour faire les mises à jours du logiciels, il suffira de faire la MAJ de l'application serveur quand celle-ci le proposera puis copier ces fichiers dans le répertoire bin et lib, sans oublier les fichiers du répertoire \Microsoft.VC80.CRT. Rien de plus simple :)

Optimisations futures :

Même si ça fonctionne vraiment bien, il y a quelques déconvenues :

- Les utilisateurs peuvent modifier les paramètres via le systray ainsi que la MAJ de la base virale.

- Ce mode d'installation ne fonctionne que pour des machine fixe, si on effectue cette méthode sur des clients itinérents, ceux-ci n'auront pas d'anti-virus à l'extérieur du domaine.

Je suis en train de travailler sur des solutions pour palier à ces deux problèmes. Si vous avez des idées, elles sont les bienvenues :)


Références :

1 http://sourceforge.net/projects/clamwin/
2 http://clamsentinel.sourceforge.net/
3 http://fr.clamwin.com/content/view/98/92/
4 http://clamsentinel.sourceforge.net/SentinelSimpleGuide.html

Écrit le jeudi 9 janvier 2014,2 commentaire(s).

Pense bête #2 : Déployer le msi de LibreOffice par GPO

 

Sommaire :

1. État des lieux,
2. Correction du msi,
3. Modification des options,
4. Références.
 

État des lieux

Par défaut, le msi fournit par la Document Foundation1 pour installer LibreOffice2 pose quelques petits problèmes pour un déploiement automatisé via GPO.

1 - Les options de personnalisation ne sont documentées que pour l'installation en ligne de commande3 via msiexec, hors, Microsoft nous fournit un outils bien plus pratique.

2 - Si on essaye d'importer le msi telquel, ça ne fonctionne pas à cause de problèmes sur le package.

Correction du msi

On peut facilement remédier à ça grâce à Orca4.

Tout d'abord, réglons le problème d'importation :

Ouvrez Orca et importez votre msi.

Pour savoir ce qui poste problème, il faut tester le paquet5 :

Tool > Validate > Go

Nous pouvons voir que ce sont certaines langues qui posent problème.

Pour corriger ceci, allez dans l'option view et enfin dans summary informations...

Dans cette fenêtre, il faut se rendre sur "Languages" et supprimer les langues problématiques (ou ne conserver que les votre, je n'ai gardé que l'Anglais et le Français : 1033,1036).

Et validez par OK.

Sauvegardez votre paquet, le premier point est OK.

Modification des options

Pour le second, ce n'est guère compliqué, nous allons créer un patch qui va être appliqué à l'installation du msi.

Pour cela, toujours dans Orca et votre MSI ouvert aller dans le menu transform puis "new transformation".

Ceci fait il faut vous rendre dans la colonne de gauche sur Feature. À droite toute une liste apparait. En suivant la documentation, rendez-vous sur l'option désirée et passez le "level" de chacune à 200 cela aura pour effet de la/les désactiver à l'installation.

Si vous voulez affiner le paquet pour par exemple désactiver les recherches de mise à jour automatiques, comme d'habitude c'est dans property qu'il faut vous rendre.

Le tout réglé, retournez sur le menu "transform" et cliquez sur "apply transformation", choisissez ou vous voulez créer le patch et validez.

Vous avec maintenant un joli MSI installable automatiquement ainsi qu'un patch permettant de désactiver les options voulues.

Références

1 http://www.documentfoundation.org/
2 http://www.libreoffice.org/
3 https://wiki.documentfoundation.org/Deployment_and_Migration/fr
4 http://msdn.microsoft.com/en-us/library/aa370557%28v=vs.85%29.aspx
5 https://bugs.freedesktop.org/show_bug.cgi?id=45750#c14
 

Écrit le jeudi 28 novembre 2013,0 commentaire(s).

Pense bête #1 : Serveur git + The bug Genie bug tracking

 

Sommaire :

  1. Convention,
  2. Préparer apache et PHP,
  3. Préparer GIT,
  4. Installer The Bug Genie,
  5. Créez un projet dans The bug Genie,
  6. Lier le projet GIT à The Bug Genie,
  7. Le premier commit.

Convention :

La distribution utilisée est Archlinux,

Les outils utilisés sont apache, php5.3 et mariaDB,

Apache doit avoir l'url rewrite d'activé,

PHP doit avoir les modules PDOMysql et GD d'activé.

Les dépots GIT et le serveur web sont regroupés dans un répertoire commun :

/data
/data/git
/data/www

mkdir -p /data/{git,www}

Le dépôt GIT est le suivant : /data/git/my_project.git

Préparer apache et PHP :

DocumentRoot "/data/www/thebuggenie"

Et activer l'URL rewrite dans http.conf :

<directory data="">
    Options Indexes FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</directory>

Dans php.ini, ajouter le répertoire /data dans la variable open_basedir afin qu'il puisse être exécuté dans /data/git :

open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/:/usr/share/webapps/:/data/

Préparer GIT :

Ajouter l'utilisateur GIT au groupe http

usermod -g http git

Assurez vous d'avoir un dépôt GIT d'activé.

Installer The Bug Genie :

Télécharger les source de The Bug Genie (http://www.thebuggenie.com/download)

Décompressez l'archive dans le répertoire /data/www

Vérifiez bien la présence du répertoire thebuggenie qui contient la partie applicatif web

Démarrez apache et mariaDB.

Rendez vous sur votre serveur avec votre navigateur avec cette url :

http://mygitserver/install/install.php

Et suivez la procédure d'installation.

Créez un projet dans The bug Genie :

Créez maintenant votre projet, puis dans les paramètres de celui-ci, allez dans l'onglet VCS integration et paramétrer le module avec les options suivantes :

Activer l'intégration VCS : Enable for commits applying to existing issues only

Activer les flux de travaux ? : Enable for this project

Access method : Accès direct (via un appel à tbg_cli)

Sauvegarder et récupérer la clé du projet inidiquée comme ici:

"N'oubliez pas de définir l'ancre après avoir sauvegardé ces paramètres - voir la documentation.
    Vous aurez besoin du numéro d'ID de ce projet 1"

Lier le projet GIT à The Bug Genie :

Une fois terminée, il faut que l'utilisateur GIT puisse exécuter les scripts présents dans /data/www (tbg_cli):

chmod -R 775 /data/www

Puis copiez le script d'appel de tbg_cli dans le répertoire hook de votre projet GIT :

cp /data/www/modules/vcs_integration/hooks/git/tbg-post-receive /data/git/my_project.git/hooks/post_receive

Editer la copie pour y ajouter la clé de votre projet :

vim /data/my_project.git/hooks/post_receive

tbg_cli_path=/data/www/

Puis rendez ce script exécutable :

chmod +x /data/git/my_project.git/hooks/post-receive

Les deux outils sont maintenant reliés et fonctionnels.

Le premier commit :

Pour pouvoir éditer les issues depuis les commits GIT, il faut respecter le workflow qui est paramétré dans The Bug Genie. Par exemple pour fixer une issue :

git commit -m "Fixed trololo issue 1 (resolve issue: resolution=RESOLVED status=fixed)" Écrit le vendredi 9 août 2013,236 commentaire(s).

Astuce de recherches firefox

 

Voici une petite astuce toute simple et ne nécessistant aucun plugin, qui me permet d'effectuer mes différentes recherches sur internet directement de puis la barre d'adresse de firefox.

Une fois celle-ci appliquée (par exemple pour des recherches sur php.net), il suffit d'ouvrir un nouvel onglet et de taper un mot clé puis la recherche souhaité, une fois validé l'entrée, on se retrouve directement sur le site en question.

Par exemple :

Donnera :

Pour mettre en oeuvre cette solution, vous devez d'abord lancer une recherche sur votre site favori, puis récupérer l'url conternant la recherche (chez php.net, une rederection est effectuée :( ).

Ce qui donne ici :

http://www.php.net/manual-lookup.php?pattern=array_shift&lang=fr&scope=quickref

Ensuite vous vous rendez dans le menu des marques pages et crééz en un nouveau :

Dans l'url vous y collez la requête en remplaçant la recherche par %s et dans la zone mot clé, vous indiquez le mot clé que vous allez entrer pour lancer cette recherche :

Et c'est tout ! Ça marche très bien et on y prend vite goût !

Écrit le mardi 16 juillet 2013,0 commentaire(s).

Un coup de peinture #1

 

Une nouveauté qui me permettra peut-être de poster plus de billets ;)

Je vais présenter le thème du moment de mes différents machines avec leurs configurations et les liens nécessaires.

Cette première, est partie d'un rafraichissement de mon portable sous archlinux, celui-ci ayant recontré son petit succès sur google+ (le lien vers le post):

Iron Awesome Arch Desktop (rhoo le nom ;) ) pour rester sur le thème iron man je vais le nommer I.A.A.D.

Le rc.lua d'awesome :

-- Standard awesome library
local gears = require("gears")
local awful = require("awful")
awful.rules = require("awful.rules")
require("awful.autofocus")
-- Widget and layout library
local wibox = require("wibox")
-- Theme handling library
local beautiful = require("beautiful")
-- Notification library
local naughty = require("naughty")
local menubar = require("menubar")
vicious = require("vicious")

-- {{{ Error handling
-- Check if awesome encountered an error during startup and fell back to
-- another config (This code will only ever execute for the fallback config)
if awesome.startup_errors then
    naughty.notify({ preset = naughty.config.presets.critical,
                     title = "Oops, there were errors during startup!",
                     text = awesome.startup_errors })
end

-- Handle runtime errors after startup
do
    local in_error = false
    awesome.connect_signal("debug::error", function (err)
        -- Make sure we don't go into an endless error loop
        if in_error then return end
        in_error = true

        naughty.notify({ preset = naughty.config.presets.critical,
                         title = "Oops, an error happened!",
                         text = err })
        in_error = false
    end)
end
-- }}}

-- {{{ Variable definitions
-- Themes define colours, icons, and wallpapers
-- beautiful.init(".themes/awesome/default/theme.lua")
beautiful.init(".themes/awesome/iron_man/theme.lua")
awesome.font = "SF Intermosaic 6"
-- This is used later as the default terminal and editor to run.
terminal = "urxvt"
editor = os.getenv("EDITOR") or "subl"
editor_cmd = terminal .. " -e " .. editor

-- Default modkey.
-- Usually, Mod4 is the key with a logo between Control and Alt.
-- If you do not like this or do not have such a key,
-- I suggest you to remap Mod4 to another key using xmodmap or other tools.
-- However, you can use another modifier like Mod1, but it may interact with others.
modkey = "Mod4"

-- Table of layouts to cover with awful.layout.inc, order matters.
local layouts =
{
    awful.layout.suit.floating,
    awful.layout.suit.tile,
    awful.layout.suit.tile.left,
    awful.layout.suit.tile.bottom,
    awful.layout.suit.tile.top,
    awful.layout.suit.fair,
    awful.layout.suit.fair.horizontal,
    awful.layout.suit.spiral,
    awful.layout.suit.spiral.dwindle,
    awful.layout.suit.max,
    awful.layout.suit.max.fullscreen,
    awful.layout.suit.magnifier
}
-- }}}

-- {{{ Wallpaper
if beautiful.wallpaper then
    for s = 1, screen.count() do
        gears.wallpaper.maximized(beautiful.wallpaper, s, true)
    end
end
-- }}}

-- {{{ Tags
-- Define a tag table which hold all screen tags.
tags = {
  names = { "dev ?", "web ?", "ter ?",  "off ?",  "med ?", "oth ?" },
  layout = { layouts[2], layouts[10], layouts[2], layouts[10], layouts[1], layouts[1] }
  }
 
for s = 1, screen.count() do
  tags[s] = awful.tag(tags.names, s, tags.layout)
end
-- }}}

-- {{{ Wibox
-- Create a textclock widget
--mytextclock = awful.widget.textclock()
os.setlocale("fr_FR.UTF-8") -- Fran�ais
mytextclock = awful.widget.textclock(" ? %a %d %b %H:%M ")




-- {{{ Personnal widgets

-- batteryWidget

-- Initialize widget
batwidget = wibox.widget.textbox()
-- Register widget
vicious.register(batwidget, vicious.widgets.bat, "? $3 $1", 21, "BAT0")

-- volumeWidget
volumeWidget = wibox.widget.textbox()
--volumeWidget.width = 50
--volumeWidget:set_align("right")
volumeWidget:buttons(awful.util.table.join(
        awful.button({ }, 3, function () volumeMute() end),
        awful.button({ }, 4, function () volumeUp() end),
        awful.button({ }, 5, function () volumeDown() end)
    ))
function volumeUp()
  local step = 655
  local f = io.popen("pacmd dump |grep set-sink-volume")
  local v = f:read()
  local volume = tonumber(string.sub(v, string.find(v, 'x') - 1))
  local newVolume = volume + step
  if newVolume > 65536 then
    newVolume = 65536
  end
  io.popen("pacmd set-sink-volume 0 "..newVolume)
  volumeInfo()
  f:close()
end
function volumeDown()
  local step = 655
  local f = io.popen("pacmd dump |grep set-sink-volume")
  local v = f:read()
  local volume = tonumber(string.sub(v, string.find(v, 'x') - 1))
  local newVolume = volume - step
  if newVolume < 0 then
    newVolume = 0
  end
  io.popen("pacmd set-sink-volume 0 "..newVolume)
  volumeInfo()
  f:close()
end
function volumeMute()
  local g = io.popen("pacmd dump |grep set-sink-mute")
  local mute = g:read()
  if string.find(mute, "no") then
    io.popen("pacmd set-sink-mute 0 yes")
  else
    io.popen("pacmd set-sink-mute 0 no")
  end
  volumeInfo()
  g:close()
end
function volumeInfo()
  volmin = 0
  volmax = 65536
  local f = io.popen("pacmd dump |grep set-sink-volume")
  local g = io.popen("pacmd dump |grep set-sink-mute")
  local v = f:read()
  local mute = g:read()
  if string.find(mute, "no") then
    volume = math.floor(tonumber(string.sub(v, string.find(v, 'x')-1)) * 100 / volmax).."%"
  else
    volume = "?"
  end
  volumeWidget:set_text("????  "..volume)
  f:close()
  g:close()
end
volumeInfo()

wifiwidget = wibox.widget.textbox()
wifiwidget:buttons(awful.util.table.join(
        awful.button({ }, 1, function () wifiList() end),
        awful.button({ }, 2, function () devicesList() end),
        awful.button({ }, 3, function () nmEdit() end)
    ))
function wifiList()
  local nm = io.popen("nmcli -f ssid,signal,active dev wifi list")
  local list = nm:read("*a")
  nm:close()
  naughty.notify({ title = "Current connection",
                 text = list })
end
function devicesList()
  local nm = io.popen("nmcli -f device,state dev status")
  local list = nm:read("*a")
  nm:close()
  naughty.notify({ title = "Devices list",
                 text = list })
end
function nmEdit()
  io.popen("nm-connection-editor")
end
function wifiInfo(adapter)
     local s = io.open("/sys/class/net/"..adapter.."/link_mode")
     local state = s:read()
     if state == "1" then
         -- local f = io.open("/sys/class/net/"..adapter.."/wireless/link")
         local f = io.popen('awk \'NR == 3 {sub (/\\./,""); print $3}\' /proc/net/wireless')
         signal = f:read()
         if signal ~= nil then
           if signal == "0" then
               wifiStrength = "NS"
           else
               wifiStrength = signal.."%"
           end
           f:close()
         else
            wifiStrength = "NC"
         end
     else
        wifiStrength = "Off"
     end
     wifiwidget:set_text("? "..wifiStrength)
     s:close()
     
     
end
wifiInfo("wlan0")
-- awful.hooks.timer.register(5, function()
--      wifiInfo("wlan0")
-- end)



separator = wibox.widget.textbox()
separator:set_text(" ? ")
-- }}}




-- Create a wibox for each screen and add it
mywibox = 
mypromptbox = 
mylayoutbox = 
mytaglist = 
mytaglist.buttons = awful.util.table.join(
                    awful.button({ }, 1, awful.tag.viewonly),
                    awful.button({ modkey }, 1, awful.client.movetotag),
                    awful.button({ }, 3, awful.tag.viewtoggle),
                    awful.button({ modkey }, 3, awful.client.toggletag)
                    )
for s = 1, screen.count() do
    -- Create a promptbox for each screen
    mypromptbox[s] = awful.widget.prompt()
    -- Create a taglist widget
    mytaglist[s] = awful.widget.taglist(s, awful.widget.taglist.filter.all, mytaglist.buttons)

    -- Create the wibox
    mywibox[s] = awful.wibox({ position = "top", height = "12", screen = s })

    -- Widgets that are aligned to the left
    local left_layout = wibox.layout.fixed.horizontal()
    left_layout:add(mytaglist[s])
    left_layout:add(mypromptbox[s])

    -- Widgets that are aligned to the right
    local right_layout = wibox.layout.fixed.horizontal()
    --if s == 1 then right_layout:add(wibox.widget.systray()) end
    right_layout:add(volumeWidget)
    right_layout:add(separator)
    right_layout:add(wifiwidget)
    right_layout:add(separator)
    --right_layout:add(batterywidget)
    right_layout:add(batwidget)
    right_layout:add(mytextclock)

    -- Now bring it all together (with the tasklist in the middle)
    local layout = wibox.layout.align.horizontal()
    layout:set_left(left_layout)
    layout:set_right(right_layout)

    mywibox[s]:set_widget(layout)
end
-- }}}

-- {{{ Key bindings
globalkeys = awful.util.table.join(
    awful.key({ modkey,           }, "Left",   awful.tag.viewprev       ),
    awful.key({ modkey,           }, "Right",  awful.tag.viewnext       ),
    awful.key({ modkey,           }, "Escape", awful.tag.history.restore),

    awful.key({ modkey,           }, "j",
        function ()
            awful.client.focus.byidx( 1)
            if client.focus then client.focus:raise() end
        end),
    awful.key({ modkey,           }, "k",
        function ()
            awful.client.focus.byidx(-1)
            if client.focus then client.focus:raise() end
        end),

    -- Layout manipulation
    awful.key({ modkey, "Shift"   }, "j", function () awful.client.swap.byidx(  1)    end),
    awful.key({ modkey, "Shift"   }, "k", function () awful.client.swap.byidx( -1)    end),
    awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end),
    awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end),
    awful.key({ modkey,           }, "u", awful.client.urgent.jumpto),
    awful.key({ modkey,           }, "Tab",
        function ()
            awful.client.focus.history.previous()
            if client.focus then
                client.focus:raise()
            end
        end),

    -- Standard program
    awful.key({ modkey,           }, "Return", function () awful.util.spawn(terminal) end),
    awful.key({ modkey, "Control" }, "r", awesome.restart),
    awful.key({ modkey, "Shift"   }, "q", awesome.quit),

    awful.key({ modkey,           }, "l",     function () awful.tag.incmwfact( 0.05)    end),
    awful.key({ modkey,           }, "h",     function () awful.tag.incmwfact(-0.05)    end),
    awful.key({ modkey, "Shift"   }, "h",     function () awful.tag.incnmaster( 1)      end),
    awful.key({ modkey, "Shift"   }, "l",     function () awful.tag.incnmaster(-1)      end),
    awful.key({ modkey, "Control" }, "h",     function () awful.tag.incncol( 1)         end),
    awful.key({ modkey, "Control" }, "l",     function () awful.tag.incncol(-1)         end),
    awful.key({ modkey,           }, "space", function () awful.layout.inc(layouts,  1) end),
    awful.key({ modkey, "Shift"   }, "space", function () awful.layout.inc(layouts, -1) end),

    awful.key({ modkey, "Control" }, "n", awful.client.restore),

    -- Prompt
    awful.key({ modkey },            "r",     function () mypromptbox[mouse.screen]:run() end),

    -- Dmenu
    awful.key({ modkey },            "d",     function ()
    awful.util.spawn("dmenu_run -i -p 'Run :' -nb '" .. beautiful.bg_normal .. "' -nf '" .. beautiful.fg_normal .. "' -sb '" .. beautiful.bg_focus .. 
      "' -sf '" .. beautiful.fg_focus .. "'") 
    end),

    awful.key({ modkey }, "x",
              function ()
                  awful.prompt.run({ prompt = "Run Lua code: " },
                  mypromptbox[mouse.screen].widget,
                  awful.util.eval, nil,
                  awful.util.getdir("cache") .. "/history_eval")
              end),
    -- Menubar
    awful.key({ modkey }, "p", function() menubar.show() end),

    -- Raccourcis personnels
    awful.key({ modkey, "Control"}, "q", function () awful.util.spawn("sudo shutdown -h now") end),
    awful.key({ modkey, "Control"}, "s", function () awful.util.spawn("sudo /usr/sbin/pm-suspend") end),
    awful.key({ modkey, "Control"}, "d", function () awful.util.spawn("sudo reboot") end)
)

clientkeys = awful.util.table.join(
    awful.key({ modkey,           }, "f",      function (c) c.fullscreen = not c.fullscreen  end),
    awful.key({ modkey, "Shift"   }, "c",      function (c) c:kill()                         end),
    awful.key({ modkey, "Control" }, "space",  awful.client.floating.toggle                     ),
    awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end),
    awful.key({ modkey,           }, "o",      awful.client.movetoscreen                        ),
    awful.key({ modkey,           }, "t",      function (c) c.ontop = not c.ontop            end),
    awful.key({ modkey,           }, "n",
        function (c)
            -- The client currently has the input focus, so it cannot be
            -- minimized, since minimized clients can't have the focus.
            c.minimized = true
        end),
    awful.key({ modkey,           }, "m",
        function (c)
            c.maximized_horizontal = not c.maximized_horizontal
            c.maximized_vertical   = not c.maximized_vertical
        end)
)

-- Compute the maximum number of digit we need, limited to 9
keynumber = 0
for s = 1, screen.count() do
   keynumber = math.min(9, math.max(#tags[s], keynumber))
end

-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it works on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
for i = 1, keynumber do
    globalkeys = awful.util.table.join(globalkeys,
        awful.key({ modkey }, "#" .. i + 9,
                  function ()
                        local screen = mouse.screen
                        if tags[screen][i] then
                            awful.tag.viewonly(tags[screen][i])
                        end
                  end),
        awful.key({ modkey, "Control" }, "#" .. i + 9,
                  function ()
                      local screen = mouse.screen
                      if tags[screen][i] then
                          awful.tag.viewtoggle(tags[screen][i])
                      end
                  end),
        awful.key({ modkey, "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus and tags[client.focus.screen][i] then
                          awful.client.movetotag(tags[client.focus.screen][i])
                      end
                  end),
        awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
                  function ()
                      if client.focus and tags[client.focus.screen][i] then
                          awful.client.toggletag(tags[client.focus.screen][i])
                      end
                  end))
end

clientbuttons = awful.util.table.join(
    awful.button({ }, 1, function (c) client.focus = c; c:raise() end),
    awful.button({ modkey }, 1, awful.mouse.client.move),
    awful.button({ modkey }, 3, awful.mouse.client.resize))

-- Set keys
root.keys(globalkeys)
-- }}}

-- {{{ Rules
awful.rules.rules = {
    -- All clients will match this rule.
    { rule = { },
      properties = { tag = tags[1][6],
                     border_width = beautiful.border_width,
                     border_color = beautiful.border_normal,
                     focus = awful.client.focus.filter,
                     keys = clientkeys,
                     buttons = clientbuttons } },
    { rule = { class = "net-minecraft-LaucherFrame"},
      properties = { floating = false, switchtotag = true } },
    { rule = { class = "sun-awt-X11-XFramePeer"},
      properties = { floating = false } },
    { rule = { class = "MPlayer" },
      properties = { floating = true,
                     tag = tags[1][5], switchtotag = true } },
    { rule = { class = "pinentry" },
      properties = { floating = true, switchtotag = true } },
    { rule = { class = "gimp" },
      properties = { floating = true, switchtotag = true } },
    -- Applications sur le tag dev de l'�cran 1
    { rule = { class = "subl" },
     properties = { tag = tags[1][1],
                    floating = false, switchtotag = true } },
    -- Applications sur le tag web de l'�cran 1
    { rule = { class = "Firefox" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    { rule = { class = "Chromium" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    { rule = { class = "chromium" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    { rule = { class = "Opera" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    { rule = { class = "opera" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    { rule = { class = "evolution" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    { rule = { class = "Evolution" },
     properties = { tag = tags[1][2],
                    floating = false, switchtotag = true } },
    -- Applications sur le tag ter de l'�cran 1
    -- { rule = { class = "gnome-terminal" },
     -- properties = { tag = tags[1][3] } },
    -- { rule = { class = "Gnome-terminal" },
     -- properties = { tag = tags[1][3] } },
    { rule = { class = "urxvt" },
     properties = { tag = tags[1][3], switchtotag = true } },
    { rule = { class = "URxvt" },
     properties = { tag = tags[1][3], switchtotag = true } },
    -- Applications sur le tag off de l'�cran 1
    { rule = { class = "libreoffice" },
     properties = { tag = tags[1][4],
                    floating = false, switchtotag = true } },
    -- Applications sur le tag med de l'�cran 1
    { rule = { class = "vlc" },
      properties = { tag = tags[1][5],
                     floating = true, switchtotag = true } },
    { rule = { class = "Vlc" },
      properties = { tag = tags[1][5],
                     floating = true, switchtotag = true } },
    { rule = { class = "Download"},  
      properties = { floating = true } },
    { rule = { class = "Dialog"},
      properties = { floating = true } },
}


-- }}}

-- {{{ Signals
-- Signal function to execute when a new client appears.
client.connect_signal("manage", function (c, startup)
    -- Enable sloppy focus
    c:connect_signal("mouse::enter", function(c)
        if awful.layout.get(c.screen) ~= awful.layout.suit.magnifier
            and awful.client.focus.filter(c) then
            client.focus = c
        end
    end)

    if not startup then
        -- Set the windows at the slave,
        -- i.e. put it at the end of others instead of setting it master.
        -- awful.client.setslave(c)

        -- Put windows in a smart way, only if they does not set an initial position.
        if not c.size_hints.user_position and not c.size_hints.program_position then
            awful.placement.no_overlap(c)
            awful.placement.no_offscreen(c)
        end
    end

    local titlebars_enabled = false
    if titlebars_enabled and (c.type == "normal" or c.type == "dialog") then
        -- Widgets that are aligned to the left
        local left_layout = wibox.layout.fixed.horizontal()
        left_layout:add(awful.titlebar.widget.iconwidget(c))

        -- Widgets that are aligned to the right
        local right_layout = wibox.layout.fixed.horizontal()
        right_layout:add(awful.titlebar.widget.floatingbutton(c))
        right_layout:add(awful.titlebar.widget.maximizedbutton(c))
        right_layout:add(awful.titlebar.widget.stickybutton(c))
        right_layout:add(awful.titlebar.widget.ontopbutton(c))
        right_layout:add(awful.titlebar.widget.closebutton(c))

        -- The title goes in the middle
        local title = awful.titlebar.widget.titlewidget(c)
        title:buttons(awful.util.table.join(
                awful.button({ }, 1, function()
                    client.focus = c
                    c:raise()
                    awful.mouse.client.move(c)
                end),
                awful.button({ }, 3, function()
                    client.focus = c
                    c:raise()
                    awful.mouse.client.resize(c)
                end)
                ))

        -- Now bring it all together
        local layout = wibox.layout.align.horizontal()
        layout:set_left(left_layout)
        layout:set_right(right_layout)
        layout:set_middle(title)

        awful.titlebar(c):set_widget(layout)
    end
end)

client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
awful.util.spawn_with_shell("wmname LG3D")
-- }}}

Le theme.lua :

---------------------------
-- Default awesome theme --
---------------------------

theme = 

theme.font          = "SF Intermosaic 6"

theme.bg_normal     = "#280f0a"
theme.bg_focus      = "#2f2f2f"
theme.bg_urgent     = "#ff0000"
theme.bg_minimize   = "#444444"
theme.bg_systray    = theme.bg_normal

theme.fg_normal     = "#de8221"
theme.fg_focus      = "#fdb972"
theme.fg_urgent     = "#ffffff"
theme.fg_minimize   = "#ffffff"

theme.border_width  = 0
theme.border_normal = "#000000"
theme.border_focus  = "#2f2f2f"
theme.border_marked = "#91231c"

-- There are other variable sets
-- overriding the default one when
-- defined, the sets are:
-- [taglist|tasklist]_[bg|fg]_[focus|urgent]
-- titlebar_[bg|fg]_[normal|focus]
-- tooltip_[font|opacity|fg_color|bg_color|border_width|border_color]
-- mouse_finder_[color|timeout|animate_timeout|radius|factor]
-- Example:
--theme.taglist_bg_focus = "#ff0000"

-- Display the taglist squares
theme.taglist_squares_sel   = ".themes/awesome/default/taglist/squarefw.png"
theme.taglist_squares_unsel = ".themes/awesome/default/taglist/squarew.png"

-- Variables set for theming the menu:
-- menu_[bg|fg]_[normal|focus]
-- menu_[border_color|border_width]
theme.menu_submenu_icon = "/usr/share/awesome/default/submenu.png"
theme.menu_height = 12
theme.menu_width  = 100

-- You can add as many variables as
-- you wish and access them by using
-- beautiful.variable in your rc.lua
--theme.bg_widget = "#cc0000"

-- Define the image to load
theme.titlebar_close_button_normal = "/usr/share/awesome/themes/default/titlebar/close_normal.png"
theme.titlebar_close_button_focus  = "/usr/share/awesome/themes/default/titlebar/close_focus.png"

theme.titlebar_ontop_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/ontop_normal_inactive.png"
theme.titlebar_ontop_button_focus_inactive  = "/usr/share/awesome/themes/default/titlebar/ontop_focus_inactive.png"
theme.titlebar_ontop_button_normal_active = "/usr/share/awesome/themes/default/titlebar/ontop_normal_active.png"
theme.titlebar_ontop_button_focus_active  = "/usr/share/awesome/themes/default/titlebar/ontop_focus_active.png"

theme.titlebar_sticky_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/sticky_normal_inactive.png"
theme.titlebar_sticky_button_focus_inactive  = "/usr/share/awesome/themes/default/titlebar/sticky_focus_inactive.png"
theme.titlebar_sticky_button_normal_active = "/usr/share/awesome/themes/default/titlebar/sticky_normal_active.png"
theme.titlebar_sticky_button_focus_active  = "/usr/share/awesome/themes/default/titlebar/sticky_focus_active.png"

theme.titlebar_floating_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/floating_normal_inactive.png"
theme.titlebar_floating_button_focus_inactive  = "/usr/share/awesome/themes/default/titlebar/floating_focus_inactive.png"
theme.titlebar_floating_button_normal_active = "/usr/share/awesome/themes/default/titlebar/floating_normal_active.png"
theme.titlebar_floating_button_focus_active  = "/usr/share/awesome/themes/default/titlebar/floating_focus_active.png"

theme.titlebar_maximized_button_normal_inactive = "/usr/share/awesome/themes/default/titlebar/maximized_normal_inactive.png"
theme.titlebar_maximized_button_focus_inactive  = "/usr/share/awesome/themes/default/titlebar/maximized_focus_inactive.png"
theme.titlebar_maximized_button_normal_active = "/usr/share/awesome/themes/default/titlebar/maximized_normal_active.png"
theme.titlebar_maximized_button_focus_active  = "/usr/share/awesome/themes/default/titlebar/maximized_focus_active.png"

theme.wallpaper = "Images/wallpapers/iron_man_wall.jpg"

-- You can use your own layout icons like this:
theme.layout_fairh = "/usr/share/awesome/themes/default/layouts/fairhw.png"
theme.layout_fairv = "/usr/share/awesome/themes/default/layouts/fairvw.png"
theme.layout_floating  = "/usr/share/awesome/themes/default/layouts/floatingw.png"
theme.layout_magnifier = "/usr/share/awesome/themes/default/layouts/magnifierw.png"
theme.layout_max = "/usr/share/awesome/themes/default/layouts/maxw.png"
theme.layout_fullscreen = "/usr/share/awesome/themes/default/layouts/fullscreenw.png"
theme.layout_tilebottom = "/usr/share/awesome/themes/default/layouts/tilebottomw.png"
theme.layout_tileleft   = "/usr/share/awesome/themes/default/layouts/tileleftw.png"
theme.layout_tile = "/usr/share/awesome/themes/default/layouts/tilew.png"
theme.layout_tiletop = "/usr/share/awesome/themes/default/layouts/tiletopw.png"
theme.layout_spiral  = "/usr/share/awesome/themes/default/layouts/spiralw.png"
theme.layout_dwindle = "/usr/share/awesome/themes/default/layouts/dwindlew.png"

theme.awesome_icon = "/usr/share/awesome/icons/awesome16.png"

-- Define the icon theme for application icons. If not set then the icons 
-- from /usr/share/icons and /usr/share/icons/hicolor will be used.
theme.icon_theme = nil

return theme
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80

(L'image utilisée pour les bureaux virtuel est un simple point dans un png transparent)

Le thème GTK est le suivant :

http://thrynk.deviantart.com/art/Mirev2-GTK3-323172555

Enfin, la police utilisée est SF Intermozaic en 6px.

C'est tout !

Écrit le dimanche 2 juin 2013,0 commentaire(s).

Récupérer des données d'un VG dispersé sur plusieurs disques

file_disc

Sommaire :

  1. État des lieux,
  2. Créer une image disque,
  3. L'utilitaire dd,
  4. L'utilitaire ddrescue,
  5. Montage des images,
  6. Les volumes logiques,
  7. Conclusion,
  8. Références.

État des lieux

Récemment j'ai été confronté à un problème de taille :

Mon serveur de fichier m'a lâché, avec dessus 1To de données. Alimentation HS et un disque avec des erreurs d'entrée / sortie.

Le problème aurait pu rester simple si je n'avais pas mis en place un VG éclaté sur trois disques durs dont 1 en scsi et 2 en sata.

Mais comme chaque problème à toujours sa solution sous GNU/Linux je vous propose la méthode que j'ai utilisé pour récupérer mes données.

Créer une image disque

Le premier réflexe à avoir pour tout problème concernant le stockage est de créer des images. En effet, travailler sur une image en plus d'être plus rapide, est plus sécurisé.
Si le fait de récupérer des données sur un média défecteux risque de dégrader celui-ci, l'image ne bougera pas et vous ne risquez pas de formater par erreur.

Pour cette étape, j'ai utilisé dd1 et GNU ddrescue2.

dd est réservé aux disques sains, en effet, à la première erreur celui-ci stoppera net. Mais sur un média propre je le trouve plus rapide.

ddrescue lui sera donc utilisé sur les disques contenant des erreurs. Cet outil est un peu le sauveur des médias HS. Non seulement il va continuer à créer l'image en évitant les secteurs erronés, mais en plus va tenter de les lire avec des tailles de blocs différents pour essayer de récupérer ceux-ci.

Le temps nécéssaire à la création des images sera bien-sûr en fonction de la taille de votre média. À titre d'exemple, il m'a fallut 2h pour les disques scsi en réseau, 30 minutes en local, 5 heures pour 500 gigas avec 3 secteurs HS et 8 heures pour 500 gigas avec plus de 130 secteurs HS.

L'utilitaire dd

Pour les disques scsi j'ai monté la carte sur une autre machine puis j'ai booté sur un liveUSB Fedora17. La machine de sauvegarde étant à distance je suis passé par le réseau :

Sur un terminal :

dd if=/dev/sdf | ssh user@192.168.1.x "dd of=/media/hdd/save/scsi01.img"
dd if=/dev/sdh | ssh user@192.168.1.x "dd of=/media/hdd/save/scsi02.img"

Ici, rien de compliqué : if= -> le média à sauvegarder of= -> l'image à créer. J'utilise un pipe pour envoyer les données via ssh puis dd sur la machine distante pour compléter la commande.

L'extension est accessoire et ne sert simplement qu'à se repérer plus facilement. De ce fait vous pouvez très bien ne rien mettre, sous GNU/Linux ce n'est pas un souci3 !

L'utilitaire ddrescue

Pour les disques sata avec les I/O errors, on va d'abord sauvergarder les secteurs sains du disque :

ddrescue -B -v -n /dev/sdb /media/save/seagate.img /media/save/seagate.log

Explication de la commande4 :

l'option la plus importante ici est l'option -n, elle nous permet de ne copier que les secteurs sain. Ainsi ddrescue saute tout ce qui ne va pas et crée une première image.

L'option -B permet d'avoir les tailles et dimensions en binaire

L'option -v pour avoir un affichage de ce qu'il se passe.

Le premier paramètre est le disque à sauvegarder (non monté),

Le second est l'image dans laquelle sauvegarder les données,

Afin de pouvoir travailler sur la même image il faut spécifier à l'utilitaire un fichier de log qui sera déclaré à chaque appel de la commande sur un même disque. Ce fichier enregistrera les zones défectueuses, il sera ainsi possible revenir dessus plus tard pour travailler dessus sans à avoir à tout sauvegarder de nouveau.

ddrescue -B -v -c 16 -r 2 /dev/sdb /media/save/seagate.img /media/save/seagate.log

L'option -c 16 permet de lire les secteurs corrompus par blocs de 16 secteurs (par défaut 128).

L'option -r 2 pour faire deux passes.

Si vous avez toujours des erreurs, il faut refaire une lecture de celles-ci secteur par secteur (et avec 5 passes) afin de récupérer le maximum de données, et ce autant de fois que nécéssaire pour que ddrecue vous affiche un joli "finished !".

ddrescue -B -v -c 1 -r 5 /dev/sdb /media/save/seagate.img /media/save/seagate.log

Pour mon disque contenant plus de 130 I/O erros, j'ai du le faire dix fois (donc 50 passes !) et toutes les données ont été récupérées.

Montage des images

Cette étape consiste à monter les images disque sur la machine de sauvegarde. Non pas un montage classique de système de fichiers car ça ne fonctionnerait pas avec des VG mais un montage en "bloc disque" qui se compare à une représentation d'un disque physique dans /dev afin d'avoir accès aux commandes lvm dessus. C'est à ma connaissance le seul moyen de travailler des images de volumes logiques.

Pour pouvoir monter ces images en bloc nous avons besoin de l'utilitaire losetup5 qui permet de créer des disques dur virtuels à partir d'image.

Il y a deux façon de monter l'image, la première, plus simple est disponible si le module loop n'a pas été compilé en dur dans le noyau, quand à la seconde, je ne l'expliquerai pas ici (ne l'ayant pas utilisée) je vous laisse le soin de suivre le lien dans mes références6.

Si vous avez plusieurs partitions, afin qu'elle soient toutes disponibles, il faut décharger puis charger le module loop avec les bons paramètres :

modprobe -r loop modprobe & modprobe loop max_part=63

max_part=63 demander à loop de monter jusqu'à 63 partitions d'une image (on a de quoi voir venir ;) )

Ceci fait, il ne reste qu'à monter les différentes images :

losetup /dev/loop0 /media/hdd/save/scsi01.img
losetup /dev/loop1 /media/hdd/save/scsi02.img
losetup /dev/loop2 /media/hdd/save/seagate.img
losetup /dev/loop3 /media/hdd/save/western.img

Si le besoin de vouloir des explications se faisait resentir : /dev/loop0 => la boucle ou l'on veut monter l'image disque et ensuite le chemin vers l'image concernée.

Les volumes logiques

Si tout c'est bien passé, vous devriez voir apparaitre vos disques comme non monté. Ou comme ici, voir votre groupe de volumes logiques dans /dev/mapper/

Si c'est le cas, Il ne vous reste maintenant qu'à travailler vos partitions de manière tout à fait classique avec les outils lvm7.

Pour commencer il faut scanner les disques :

pvscan

Si le groupe apparait il suffit de le charger :

vgchange -ay mongroupe

ou simplement vgchange -ay si vous n'avez qu'un groupe sur vos disques

Et il ne nous reste plus qu'à lister et monter les volumes logiques :

lvs

Puis :

mount /dev/mapper/myvol /media/source

À ce stade, les données devraient être présentes.

Conclusion

Comme d'habitude sous GNU/Linux l'impossible n'existe pas. Et avec ces utilitaires indispensables, nous pouvons facilement récupérer nos chères données !

Il faut certes un peu de temps, mais qu'est ce que sont quelques heures de travail pour nos précieuses photos de famille.

Références

1 https://www.gnu.org/software/coreutils/manual/html_node/dd-invocation.html
2 https://www.gnu.org/software/ddrescue/manual/ddrescue_manual.html
3 https://fr.wikipedia.org/wiki/Extension_de_nom_de_fichier
4 http://forum.pcastuces.com/recuperation_de_donnees_sous_linux_ddrescue__tuto-f1s120710.htm?page=1
5 https://en.wikipedia.org/wiki/Loop_device
6 http://www.thegibson.org/blog/archives/467
7 https://fr.wikipedia.org/wiki/Gestion_par_volumes_logiques

Écrit le lundi 18 février 2013,3 commentaire(s).

Vous êtes accroc !

drugs

 

Si, quand vous allez à votre PC, le premier réflexe que vous avez c'est de mettre les mains sur le clavier, les 10 doigts prenant naturellement la position de frappe, avant de vous rappeler que vous avez une souris.

Si vous n'avez pas installé de splashscreen afin de vérifier le bon déroulement de votre init.

Si vous devez taper un mot de passe de plus de 10 caractères qui ressemble plus à une regex qu'à un mémo facile à retenir.

Si le premier programme lancé est un émulateur de terminal ou pire ! Un coup de [Ctrl] [Alt] [F1].

Si, la journée à peine entamée, vous êtes plus au fait des derniers commit sur votre noyau préféré que des nouvelles mesures d'austérité d'économies prises la nuit dernière dans votre pays.

Si la première chose que vous faites pendant votre pause c'est de vérifier votre boite mail / agrégateur de flux en pensant à votre dernier projet perso qui va surement peupler /dev/null dans quelques semaines.

Si, quand vous devez faire des manipulation fastidieuses dans votre /home pour retrouver les photos, musiques, que sais-je, afin de générer truc bidule, vous préférez faire un .sh qui vous aura pris autant de temps que de traiter à la main, qui ne vous servira qu'une fois, mais... On ne sait jamais.

Si, au moment ou vous envoyez un mail, il vous arrive de vous imaginer le chemin que celui-ci va parcourir: de votre client en passant par votre serveur postfix, switch, routeur, les entrailles de votre FAI, etc ...

Si, quand votre moitié / ami(e) vous demande de lui envoyer un fichier, le premier réflexe que vous avez c'est d'ouvrir un terminal et de taper scp ...  [ctrl][shift][d] "Rhaaaa ! Il est sous Windows ! Elle est ou cette fichue clé USB" !

Si quand vous décidez de regarder un film sur votre PC branché à la TV, vous vous rendez compte que le dernier pilote nouveau / radeon fait encore des siennes car vous avez voulu tester une feature de votre GPU uniquement disponible dans la version BETA de la branche testing la semaine dernière, en vous promettant de tout remettre en ordre après les tests.

Si, quand vous êtes au téléphone avec un technicien car votre connexion internet est en panne, c'est vous qui lui donnez le type de panne avec le code d'erreur et lui expliquez les procédures qu'il doit engager suivant le cahier des charges de votre FAI.

Si, quand vous jouez à un jeu vidéo, vous comprenez qu'il est scripté et résultat des courses vous ne vous faites plus toucher car vous savez exactement ce qui va arriver et quand (ou alors vous y allez comme un gros bourrin parce que vous vous dites qu'il n'y a pas que les autres qui doivent mourir).

Si, quand vous passez devant votre modem / point d'accès, vous vous dites qu'il y a quelque chose de louche car la led "ACT" clignote frénétiquement alors que vos serveurs ne transmettent pas de paquets par cette route et que votre PC est éteint.

Si, pendant une série ou un film, vous ne pouvez pas vous empêcher de faire l'inventaire de tout le matériel High Tech présent allant parfois même jusque énoncer à haute voix les numéros de version.

Si, dans une soirée avec des gens lambda, vous n'arrivez pas obtenir l'adhésion de l'assemblée sur le bienfait de la GPLv3 et du matériel open source, juste parce que l'hôte vous a fait part de son mécontentement au sujet de sa machine à café dernier cri tombée en panne au lendemain de la garantie.

Si, quand vous prenez de l'argent au guichet, vous n'êtes pas rassuré car la machine qui vous donne vos billet tourne sous windows.

Si votre entourage est persuadé que vous êtes un hacker comme dans matrix alors que vous codez simplement une commande en PHP / Python etc... sur votre SublimeText2 avec le thème Monokai.

Si, parfois quand vous vous couchez, vous trouvez la solution à un bug qui vous a bloqué toute la journée.

Si, à 3 heures du matin vous vous dites "encore 5 minutes et je me couche" et ce depuis trois heure.

Si, quand vous êtes obligé d'arrêter votre PC en appuyer sur le bouton pendant 30 secondes, vous vous imaginez les têtes de votre disque crasher lamentablement et vous souffrez.

Si, vous remplissez au moins 80% de ces contextes.

Vous n'êtes pas seul (mais ça ne se soigne pas ;) ).

Écrit le jeudi 31 janvier 2013,0 commentaire(s).

Faire prendre la mayonnaise

microscope

 

Le site avance doucement.

Je partage en paralèlle quelques article / lien que je met ici sur mon profil google+ ainsi, le jour ou je décide de basculer définitivement sur le blog, il n'y aura qu'à supprimer le profil google+.

Mais avant il y a encore du travail ici !

Je pense ajouter un module de statistiques prochainement. Comme ça pas de service tiers (je n'en met aucun) et par la même aucune dépendance de quoi que ce soit.

Si vous voyez des bugs n'hésitez ma à me le noter en commentaire (certains sont connus mais le manque de temps fait qu'ils sont corrigé lentement).

Autre chose, si vous constatez des indisponibilités sur le site, c'est normal car souvent je teste des nouvelles choses et parfois ça plante ;) En théorie, j'ai testé sur le serveur de dev mais parfois un oubli et hop, page blanche !

@ bientôt !

Écrit le lundi 14 janvier 2013,0 commentaire(s).