Environnement d’exécution différents entre l’utilisateur et le cron de l’utilisateur

Une simple brève pour rappeler qu’un utilisateur que ce soit root ou un autre n’a pas le même environnement d’exécution que le cron de cet utilisateur. En d’autres termes ce n’est pas parce qu’une commande s’exécute correctement lorsque que l’on est connecté en tant que l’utilisateur X que cette même commande s’exécutera correctement dans un cron de l’utilisateur X (test fait sous debian).

L’environnement étant différent l’accès à certaines commandes ne se fait pas toujours de la même façon.
Ceux sont souvent des scripts peu classiques, par exemple un script de renouvellement automatique pour let’s encrypt comme proposé ici, s’exécutera très bien en root en ne tapant pas le chemin complet vers le script mais pas via le cron de root si vous n’indiquez pas le chemin complet vers le script. Il faut donc penser à tester ces crons, de manière quasi systématique pour être certains de la bonne exécution de ceux-ci.

Et voilà 😉

Récupérer les dates de début et de fin d’un certificat ssl en ligne de commande

Si vous avez besoin de récupérer rapidement et simplement les dates de début et de fin de certificat ssl pour par exemple vérifier le temps qu’il vous reste avant l’expiration il y a plusieurs solutions :

La solution simple via le navigateur : Vous vous connectez sur l’url à vérifier et vous inspectez votre certificat à travers le navigateur, action simple et visuelle.

Oui mais pas facile à automatiser cela demande une action humaine.

Si vous souhaitez monitorer les dates de manière automatique vous pouvez passer par une ligne de commande qui vous retourne les dates du certificat, la voici :
echo | openssl s_client -showcerts -servername monUrl.fr -connect monUrl.fr:443 2>/dev/null | openssl x509 -inform pem -noout -text | egrep "Not After :|Not Before:"

Cette ligne de commande vous sort ce résultat :

Not Before: Mar 24 07:28:00 2017 GMT
Not After : Jun 22 07:28:00 2017 GMT

Il est simple par la suite de récupérer les 2 dates (Not before : date d’émission du certificat, Not after : date d’expiration du certificat) et de les stocker comme bon vous semble et de faire les calculs qui vont bien pour vous prévenir quand l’échéance du renouvellement arrive.

Et voilà 😉

Source : http://serverfault.com/questions/661978/displaying-a-remote-ssl-certificate-details-using-cli-tools

Quelles technologies se cachent derrière le format de paquets snaps « by Canonical » ?

Principe de fonctionnement des snaps

Contrairement aux paquets habituels sous Linux, les snaps ne partagent pas leurs dépendances. C’est ce qui explique que les logiciels empaquetés dans des snaps soient indépendants du système. Les paquets sont bien plus lourds et chaque logiciel lancé chargera en RAM l’intégralité de ses dépendances sans les partager.

Un paquet snap est une archive SquashFS montée en lecture seule, exactement comme un Live CD sous Linux. Les paquets sont signés comme les dépôts et mis à jours de manière transactionnelle. Les mises à jours n’ajoutent que les différences entre la nouvelle version et l’actuelle, sans retélécharger intégralement le paquet.

Chaque paquet dispose d’autorisations précises pour accéder à d’autres applications, services ou fonctionnalités du système d’exploitation (via AppArmor). Leurs dossiers « tmp » sont séparés.

Un snap peut difficilement endommager ou déstabiliser le système :

Contrairement aux conteneurs à la mode, type docker et compagnie, les paquets sont montés dans des dossiers isolés par confinement, ils utilisent donc le noyau du système et n’ont pas d’interface réseau individuelle requérant une gestion NAT compliquée.

Le système Ubuntu complet a été découpé et mis dans des snaps dans l’édition Ubuntu Core. Voici à quoi ressemble l’OS actuel :

Et voici Ubunutu Core :

Sur Ubuntu Core, les .deb ne disparaissent pas du système pour autant mais ne sont plus la voie principale pour installer des paquets, puisqu’apt semble placé dans un conteneur (assez peu d’info trouvée à ce sujet). Dans un premier temps en revanche, l’option la plus souple semble d’installer snapd (l’apt des snaps) sur un système non-snappy tel que l’Ubuntu Desktop classique, ce qui vous prive toutefois du déploiement facilité de mises à jour d’Ubuntu Core.

