jeudi 14 novembre 2013

Yeoman, AngularJS and Bower, bower-install : gestion de dépendance

Dans le billet précédent, on a préparé l'environment de travail. Nous allons voir ici comment gérer les dépendances javascript.

Avant, il fallait

  • aller trouver sa librairie javascript et ses dépendances
  • les télécharger
  • les placer dans l'arborescence,
  • modifier son index.html pour référencer les fichiers
  • ...
Et si vous avez fait du Java avant l'existance de Maven, vous vous souvenez de l'enfer que pouvait être le conflis de version, la mise à jour d'une librairie ...

Bower va nous aider à resorber quelques uns de ces problèmes.


Pour se faire, il vous faut l'environment du billet précédent ainsi que grunt-bower-install

Step 1

npm install

Installer grunt-bower-install pour commencer. Ouvrir une console dans votre répertoire de travail et lancer la commande:

npm install grunt-bower install --save-dev


Gruntfile.js

Chargement de bower-install
Modifier le fichier Gruntfile.js de votre projet comme suit. Vous devriez avoir une fonction declarée :

module.export = function (grunt) {
...
}


Il faut charger grunt-bower-install dans ces environs. A la fin de la succession de 'require', ajouter la ligne magique pour avoir :

...
require('load-grunt-tasks')(grunt);
require('time-grunt')(grunt);
grunt.loadNpmTasks('grunt-bower-install');
...

Déclaration de bower-install
Si vous n'êtes pas perdu ici, il faudra ensuite declarer la tache bower-install dans le bloc grunt.initConfig.

Vous devrez passer de :


  grunt.initConfig({
    yeoman: {
      // configurable paths
      app: require('./bower.json').appPath || 'app',
      dist: 'dist'
    },
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },
...


A ce qui suit:
grunt.initConfig({
      'bower-install': {

        target: {

          // Point to the html file that should be updated
          // when you run `grunt bower-install`
          html: 'app/index.html',

          // Optional:

          // If your file paths shouldn't contain a certain
          // portion of a url, it can be excluded
          ignorePath: 'app/',

          // Customize how your stylesheets are included on
          // your page.
          //
          //   default: '<link rel="stylesheet" href="{{filePath}}" />'
          cssPattern: '<link href="{{filePath}}" rel="stylesheet">',

          // Customize how your <script>s are included into
          // your HTML file.
          //
          //   default: '<script src="{{filePath}}"></script>'
          jsPattern: '<script type="text/javascript" src="{{filePath}}"></script>'
        }
      },
    yeoman: {
      // configurable paths
      app: require('./bower.json').appPath || 'app',
      dist: 'dist'
    },
    watch: {
      coffee: {
        files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
        tasks: ['coffee:dist']
      },


index.html

Une dernière modification est à faire du coté de votre fichier index.html. Il faudra ajouter le tag suivant :

<!-- bower:js -->
<!-- endbower -->



Terminé!

Step 2

Ajoutons à présent une dépendance comme ngUpload

Dans la console :

bower install ngUpload --save

Cette commande installera le nécessaire pour vous mettre à dispo la librairie ngUpload et modifiera le fichier bower.json.

il faudra enfin lancer la commande:
grunt bower-install


Vous aurez à la fin la librairie ainsi que ses dépendances de telechargées. Elles seront aussi déclarées dans votre index.html.




PS : il est possible que vous tombiez sur un message "building is not supported on win32" sous Windows lors de l'utilisation de la commande npm install. Le bug est connu est une solution temporaire existe.



















dimanche 3 novembre 2013

Yeoman, AngularJS ....

Yeoman, grunt, angularJS ... ou l'industrialisation d'une application Web du coté client.

PS : tout ce qui suit a été fait sous Windows

Prérequis


Il faudra

Installer

  • Installer NodeJS en suivant les instructions, puis Ruby et pour finir Google Chrome
  • Ouvrir une console et taper 'gem install compass'. Cette commande installera Compass et sera utilisé pour la commande "grunt server" qui sera vue plus bas.


Configuration de variables d'environement

  • Ajouter NodeJS dans votre PATH afin d'invoquer npm plus facilement.
  • Créer une variable CHROME_BIN qui pointera vers l'executable de chrome (sera utilise pour la commande 'grunt test' qui sera abordé plus bas

Installer Yeoman 


Comme stipuler sur le site, en ligne de commande :
npm install -g yo
 
Maintenant installer le générateur associé à AngularJS:
npm install -g generator-angular


Préparer le projet

On va maintenant créer la structure de base du projet Web. En ligne de commande, ce mettre dans votre répertoire de travail puis taper:
yo angular

Et la c'est le drame. Vous tombez dans les abysse d'un Maven like qui tire semble tirez la terre entière .... mais en fait non.

Vous devez répondre à quelques questions telles que : "voulez vous bootstrap ?"

Une fois les questions répondu et que le programme vous a rendu l'otage qu'est votre console, vous aurez une arborescence proche de ce qui suit:


 


Grunt server

Pour avoir un premier retour de tout ce que nous venons de faire, aller dans le répertoire de votre projet avec la console  puis taper:
grunt server

Si votre navigateur se lance avec une page ayant pour contenu "Allo, Allo!", c'est que l'ensemble est plutôt bien configuré.
Cette commande vous sera très utile lors de l’édition de votre site. Elle permettra de voir le resultat du travail directement sans lancer de serveur tierce.

Grunt test

Si vous êtes développeur Backend, vous vous êtes toujours demandé comment tester ce code Javascript : grunt test

Cette commande permet de lancer des tests unitaires basés sur le framework Karma et va nous permettre ici d'une certaine façon de valider l'environement de travail.

Taper maintenant la commande:
grunt test

Si aucune erreur se produit, que votre navigateur se lance et la sortie console vous indique que l'ensemble des tests s'est effectué sans erreur, c'est que votre environnement de travail est prêt!

Petite touche finale de préparation : Font Awesome

Vous utilisez surement cette librairie dans vos projets. Pour l'utilisez dans le cadre de cette préparation : bower install --save font-awesome


... la suite dans un autre billet

vendredi 11 octobre 2013

Supprimer/remplacer l'entête de code source (java)

Problème : mes entêtes de code source java ne sont plus bons. Il faut les remplacer avec un nouveau header

Solution! Jedit et sa fonction 'Search in directory' en cochant 'seach subdirectories' et 'Regular expressions' pour trouver l'ensemble des fichiers. L'expression regulière utilisée est :  "/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/package"

Il suffit ensuite de valuer 'Remplace with' avec le nouvel entête sans oublier 'package' et cliquer sur 'Replace all' comme dans l'exemple qui suit:

Exemple d'utilisation Jedit

PS : j'ai testé par curiosité regexxer mais il ne semblait pas gérer les commentaires multi-lignes

vendredi 5 juillet 2013

HAProxy et les logs (Debian squeeze)

Pour faire suite au billet précedent, on peut avoir les log de l'ensemble des connexions transitant par HAProxy dans des fichiers distinct.


Step 1

mkdir /var/log/haproxy

Step 2

Créer le fichier  /etc/rsyslog.d/haproxy.conf et y placer le contenu suivant:

if ($programname == 'haproxy' and $syslogseverity-text == 'info') then -/var/log/haproxy/haproxy-info.log
& ~
if ($programname == 'haproxy' and $syslogseverity-text == 'notice') then -/var/log/haproxy/haproxy-notice.log
& ~

Step 3

Modifier la configuration HAProxy (haproxy.cfg) pour avoir dans la clause global :


global
    log /dev/log local0 info
    log /dev/log local0 notice

Penser à supprimer toute autre réference au log dans cette partie global.

Step 4


Relancer rsyslod
service rsyslog restart

Relancer haproxy
service haproxy restart

Dans le répertoire /var/log/haproxy, vous devriez avoir les fichiers suivant:

total 32
-rw-r----- 1 root adm 24948  5 juil. 18:28 haproxy-info.log
-rw-r----- 1 root adm   378  5 juil. 18:33 haproxy-notice.log


Step 5

logrotate! Pour ne pas avoir des fichiers de log monstueux il faut utiliser logrotate. Créer le fichier /etc/logrotate.d/haproxy et y placer:

/var/log/haproxy/*.log {
        weekly
        missingok
        rotate 7
        compress
        delaycompress
        notifempty
        create 640 haproxy haproxy
        sharedscripts
        postrotate
        /etc/init.d/haproxy reload > /dev/null
        endscript
}

jeudi 4 juillet 2013

Gnome Shell - Avoir le dock affiché en permance

Il est possible d'avoir le dock Gnome-Shell affiché en permanence afin d'avoir un apérçu des fenêtres ouvertes.

Il faut dans un premier temps installer l'extension Dock.

Par défaut il sera à droite et s'affichera lorsque vous le survolerez. Si vous voulez l'afficher en permanance, utilisez la commande:
dconf write "/org/gnome/shell/extensions/dock/autohide" false

Si vous voulez placer le dock à gauche:
dconf write "/org/gnome/shell/extensions/dock/position" "'left'"


mardi 2 juillet 2013

STunnel (SSL) + HAProxy + Debian Squeeze

Il est possible d'ajouter un pont SSL à la configuration HAProxy du billet précédent

Step 1 : installer stunnel

apt-get install stunnel

Step 2 : générer le certificat


 openssl req -new -nodes -x509 -out /etc/stunnel/stunnel.pem -keyout /etc/stunnel/stunnel.pem

 Aller dans le répertoire /etc/stunnel et corriger les droits du certificat:

 chown stunnel4:stunnel4 stunnel.pem

 Step 3 : Configurer


Sauvegarder la configuration par defaut:
mv /etc/stunnel/stunnel.conf /etc/stunnel/stunnel.conf.bck


Puis éditer le fichier le fichier de configuration pour avoir:
 

sslVersion = all
options = NO_SSLv2


chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
; PID is created inside the chroot jail
pid = /stunnel.pid
socket = l:TCP_NODELAY=0
socket = r:TCP_NODELAY=1
output = /var/log/stunnel.log

[mon.domain.com]
cert = /etc/stunnel/stunnel.pem
accept  = 192.168.0.20:443
connect = 192.168.0.20:80
TIMEOUTclose = 0



Il faut modifier les IP mentionnées dans 'accept' et 'connect' avec votre adresse IP publique pour le 'accept' et l'adresse où se trouve HAProxy pour le 'connect'

Enfin, il faut modifier le fichier /etc/default/stunnel4 pour permettre à stunnel de se lancer en modifiant la ligne
  • ENABLED=0
pour
  •  ENABLED=1

Step 4 : relancer stunnel

Vous pouvez maintenant relancer stunnel:
service stunnel restart


Vous avez maintenant un Load balancer (HAProxy) avec une connectivité chiffré grâce à stunnel

lundi 1 juillet 2013

HAProxy et Debian Squeeze

HAProxy permet de faire du load balancing entre plusieurs serveurs. Il peut faire de l'équilibrage de charge entre plusieurs Tomcat ou encore entre plusieurs serveurs de streaming. La configuration qui va suivre va le faire pour 2 Tomcat et 2 serveurs qui peuvent accepter un flux TCP.

Ce qui est suit fonctionne sur une Debian Squeeze.

Step 1 : installer


apt-get install haproxy

Step 2 : configurer

Editer le fichier /etc/default/haproxy pour remplacer
  • ENABLED=0
par
  • ENABLED=1

 Sauvegarder le fichier par defaut :
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bck

puis éditons ce fichier : vi /etc/haproxy/haproxy.cfg

Comme dit plus haut, nous allons rediriger le traffic HTTP vers 2 Tomcat en prenant soin de prendre l'éventuelle session Tomcat ouverte sur les serveur.

Nous allons rediriger aussi 1 flux TCP venant sur le port 3637 vers un des serveurs prenant en charge ces flots.

global
    daemon
    maxconn 256
    log 127.0.0.1 local0

defaults
    retries 3
    option logasap
    log global

    timeout connect 5000ms
    timeout client 600000ms
    timeout server 600000ms



listen TOMCAT :80
        mode http
        option httplog
        balance roundrobin
        option redispatch
        option httpclose
        option forwardfor
        cookie JSESSIONID prefix
        server liferay_server1 192.168.0.26:8080 cookie tomcat1 check
        server liferay_server2
192.168.0.27:8080 cookie tomcat2 check
        stats uri /admin?stats
        stats realm haproxy
        stats scope .

listen VOTRE_PROTOCOLE :3637
        mode tcp
        option tcplog
        balance leastconn
        server mscodec_1
192.168.0.31:3637
        server mscodec_2
192.168.0.32:3637


Pour le protocole sur le port 3637, il est possible d'utiliser la configuration:

listen VOTRE_PROTOCOLE :3637
        mode tcp
        option tcplog
        balance leastconn
        server mscodec_1
192.168.0.31:3637 check
        server mscodec_2
192.168.0.32:3637 check

Le mot clé 'check' va indiquer à HAproxy de vérifier régulièrement si le service est disponible sur le serveur indiqué

Step 3 : relancer HAProxy

service haproxy restart

mercredi 29 mai 2013

SVN, supprimer les fichiers non 'versionnés'

svn -R revert . ne suffit pas pour revenir à un état des répertoires similaires à celui du dépôt. La commande suivante devrait arriver à bout du problème :

svn status | grep ^\? | cut -c9- | xargs -d \\n rm -r 



Source

mardi 7 mai 2013

Maven et paquet Debian

Il est possible de réaliser un paquet Debian avec Maven en s'aidant du plugin JDeb

Dans l'exemple qui suit, j'ai fait un programme Java qui va logguer un message toute les 5 secondes. J'utilise dans cette exemple Lombok SLF4 et le @Scheduled de Spring . Il sera lancer comme service au lancement de l'OS.

Les sources de l'exemple sont sur github.


Fichier control

Pour la réalisation du paquet, il est nécessaire d'avoir un fichier control contenant les informations de votre paquet tel que son nom, sa version, ses dépendances...
Dans l'exemple, j'ai mis 2 dépendances pour illustrer cette utilisation : 
  • dos2unix interviendra dans le script de post-installation (postinst) pour s'assurer que le script de lancement est bien au format unix. 
  • sudo sera utilisé pour lancer le service avec l'utilisateur approprié

Scripts de pre et post-installation

L'installation d'un paquet peut aussi faire intervenir des scripts avant la phase d'installation de votre application et après installation de votre application. Vous pouvez faire intervenir les scripts :
  • preinst : avant installation
  • postinst : après installation
  • prerm : avant désinstallation
  • postrm : après désinstallation
Je met l'ensemble de ces fichiers dans le répertoire src/main/deb/control de mon projet :


Dans cet exemple, le script de pre-installation vérifie par exemple l'existence d'un utilisateur dédié au lancement du service. Il va aussi préparer l'arborescence pour le bon fonctionnement du service.

Le script de post-installation utilisera la commande update-rc.d pour inscrire le service et le démarrera.


Fichier init.d

Pour lancer et arrêter le service, j'utilise le fichier jdeb-tips.sh que j'ai mis dans le répertoire src/main/deb/init.d
J'ai utilisé et modifié un template provenant d'ici.


pom.xml


Step 1

Ayant utilisé des propriétés Maven dans les fichiers du répertoire src/main/deb, je les copies dans le répertoire 'target' en utilisant le filtragre :

            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.4.3</version>
                <executions>
                    <execution>
                        <id>copy-deb-package-resources</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/deb</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/deb</directory>
                                    <filtering>true</filtering>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>



Step 2

Je récupère les dépendances pour permettre une exécution autonome du programme :

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${project.build.directory}/libs</outputDirectory>
                            <overWriteReleases>false</overWriteReleases>
                            <overWriteSnapshots>false</overWriteSnapshots>
                            <overWriteIfNewer>true</overWriteIfNewer>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Step 3


J'utilise ensuite maven-jar-plugin pour réaliser mon Jar exécutable :

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>libs/</classpathPrefix>
                            <mainClass>fr.gunduz.tips.jdeb.Main</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

Step 4


Enfin, l'utilisation du plugin JDeb. Ce qui est important de noter dans ce qui suit est comment indiquer au plugin où ce trouve les fichiers control grâce à la balise  <controlDir>. Etant donnée que j'ai copié les fichiers -afin qu'ils soient valués- dans le répertoire target, il faut absolument utiliser cette balise.
Le reste de la configuration indique uniquement les fichiers à inclure dans le paquet deb ainsi que les répertoires de destination et leurs propriétés.

            <plugin>
                    <artifactId>jdeb</artifactId>
                    <groupId>org.vafer</groupId>
                    <version>1.0</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>jdeb</goal>
                            </goals>
                            <configuration>

                                <verbose>true</verbose>
                                <controlDir>${basedir}/target/deb/control</controlDir>

                                <dataSet>
                                    
                                     <data>
                                        <src>${project.basedir}/target/libs</src>
                                        <type>directory</type>
                                        <mapper>
                                            <type>perm</type>
                                            <prefix>${debian.target.dir}/jdeb-tips/libs/</prefix>
                                            <user>jdeb-tips</user>
                                            <group>jdeb-tips</group>
                                            <filemode>644</filemode>
                                        </mapper>
                                    </data>
                                    
                                    <data>
                                        <src>${basedir}/target/${project.build.finalName}.jar</src>
                                        <dst>${debian.target.dir}/jdeb-tips/${project.build.finalName}.jar</dst>
                                        <type>file</type>
                                        <mapper>
                                            <type>perm</type>
                                            <user>jdeb-tips</user>
                                            <group>jdeb-tips</group>
                                            <filemode>644</filemode>
                                        </mapper>
                                    </data>
                                    <data>
                                        <src>${basedir}/target/deb/init.d/jdeb-tips.sh</src>
                                        <dst>/etc/init.d/jdeb-tips</dst>
                                        <type>file</type>
                                        <mapper>
                                            <type>perm</type>
                                            <user>root</user>
                                            <group>root</group>
                                            <filemode>755</filemode>
                                        </mapper>
                                    </data>
                                </dataSet>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>


Construction et installation

Il vous suffit de lancer la commande mvn clean install pour avoir votre paquet Debian. Pour l'installer sur le système hôte, il faudra utiliser la commande dpkg -i <votre paquet>

Attention, si vos dépendances ne sont pas installées au préalable à l'aide d'apt, la commande dpkg retournera une erreur.