Vous pouvez trouver plus d’informations en écoutant cette conférence de l’Ubuntu Party de Paris.

Que sont les paquets Snaps développés par Canonical pour la portabilité ?

Introduction

Avec son désir d’interface graphique « convergeante », c’est à dire adaptative entre des tailles d’écran très différentes, Canonical doit faire face à des problèmes de portabilité de ses applications.

Le monde mobile a ceci de particulier que les périphériques sont vendus préinstallés, à des utilisateurs néophytes, le plus souvent sur l’architecture ARM réputée plus complexe que le monde standardisé des processeurs x86 de bureau. Mettre le téléphone d’un utilisateur à jour et à distance relève dès lors du défis. L’univers Android le connait bien, puisque les téléphones reçoivent au mieux quelques mises à jour avant d’être abandonnés.

L’entreprise Canonical veut éviter de tomber dans ce piège et pouvoir gérer elle même les mises à jours de tous les périphériques utilisant son OS, mobiles comme ordinateurs de bureau. Cela lui permettra d’une part d’éviter une fragmentation importante des versions de son OS sur le marché mobile, d’autre part d’étendre la prise en charge de ses applications sur ordinateur de bureau vers d’autres distributions Linux.

Des paquets universels

La solution envisagée repose sur la création d’un format de paquet universel, différent de deb ou rpm, capable de s’installer sur tout système d’exploitation Linux ayant installé le logiciel snapd, équivalent d’apt. Snappy est déjà disponible dans Gentoo, Fedora, Arch Linux, Debian etc.

Puisque ces paquets sont portables, il existe un site expliquant comment packager des applications ainsi qu’un store d’applications empaquetées.

Microsoft Azure supporte Ubuntu Snappy depuis fin 2014, une version serveur d’Ubuntu utilisant les snaps, et Ubuntu Desktop les supporte depuis la version 16.04.

L’intérêt pour les développeurs

Tout le casse tête pour un développeur d’applications souhaitant prendre en charge l’univers Linux est de devoir s’intéresser à chaque distribution individuellement, empaqueter son logiciel en .deb, .rpm et continuer avec les nombreux autres formats, tout en s’impliquant dans un processus long et complexe de maintient de ses paquets dans les dépôts officiels des distributions qu’il veut toucher, et recommencer lors de chaque mise à jour desdites distributions, là où un .exe sous Windows peut fonctionner de XP à Windows 10 sans avoir eu à s’en soucier.

Les paquets snaps viennent de résoudre cette problématique.

L’intérêt pour les utilisateurs

En revanche, côté utilisateur, les .deb ont beaucoup d’avantages :

  • On peut les installer via un store applicatif (apt, la logithèque Ubuntu, le centre de logiciels Gnome, celui de KDE etc)
  • L’installation de paquets sur le système requiers les droits « root »
  • Tous les paquets sont vérifiés et signés, donc sûrs, leur présence dans un dépôt officiel garanti qu’ils soient libres et que ce soit bien la version officielle du développeur initial (et non trafiquée par Sourceforge)
  • Les mises à jours de tous les logiciels sont centralisées dans un seul outil, ce dont les utilisateurs de Windows rêvent depuis sa création
  • Les dépendances d’un logiciel sont partagées, rendant son téléchargement initial ultra léger (plus on a de logiciels installés plus on a de change d’avoir déjà toutes les bibliothèques les plus populaires). Autre avantage, la consommation en RAM est réduite à son minimum car une bibliothèque n’est chargée qu’une fois pour plusieurs logiciels (GTK est un bon exemple). Le système est donc rapide pour installer, lancer et mettre à jour ses logiciels.

Et quelques inconvénients :

  • Les versions des logiciels sont figées dans les dépôts, on a rarement la dernière version du développeur, seulement les mises à jour pour la version en cours
  • Ajouter des dépôts externe créé irrémédiablement de l’instabilité, en proposant parfois des mises à jour de dépendances
  • Installer un logiciel hors des dépôts n’est pas une facilité et le mettre à jour est plus compliqué

L’avantage des paquets snaps pour l’utilisateur est la possibilité d’avoir les dernières versions disponibles de chaque logiciel sans avoir à attendre la prochaine montée de version du système. Les paquets snaps pourraient convaincre des développeurs dont le logiciel fonctionne sous Linux de faire l’effort de l’empaqueter pour le distribuer et le maintenir. Certains logiciels comme l’interface Unity représentent actuellement un trop grand défi pour être empaquetés sur d’autres distributions. Enfin, les vieux logiciels abandonnés finissent souvent par ne plus avoir de paquets deb/rpm récents et ne peuvent plus être exécutés sur les distributions récentes à cause de leurs dépendances.

Les paquets snaps arrivent avec un inconvénient, en terme de poids et consommation en RAM. Pour savoir de quoi ils sont faits, lisez la suite !

Nokogiri : installer avec « Building native extensions » sous Mac OSX 10.12 Sierra

Si l’installation de la gem Nokogiri provoque une erreur telle que :

$ gem install nokogiri -v 1.6.7.1
Fetching: nokogiri-1.6.7.1.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
  ERROR: Failed to build gem native extension.

    current directory: /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/ext/nokogiri
/Users/username/.rvm/rubies/ruby-2.3.1/bin/ruby -r ./siteconf20170214-68028-185u3z7.rb extconf.rb
checking if the C compiler accepts ... yes
checking if the C compiler accepts -Wno-error=unused-command-line-argument-hard-error-in-future... no
Building nokogiri using packaged libraries.
Using mini_portile version 2.0.0
checking for iconv.h... yes
checking for gzdopen() in -lz... yes
checking for iconv using --with-opt-* flags... yes
************************************************************************
IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxml2-2.9.2
with the following patches applied:
  - 0001-Revert-Missing-initialization-for-the-catalog-module.patch
  - 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch
  - 0003-Stop-parsing-on-entities-boundaries-errors.patch
  - 0004-Cleanup-conditional-section-error-handling.patch
  - 0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch
  - 0006-Another-variation-of-overflow-in-Conditional-section.patch
  - 0007-Fix-an-error-in-previous-Conditional-section-patch.patch
  - 0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch
  - 0009-Updated-config.guess.patch
  - 0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch
  - 0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch
  - 0012-Avoid-processing-entities-after-encoding-conversion-.patch
  - 0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch
  - 0014-CVE-2015-5312-Another-entity-expansion-issue.patch
  - 0015-Add-xmlHaltParser-to-stop-the-parser.patch
  - 0016-Detect-incoherency-on-GROW.patch
  - 0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch
  - 0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install

Note, however, that nokogiri is not fully compatible with arbitrary
versions of libxml2 provided by OS/package vendors.
************************************************************************
Extracting libxml2-2.9.2.tar.gz into tmp/x86_64-apple-darwin15.0.0/ports/libxml2/2.9.2... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0001-Revert-Missing-initialization-for-the-catalog-module.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0003-Stop-parsing-on-entities-boundaries-errors.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0004-Cleanup-conditional-section-error-handling.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0005-CVE-2015-1819-Enforce-the-reader-to-run-in-constant-.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0006-Another-variation-of-overflow-in-Conditional-section.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0007-Fix-an-error-in-previous-Conditional-section-patch.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0008-CVE-2015-8035-Fix-XZ-compression-support-loop.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0009-Updated-config.guess.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0010-Fix-parsering-short-unclosed-comment-uninitialized-access.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0011-Avoid-extra-processing-of-MarkupDecl-when-EOF.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0012-Avoid-processing-entities-after-encoding-conversion-.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0013-CVE-2015-7497-Avoid-an-heap-buffer-overflow-in-xmlDi.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0014-CVE-2015-5312-Another-entity-expansion-issue.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0015-Add-xmlHaltParser-to-stop-the-parser.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0016-Detect-incoherency-on-GROW.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0017-CVE-2015-7500-Fix-memory-access-error-due-to-incorre.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxml2/0018-CVE-2015-8242-Buffer-overead-with-HTML-parser-in-pus.patch... OK
Running 'configure' for libxml2 2.9.2... OK
Running 'compile' for libxml2 2.9.2... OK
Running 'install' for libxml2 2.9.2... OK
Activating libxml2 2.9.2 (from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/ports/x86_64-apple-darwin15.0.0/libxml2/2.9.2)...
************************************************************************
IMPORTANT NOTICE:

Building Nokogiri with a packaged version of libxslt-1.1.28
with the following patches applied:
  - 0001-Adding-doc-update-related-to-1.1.28.patch
  - 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch
  - 0003-Initialize-pseudo-random-number-generator-with-curre.patch
  - 0004-EXSLT-function-str-replace-is-broken-as-is.patch
  - 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch
  - 0007-Separate-function-for-predicate-matching-in-patterns.patch
  - 0008-Fix-direct-pattern-matching.patch
  - 0009-Fix-certain-patterns-with-predicates.patch
  - 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch
  - 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch
  - 0014-Fix-for-bug-436589.patch
  - 0015-Fix-mkdir-for-mingw.patch
  - 0016-Fix-for-type-confusion-in-preprocessing-attributes.patch
  - 0017-Updated-config.guess.patch

Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:

    gem install nokogiri -- --use-system-libraries
        [--with-xml2-config=/path/to/xml2-config]
        [--with-xslt-config=/path/to/xslt-config]

If you are using Bundler, tell it to use the option:

    bundle config build.nokogiri --use-system-libraries
    bundle install
************************************************************************
Extracting libxslt-1.1.28.tar.gz into tmp/x86_64-apple-darwin15.0.0/ports/libxslt/1.1.28... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0008-Fix-direct-pattern-matching.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0014-Fix-for-bug-436589.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0015-Fix-mkdir-for-mingw.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0016-Fix-for-type-confusion-in-preprocessing-attributes.patch... OK
Running git apply with /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/patches/libxslt/0017-Updated-config.guess.patch... OK
Running 'configure' for libxslt 1.1.28... OK
Running 'compile' for libxslt 1.1.28... ERROR, review '/Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1/ext/nokogiri/tmp/x86_64-apple-darwin15.0.0/ports/libxslt/1.1.28/compile.log' to see what happened. Last lines are:
========================================================================
                      ^
xsltutils.c:1876:24: note: expanded from macro 'XSLT_CLOCK'
#    define XSLT_CLOCK CLOCK_REALTIME
                       ^
xsltutils.c:1886:23: error: use of undeclared identifier 'CLOCK_REALTIME'
        clock_gettime(XSLT_CLOCK, &startup);
                      ^
xsltutils.c:1876:24: note: expanded from macro 'XSLT_CLOCK'
#    define XSLT_CLOCK CLOCK_REALTIME
                       ^
xsltutils.c:1890:19: error: use of undeclared identifier 'CLOCK_REALTIME'
    clock_gettime(XSLT_CLOCK, &cur);
                  ^
xsltutils.c:1876:24: note: expanded from macro 'XSLT_CLOCK'
#    define XSLT_CLOCK CLOCK_REALTIME
                       ^
1 warning and 3 errors generated.
make[2]: *** [xsltutils.lo] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2
========================================================================
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
  --with-opt-dir
  --with-opt-include
  --without-opt-include=${opt-dir}/include
  --with-opt-lib
  --without-opt-lib=${opt-dir}/lib
  --with-make-prog
  --without-make-prog
  --srcdir=.
  --curdir
  --ruby=/Users/username/.rvm/rubies/ruby-2.3.1/bin/$(RUBY_BASE_NAME)
  --help
  --clean
  --use-system-libraries
  --enable-static
  --disable-static
  --with-zlib-dir
  --without-zlib-dir
  --with-zlib-include
  --without-zlib-include=${zlib-dir}/include
  --with-zlib-lib
  --without-zlib-lib=${zlib-dir}/lib
  --enable-cross-build
  --disable-cross-build
/Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:366:in `block in execute': Failed to complete compile task (RuntimeError)
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:337:in `chdir'
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:337:in `execute'
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:111:in `compile'
  from /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/mini_portile2-2.0.0/lib/mini_portile2/mini_portile.rb:150:in `cook'
  from extconf.rb:289:in `block (2 levels) in process_recipe'
  from extconf.rb:182:in `block in chdir_for_build'
  from extconf.rb:181:in `chdir'
  from extconf.rb:181:in `chdir_for_build'
  from extconf.rb:288:in `block in process_recipe'
  from extconf.rb:187:in `tap'
  from extconf.rb:187:in `process_recipe'
  from extconf.rb:490:in `
' To see why this extension failed to compile, please check the mkmf.log which can be found here: /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/extensions/x86_64-darwin-15/2.3.0/nokogiri-1.6.7.1/mkmf.log extconf failed, exit code 1 Gem files will remain installed in /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/gems/nokogiri-1.6.7.1 for inspection. Results logged to /Users/username/.rvm/gems/ruby-2.3.1@test-gemset3/extensions/x86_64-darwin-15/2.3.0/nokogiri-1.6.7.1/gem_make.out

Vous pouvez essayer les solutions suivantes, en adaptant le numéro de version à celui voulu :
gem install nokogiri -v 1.6.8.1 -- --use-system-libraries
gem install nokogiri -v 1.6.8.1 -- --use-system-libraries=true --with-xml2-include=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/libxml2
brew uninstall libxml2 (fourni par Xcode) puis relancer gem install nokogiri -v 1.6.8.1 -- --use-system-libraries
brew reinstall xz --universal puis relancer gem install nokogiri -v 1.6.8.1 -- --use-system-libraries

Passenger, gestion des ressources avec plus de 6 applications

Erreur type rencontrée : This website is under heavy load, too many requests

Too many requests ?

Passenger contient dans sa configuration un paramètre PassengerMaxRequestQueueSize définissant le nombre de requêtes en attente à 100 par défaut.
Contrairement à ce que l’on pourrait penser, rallonger cette file d’attente n’est pas une bonne idée. Le serveur a une capacité à traiter un volume de requêtes simultanées donné. Lorsqu’il ne peut plus en traiter, les clients doivent alors patienter dans la file d’attente : lorsque le serveur a placé 100 requêtes en attente, toutes les prochaines recevront l’erreur « 503 Service Unavailable ».
Cette file d’attente est une sorte de tampon lors de montée en charge momentanée et non une solution durable. On peut en effet s’attendre à voir le temps d’attente devenir de plus en plus long à mesure que la file s’allonge, et des clients seront alors tentés de quitter ou de rafraichir leur page, augmentant le nombre de requêtes à traiter sans même en attendre la réponse.

Si le serveur ne peut plus faire face, il faut alors en changer ou augmenter ses ressources. Mais ce n’est pas la seule raison de l’apparition de notre erreur initiale.

Beaucoup d’appli, pool trop petit

Lorsque l’erreur « This website is under heavy load » apparait, vous pouvez soupçonner une autre cause qu’un nombre trop élevé de requêtes. C’est le cas si vous venez de lancer des actions gourmandes sur plusieurs applications, comme dans notre cas.

Ce qu’explique cet article c’est la manière dont Passenger gère des applications. Par nature, une application Rails ne peut gérer qu’une requête à la fois. Pour paralléliser le traitement des requêtes, Passenger créé des processus pour chaque nouvelle requête, dans lesquels l’application est lancée à nouveau.
passenger-request_load_balancing
Un processus ne peut donc traiter qu’une requête à la fois, mais Passenger n’attribue pas de limite de création de processus et il s’assure qu’au moins un processus reste toujours actif par application. Les processus inactifs depuis plus de 5 minutes sont éteints.

En revanche, Passenger définit une limite globale du nombre de processus actifs, par défaut de 6 processus, qui fait autorité sur tout autre paramètre de configuration. Cela signifie qu’avec 7 applications, Passenger passera son temps à jongler entre les processus actifs pour n’en garder que 6, éteignant un processus pour en démarrer un autre.

Par défaut, si une action telle qu’un import de données est lancée simultanément sur 6 applications, les 6 processus actifs ne peuvent plus être « tués » car ils sont en cours de traitement long et la queue va se remplir très rapidement. Le paramètre « passengermaxpoolsize » est donc à configurer en fonction du nombre d’applications que Passenger gère, selon vos besoins et la capacité du serveur.

Pour ne pas manquer de mémoire vive, la documentation conseille de garder 25% de la RAM totale pour l’OS. On divise les 75% de RAM restants par la consommation en RAM totale de toutes les applications (attention aux unités), ce qui indique combien de processus le serveur est en théorie capable d’exécuter.

Il est possible de surveiller la consommation en ressources de chaque application via la commande passenger-status. On y trouve la longueur courante de la queue, bien qu’il ne soit pas possible de la visualiser. Il est cependant possible d’afficher les requêtes en cours de traitement avec passenger-status --show=requests.

Jouons avec les multiplexeurs de terminaux sous Debian

Aujourd’hui nous parlerons de screen, byobu, tmux et tmate, quatre outils en ligne de commande permettant de rendre un terminal persistant dans un processus.

GNU Screen

« Il permet à un utilisateur d’accéder à de multiples sessions de terminal à l’intérieur d’une simple fenêtre de terminal, ou d’une session distante typiquement lancée par SSH » (Wikipedia). Il s’installe avec apt-get install screen.

Créer une nouvelle session : screen ou screen -S exemple. La session remplace le terminal courant par un terminal virtuel vivant dans un processus. Utiliser Ctrl+d tuera la session. La commande screen -d ou Ctrl+a d détachera la session et vous ramènera sur votre terminal initial, sans fermer la session. Le terminal virtuel continue sa vie dans un processus. Les sessions sont isolées par utilisateur système.
Lister les sessions : screen -ls.
Se connecter à une session : screen -r ou screen -r exemple.
Détacher une session de l’extérieur : screen -d, Ctrl+a d ou screen -d exemple.
Rejoindre une session attachée : screen -x ou screen -x exemple. Cela permet de visualiser de plusieurs endroits le contenu d’un unique terminal.

Il n’est pas possible d’imbriquer des sessions, bien qu’on puisse les lister depuis n’importe quel terminal et en créer (ce qui a pour effet de changer de session sans détacher la première). En revanche, on peut ajouter des terminaux virtuels (onglets) au sein d’une même session avec Ctrl+a c et les lister à leur tour avec Ctrl+a ".

Il existe de nombreux autres raccourcis clavier que l’on retrouve dans cette documentation permettant notamment de jouer avec le fenêtrage des terminaux (split vertical ou horizontal).

Les avantages de screen

  • S’utilise aussi bien en utilisant la session par défaut qu’avec de multiples sessions nommées.
  • Permet de lancer des opérations longues telles que du transcodage vidéo, des transferts de données ou des scripts interactifs sans se soucier d’attendre le retour ou de risquer un « Broken pipe »
  • Permet de partager un même terminal avec quelqu’un à distance
  • Permet se construire très rapidement des écrans de monitoring, en splittant le terminal en grille et en lançant des commandes telles que htop (uptime, load average, consommation en ram), watch -n1 df -h (calcul de l’espace disque en temps réel), iftop (trafic réseau), etc.

Les inconvénients

Peu user-friendly, de fonctionne que par raccourcis claviers à mémoriser. Le risque de mélanger les raccourcis et de faire ctrl+d par habitude est un problème.

tmux

« Tmux a pour but d’être une alternative stable et moderne à GNU Screen, il possède d’ailleurs la majorité des fonctions de GNU Screen, mais contrairement à celui-ci il est distribué sous licence BSD et fait partie de la base système d’OpenBSD » (Wikipedia). Il s’installe avec apt-get install tmux.

Créer une nouvelle session : tmux ou tmux new -s exemple. La session remplace le terminal courant par un terminal virtuel vivant dans un processus. Utiliser Ctrl+d tuera la session. La commande tmux detach ou Ctrl+b d détachera la session en cours et vous ramènera sur votre terminal initial, sans fermer la session. Le terminal virtuel continue sa vie dans un processus. Les sessions sont isolées par utilisateur système.
Lister les sessions : tmux ls.
Se connecter à une session : tmux a ou tmux a -t exemple. tmux permet de rejoindre les sessions via cette même commande, détachées ou non. C’est l’équivalent screen -r et screen -x.
Détacher une session de l’extérieur et s’y connecter : tmux a -d ou tmux a -d -t exemple.

Comme avec Screen, on peut ajouter des terminaux virtuels (onglets) au sein d’une même session avec Ctrl+b c et les lister à leur tour avec Ctrl+b w.

Il existe de nombreux autres raccourcis clavier que l’on retrouve dans cette documentation permettant notamment de jouer avec le fenêtrage des terminaux (split vertical ou horizontal), renommage des sessions ou onglets, défilement etc.

Les avantages de tmux sur Screen

À première vue, les deux outils se ressemblent énormément. Il existe quelques petites différences qui font pencher la balance en faveur de tmux :

  • la portabilité du code le rend présent sur plus de systèmes d’exploitation
  • meilleure gestion de l’entrelacement de sessions (avec des alertes, etc)
  • il affiche une barre de statut en bas du terminal avec quelques infos, ce qui permet aussi de savoir qu’on est en train d’utiliser tmux
  • il offre plus de possibilités pour être scripté, telles que le partage de sessions entre utilisateurs
  • globalement plus de petites options de configuration le jour où on souhaite personnaliser une session

Les inconvénients

Potentiellement toujours ce même risque d’utiliser ctrl+d par réflexe et toujours autant de commandes à retenir.

tmate

tmate est un fork de tmux. Il apporte la possibilité de partager un terminal en lecture seule, ainsi que la possibilité de partager à quelqu’un d’autre une commande SSH reconnectant directement dans une session.

Il n’est pas présent dans les dépôts de Debian et doit donc être installé via un dépôt externe. Le serveur utilise des fonctionnalités spécifiques du noyau Linux et n’est donc pas multiplateforme, alors que le client est disponible sous Mac et BSD.

Byobu

Byobu est initialement une couche d’amélioration à GNU Screen écrit pour Ubuntu. Aujourd’hui il utilise tmux par défaut pour proposer un ensemble de fonctionnalités user-friendly, ce qui signifie que tmux est installé comme dépendance. Le tout s’installe avec apt-get install byobu. Byobu est même préinstallé sur les instances Cloud d’Ubuntu par Canonical.

On lance le contexte Byobu via la commande byobu. La session remplace le terminal courant par un terminal virtuel vivant dans un processus. Une interface graphique en mode texte apparait dans le terminal, proposant comme tmux une barre listant les onglets mais en y ajoutant des indicateurs du système d’exploitation.
Byobu - écran d'accueil

Ces indicateurs sont configurables dans l’aide de Byobu, que l’on obtient en appuyant sur F1 ou F9. Byobu ne semble pas prévu pour lancer plusieurs sessions en parallèle, comme le permettent screen et tmux. À la place, Byobu permet d’être lancé au démarrage via sa fenêtre d’aide. Lorsque cette option est activée, byobu est exécuté à chaque connexion SSH. Mieux, Ctrl+d ou exit ne font plus sortir du contexte Byobu, ils ferment les onglets virtuels, ce qui est très pratique. Lorsqu’il ne reste qu’un onglet à fermer, la connexion SSH se referme automatiquement.
Byobu - Aide (F1 ou F9)

Les commandes basiques

Créer un nouvel onglet : F2.
Aller à l’onglet précédent : F3.
Aller à l’onglet suivant : F4.
Se détacher de la session : F6.
Rafraichir les indicateurs : F5 (automatique).
Renommer l’onglet : F8.
Entrer en mode historique : F7.

Il existe d’autres commandes, notamment pour diviser un onglet en plusieurs écrans, que je ne peux pas tester sous Mac OSX car ces raccourcis claviers sont déjà utilisés par le système.

Utilisation du mode historique

Le mode historique permet de naviguer dans les anciennes sorties en utilisant des commandes similaires à vi :

  • h ou flèche gauche – reculer le curseur d’un caractère
  • l ou flèche droite – avancer le curseur d’un caractère
  • j ou flèche bas – descendre le curseur d’un ligne
  • k ou flèche haut – monter le curseur d’une ligne
  • 0 – aller au début de la ligne
  • $ – aller à la fin de la ligne
  • G – aller à la ligne indiquée (par défaut va en fin de tampon)
  • / – recherche en avant
  • ? – recherche en arrière
  • n – Passe à la prochaine correspondance, en avant ou en arrière

Les avantages de Byobu sur tmux

Par où commencer ?! L’utilisation des touches Fonction est une réelle avancée, les actions sont simples à retenir, toutes au même endroit. En mode de démarrage automatique, plus de risque de détruire la session accidentellement. Les indicateurs de la santé du système restent toujours visibles, et le parcours de l’historique à la vi est un réel plus !

Les inconvénients

Il n’y a plus vraiment d’inconvénient avec Byobu, tout est à la fois simple, intuitif et puissant. Byobu ne semble pas pensé pour être scripté ni multi-utilisateurs mais bien pour être une surcouche graphique à un outil qui peut l’être. Byobu partage les sécurités anti-sessions-imbriquées de tmux : puisque l’unique session Byobu est une session tmux, il peut devenir délicat d’utiliser tmux.

Conclusion

Byobu est le grand vainqueur de ce match. Il existe de nombreux cas pratiques où ce logiciel vous sauvera la mise : lorsqu’il ne le fera pas, le confort d’utilisation qu’il procure reste une raison valable de l’installer sur tout serveur nécessitant un minimum de maintenance.