Je donne ici quelques raccourcis et petites mises à jour par rapport à cette doc, pour installer notamment l'imprimante improche3 :
a) Installation sur Mac OS
Mon expérience sur OS 10.10 (Yosemite) :
Préférences Système / Imprimantes
Cliquer sur bouton "+"
Adresse : impression.irap.omp.eu
Protocole : IPP
File d'attente : /printers/improche3
Cliquer sur "Ajouter"
Cocher "unité d'impression duplex" pour le recto-verso
b) Installation sur Linux
Mon expérience sur Fedora 20 :
Par défaut, ça ne marche pas car le protocole IPP n'est pas autorisé par le firewall.
Donc, à moins de l'autoriser dans la config du firewall, ne pas passer par Preferences / Imprimantes, mais plutôt par le script d'installation :
sudo system-config-printer
Ajouter une imprimante
Cliquer sur "Imprimante Réseau", puis "IPP"
Là, on nous propose d'activer IPP qui n'est pas forcément activé par défaut
OK
Entrer directement l'URI complète de l'imprimante : ipp://impression.irap.omp.eu/printers/improche3
Le bon pilote devrait être automatiquement sélectionné
Si vous voulez exécutez idl SUR HYPERION, alors c'est différent, il s'agit seulement de se connecter à hyperion via la passerelle
(voir à ce sujet la section "Accès à hyperion avec Putty")
Changed:
< <
Si vous êtes toujours partants, allez directement au point 2)
> >
Si vous êtes toujours partants, allez directement au point (2) (car le point (1) ne concerne que l'administrateur du serveur)
1) Travail à faire pour l'administrateur système sur hyperion (vous pouvez sauter cette section)
Line: 1175 to 1175
Pour les utilisateurs MacOS ou Linux:
Changed:
< <
Placer les 2 lignes suivantes (une fois pour toutes) dans votre fichier de démarrage .bash_login (depuis votre répertoire home, ou bien ~/.bash_login directement depuis n'importe où), pour ne plus avoir à les taper :
> >
Placer les 2 lignes suivantes (une fois pour toutes) dans votre fichier de démarrage .bash_profile (depuis votre répertoire home, ou bien ~/.bash_profile directement depuis n'importe où), pour ne plus avoir à les taper :
Il vous faudra remplacer PATH_TO_IDL_BIN par le chemin vers VOTRE installation d'idl (par exemple pour idl 8.3 sur Mac : /Applications/exelis/idl83/bin ou bien /Users/monlogin/Applications/exelis/idl83/bin si c'est une installation seulement sur votre compte)
Added:
> >
(
ATTENTION, il est preferable d'utiliser vi, emacs, ou gedit pour faire ce fichier ;
si vous voulez vraiment utiliser TextEdit, voici la démarche à suivre :
1) Ouvrir un terminal
2) cd
3) touch .bash_profile
4) open .bash_profile
5) Verifier que dans le menu Format, il soit bien écrit : "Convertir au format RTF" (ce qui veut dire que le format actuel est bien un format TEXTE)
)
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac).
Line: 1200 to 1211
##################### end of license file #######################
Added:
> >
(
ATTENTION :
Pour faire cela avec TextEdit, suivre la même procédure que pour .bash_profile décrite ci-dessus,
sauf qu'il faut remplacer le "cd" de la 2ème étape par un "cd /Applications/exelis/license" (ou quelque chose du genre)
)
c) "Creuser" un tunnel
Line: 1209 to 1225
Ouvrir un tunnel avec mise en correspondance de 2 ports :
Added:
> >
Depuis le Terminal (console), Aller dans votre home : cd
Avec un éditeur de texte (style "vi" ou "emacs" ou "gedit"...), créer un fichier "A_EXECUTER_DEPUIS_CHEZ_MOI_AVANT_IDL.sh"
Added:
> >
(Si vous voulez utiliser TextEdit, suivre la même procédure que pour .bash_profile décrite ci-dessus)
(remplacer MON_LOGIN_EMAIL par votre login utilisé pour le mail ou pour vous connecter à la passerelle du labo, et GATEWAY par le serveur passerelle du labo)
Ne pas oublier de noter tout ce que tu fais. Rédige au fur et à mesure (avec OpenOffice).
NOUVELLES MODIFS FAITES :
4 juin :
VII-3 c) relation 1-1
16 mai :
IX-5
X - Documentation
15 mai :
IX-2 et 3
14 mai :
IX-1
VI-4
3 mai :
section VI-3 (lost password)
section IX-1 (logout)
5 Avril :
section VII-3 (crud)
Plus tard :
(pas encore sûr, à réfléchir) ajouter un script qui permet de définir un tableau de champs obligatoires pour un Modèle donné ==> Ces champs devront obligatoirement être saisis dans les vues associées au Modèle (voir http://book.cakephp.org/1.3/view/1147/required)
III - En s'inspirant du tutoriel "blog", commmencer à construire une architecture à partir d'un sous-ensemble de la BDD Europlanet
1) Ce projet est géré en versions avec subversion (plugin Eclipse subclipse)
2) Construire un schéma d'une petite BDD avec MysqlWorkbench
Ce schéma contient 7 tables principales :
- people (lien N-1 avec institutes, status, et profiles, et 1-N avec resources) : id, name, firstname, email, password, status, active, job, created, updated (le champ "active" est un booléen VRAI par défaut)
- status : id, name (avec les valeurs suivantes pour name : NULL, 'registered', 'invalidated', 'validated')
- profiles : id, name, level (level indique la hiérarchie ; name et level ont les valeurs suivantes : {'admin',10}, {'priv',5}, {'validator',3}, {'normal',0} ; donc on a la hiérarchie admin > priv > validator > normal)
- institutes : id, name, created, updated
- expertises : id, name (lien M-N avec people)
- resources (lien M-N avec sciencases) : id, name, created, updated
- sciencecases : id, name, created, updated
Par défaut, l'action "people/index" ne doit afficher que les personnes dont le champ "active" est à TRUE et le champ "status" vaut "validated"
5) Lancer les tests générés par "bake" (avec phpUnit, inclus dans Xampp ?) pour tester les modèles et les contrôleurs
http://book.cakephp.org/2.0/en/development/testing.html
cake bake fixture all ?
cake bake test all ?
Depuis cakephp 2.1 :
Console/cake test app/Model/Post.php
Console/cake test app/Controller/PostsController.php
6) Ajouter la validation des champs de tous les formulaires
http://book.cakephp.org/2.0/en/models/data-validation.html
"bake" ajoute des validations par défaut. Les étendre si nécessaire pour que toutes les validations soient générées automatiquement, en fonction du type des champs.
Vérifier que les champs obligatoires sont bien obligatoires en saisie.
Ajouter un test pour s'assurer qu'une personne est obligée de remplir tous les champs (sauf people.job) quand elle s'enregistre.
1) Ajouter l'authentification (AUTH)
Login = email
Auth (et Acl) doivent avoir pour support la table "people" (et status et profiles).
Auth (et Acl) impliquent aussi l'usage des Sessions (http://book.cakephp.org/2.0/en/development/sessions.html)
Astuce : dans la session, stocker l'id de la personne, et non pas son email (car l'email peut changer, mais pas l'id)
Toute personne non authentifiée (accès anonyme) peut :
- lire (R ) toutes les tables, sauf la table "resources"
- s'enregistrer (droit C sur la table people)
Toute personne authentifiée peut :
- lire (R ) toutes les tables (y-compris "resources")
- modifier (U) sa fiche (sauf son profil), mais pas celle des autres
- créer (C ) une ressource
- modifier/supprimer (UD) une ressource qu'elle a créée, mais pas celles des autres
- modifier (U) un institut auquel elle appartient
Gérer le login et le logout
Ajouter les tests nécessaires :
(Utiliser des "fixtures", cf section "Fixtures" dans http://book.cakephp.org/2.0/en/development/testing.html)
(cake bake fixture all ?)
Tester qu'une personne non authentifiée :
- peut lire la table 'resource'
- peut s'enregistrer
- ne peut pas modifier une table
Tester qu'une personne authentifiée peut :
…
Faire un test login/logout complet selon le scénario suivant :
- une personne se logue
- vérifier qu'elle peut créer une ressource
- elle se délogue
- vérifier qu'elle ne peut plus créer une ressource
2) Ajouter le contrôle d'accès (ACL)
Créer quelques personnes avec des rôles (profils) différents :
'user1', profil 'admin' (tous les droits)
'user2' et 'user3', profil 'normal', utilisateur normal
'user4', profil 'priv', utilisateur privilégié
'user5', profil 'validator', utilisateur pouvant valider d'autres utilisateurs
Une personne de profil 'admin' a un droit CRUD (créer/lire/modifier/supprimer) sur toutes les tables.
Une personne de profil 'priv' :
a un droit CRUD seulement sur la table 'institutes'
peut modifier le profil de toutes les personnes (sauf le sien)
Ajouter les tests nécessaires :
tester que 'user1' peut tout faire (faire juste quelques tests, pas tout)
tester que 'user4' : * peut ajouter un nouvel institut * peut modifier le profil d'une personne (mais pas le sien)
tester que 'user2' : * ne peut pas modifier une ressource qui ne lui appartient pas * peut ajouter une nouvelle ressource, et la modifier ensuite * peut modifier son email (login) et/ou son mot de passe
...
VI - ENREGISTREMENT DES UTILISATEURS (registration)
1) Réalisation de la procédure d'enregistrement (inscription) d'une personne :
(voir s'il n'existe pas déjà un plugin cakephp pour gérer ça, car c'est assez classique au début)
a) une personne remplit sa fiche d'enregistrement et la soumet (SUBMIT) ==> elle est enregistrée dans la table people avec "status" à NULL
b) elle reçoit un 1er mail de confirmation avec un lien de validation
c) elle clique sur le lien de validation, ce qui valide son inscription ==> son champ "status" passe à "registered" ; les validateurs reçoivent un mail pour les avertir de cette inscription, avec un lien vers la page du site permettant de valider ou invalider la personne
d) elle reçoit un 2e mail de confirmation lui disant qu'elle est inscrite, MAIS qu'elle doit attendre que son inscription soit validée par un 'validateur', et qu'elle recevra un mail pour le lui confirmer
e) si un validateur valide l'inscription, la personne reçoit un mail pour l'en informer (à partir de là, elle peut se connecter au site) ==> son "status" passe à "validated"
f) si un validateur invalide l'inscription, la personne reçoit un mail pour l'en informer ==> son "status" passe à "invalidated"
Ajouter les actions suivantes au Contrôleur "person" :
validate (profil 'validator') : pour valider une personne (champ "status")
invalidate (profil 'validator') : pour invalider une personne
deleteInvalidated (profil 'priv') : pour supprimer les personnes ayant un statut "invalidated"
activate (profil 'priv') : pour activer une personne (champ "active")
deactivate (profil 'priv') : pour désactiver une personne
Ajouter/modifier les tests nécessaires
2) Ajouter un captcha sur la fiche d'inscription
Ajouter/modifier les tests nécessaires :
tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
3) Récupération du mot de passe (lost password)
Sur le formulaire de login, ajouter (à droite du bouton LOGIN) un lien "register" (pour s'enregistrer) et un lien "forgot password" (mot de passe oublié)
Le lien "forgot password" pointe vers un formulaire de modification du mot de passe (Person/PasswordUpdate) contenant juste 1 champ "email" et un bouton "SUBMIT"
L'utilisateur saisit son email et clique sur "submit" pour qu'on lui envoie un nouveau mot de passe par mail (le mot de passe est aussi mis à jour dans la database)
Test
4) Procédure de désinscription (ACTION unregister)
a) une personne clique sur un lien "unregister"
b) une confirmation est demandée via une fenêtre javascript : "Are you sure that you want to unregister ?" OK/CANCEL
c) l'action "unregister" est exécutée, la personne n'est pas supprimée de la base, mais juste marquée "inactive"
d) la personne est automatiquement déconnectée
e) Test
VII - Améliorer le CRUD
1) Bien gérer complètement les relations 1-N
Actions sur Person (relation N-1 avec Institute) :
create : doit permettre d'associer la personne à un institut (via liste de noms)
update : doit permettre de modifier l'institut associé (via liste de noms)
index : doit permettre de voir toutes les personnes avec le nom (name) de l'institut associé ; un clic sur un institut doit amener à sa vue détaillée
view : doit afficher le nom (name) de l'institut associé
Action sur Institute (relation 1-N avec Person) :
view : doit afficher toutes les personnes associées
2) Bien gérer complètement les relations M-N
Actions sur Person (relation M-N avec Expertise) :
create : doit permettre d'ajouter des expertises (ET une date "since")
update : doit permettre de modifier les expertises associées
view : doit permettre de voir toutes les expertises associées
Idem pour Expertise (lien vers Person)
Même chose pour Resource (relation M-N avec Sciencecase)
Gestion des champs supplémentaires d'une table associative : exemple de la relation entre Person et Expertise :
expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table) et le champ supplémentaire "since" (date à laquelle l'expertise a été acquise)
3) Gérer d'autres types de relations
a) Ajout de plusieurs rôles différents entre 2 mêmes tables
Une personne peut avoir plusieurs liens avec une ressource (plusieurs liens entre les tables "people" et "resources"), ce qui veut dire qu'elle peut jouer plusieurs rôles par rapport à une ressource.
Ainsi, au lieu d'avoir seulement une clé étrangère "resources_id" dans la table "people", nous en aurons plusieurs avec des noms différents :
resource_provider_id : la personne qui a donné l'information sur la ressource (et qui l'a saisit)
resource_owner_id : le propriétaire de la ressource
resource_contact_id : le contact pour la ressource
Ces 3 clés pointent toutes vers la même clé primaire resource.id, et sont donc des "alias".
Améliorer les actions CRUD en conséquence
b) Relation réflexive (d'une table sur elle-même)
Ajout d'une relation réflexive sur "institutes" (dans ce cas particulier, il s'agit d'une relation hiérarchique) :
un institut peut appartenir à un autre institut (de niveau hiérarchique supérieur ; par exemple, le "CNRS" regroupe plusieurs instituts, "l'OMP" regroupe plusieurs laboratoires dont l'IRAP…)
cela revient seulement à ajouter un champ "institute_id" dans la table institutes (qui pointe sur la table institute, lien réflexif)
améliorer les actions CRUD en conséquence
c) Relation d'héritage ou spécialisation (1:1)
Une ressource peut être de différents types (ajouter la table "resourcetype") :
data
info (information, document...)
website
datacenter
chaque type de ressource est une spécialisation du type général "resource".
On aura donc 4 nouvelles tables filles "resourcedata", "resourceinfo", "resourcewebsite", "resourcedatacenter" qui "hériteront" de la table mère (générique) "resource" pour l'étendre chacune avec sa spécificité.
On peut représenter ce lien d'héritage par une relation 1-1 entre chacune de ces 4 tables filles et la table mère "resource".
Aucune des tables filles n'a d'existence propre, chacune dépend de la table mère "resource".
Ainsi, les tables filles n'ont pas de clé primaire, mais juste une clé étrangère (resource_id) qui pointe vers la clé primaire de la table mère (cette clé étrangère peut aussi leur servir de clé primaire).
Cette relation d'héritage a un impact sur toutes les VUES de la table "resource", car à chaque fois qu'on veut accéder à une ressource,
il faut récupérer aussi les informations spécifiques à son type dans la table fille associée (via la clé étrangère resource_id).
Plus particulièrement, la vue "Create" (et "Update") devra contenir un sélecteur de type ("Type de ressource"),
et n'afficher que les champs spécifiques au type sélectionné (en plus des champs généraux de la table mère).
Ajouter dans la table resource un champ "URL" (général à tous les types)
Voici les informations spécifiques à chaque type, et donc présent dans les tables filles respectives :
table data :
volume (en MB) :
restricted (oui/non)
table info (information, document...) :
langage (champ texte liste : English, French, Spanish...)
table website :
restricted (oui/non)
nom du webmaster (champ texte libre)
table datacenter :
nom du responsable (champ texte libre)
4) Ajouter les nouveaux tests nécessaires
VIII - Ajout d'une nouvelle action dans TOUS les Contrôleurs : search
ex : Person/search
Cela amène à une nouvelle vue PersonSearch qui est équivalente au formulaire de Person/create,
sauf qu'au lieu de servir à créer une nouvelle personne, il sert à en CHERCHER.
L'ensemble des personnes trouvées sont affichées dans une vue "FOUND" semblable à Person/index (sauf que c'est une vue PARTIELLE et non pas COMPLETE).
Les recherches se font sans tenir compte des majuscules ou minuscules.
En bas du formulaire, 2 boutons :
SEARCH
EXACT SEARCH
Exemples de requêtes possibles :
j'entre "Pallier" dans le champ "name" :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier", par exemple "Apallieri"...
j'entre "Pallier" dans le champ "name", "Etienne" dans le champ "firstname", et "informaticien" dans le champ "job" :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier" ET le prénom EST EGAL à "Etienne" ET le job EST EGAL à "informaticien"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier" ET le prénom CONTIENT "Etienne" et le job CONTIENT "informaticien"
Cette VUE "search" doit être accessible par un lien qui se trouve au début de la vue "index", sous la forme d'une icône en forme de LOUPE suivie de la mention "Search"
Faire les tests d'acceptation (ACCEPTANCE TESTS)
IX - Améliorer les vues
1) ajouter les liens généraux suivants :
"login" (qui n'apparaît que si l'utilisateur n'est pas logué)
et les liens "logout", "update my registration" et "unregister" (qui n'apparaissent que si l'utilisateur est logué)
2) Vue "view" : vue détaillée d'une ligne de table
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
Ajouter les boutons "Edit", "Delete" et "Create a copy" (visibles uniquement avec le profil "admin")
Pour le formulaire Person, le bouton "Edit" est aussi visible si la personne connectée correspond à la fiche visualisée.
3) Action "index" : vue globale d'une table
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
Masquer la clé primaire (id)
La colonne du champ "name" est triable : en cliquant sur la colonne "name", on trie en ordre croissant, puis décroissant
Le champ "name" est cliquable : en cliquant sur un nom, on va à la vue détaillée correspondante
Afficher le champ "name" des clés étrangères ; en cliquant dessus on va sur la vue détaillée
Les colonnes des clés étrangères sont filtrables : dans la vue people/index, en cliquant sur la colonne "institutes_id" on doit pouvoir sélectionner un nom d'institut (name) et filtrer la vue en conséquence
Au-dessus de la liste d'une table, ajouter un "filtre externe" pour chaque table M-N associée :
par exemple, pour la vue people/index, ajouter au-dessus de la liste des personnes une liste d'expertises : en sélectionnant une expertise, on ne voit plus que les personnes associées à cette expertise
En début de page, ajouter un bouton "Add a new one"
4) Ajouter les nouveaux tests nécessaires
5) Ajouter une page contenant tous les tests, avec un bouton permettant de lancer tous les tests à la suite "LAUNCH ALL TESTS"
Est-ce que samba est à l'écoute ? : service smb status
Redémarrer samba : service smb restart
Deleted:
< <
Depuis le poste client windows :
clic droit sur Poste de Travail / Créer un lecteur réseau / "\\nom_du_serveur\mon_nom"
Corriger un bug sur Mac Leopard (pas sur Tiger) : samba ne suit pas les liens qui vont vers un disque différent
Pour corriger ce bug, il suffit d'ajouter cette ligne dans la partie "[global]" du smb.conf :
Line: 4664 to 4662
unix extensions = no
Added:
> >
Gestion des utilisateurs :
Les utilisateurs enregistrés sont dans /etc/samba/smbpasswd
Créer un new user "toto" : sbmpasswd -a toto
Pour modifier le mot de passe de "toto" : smbpasswd toto
Connexion depuis un poste client Windows :
clic droit sur Poste de Travail / Créer un lecteur réseau / "\\nom_du_serveur\mon_nom"
Cas particulier des clients Windows 8 :
Try making the following adjustments on the Windows 8 machine that needs to connect to the Samba share.
This type of problem usually requires that you change the lanman server parameters in order to get Windows 8 working with older servers.
Control Panel - Administrative Tools - Local Security Policy
Local Policies - Security Options
Network security: LAN Manager authentication level
Set to Send LM & NTLM responses only
Set the Minimum session security for NTLM SSP
Disable Require 128-bit encryption
Reboot
Connexion depuis un poste client Mac :
CMD-K sur une fenetre (finder), puis saisir "smb://hyperion" (ou encore "smb://pallier@hyperion")
To force your connection to be SMB1, simply type cifs://servername instead of smb://servername when connecting to a Windows or NAS share.
This is by far easier and requires no real configuration changes.
Workaround Option 2:
To force all connections to be SMB1:
Open A terminal window
paste in the following line followed by the return key(should be all on one line):
Il vous faudra remplacer PATH_TO_IDL_BIN par le chemin vers VOTRE installation d'idl (par exemple pour idl 8.3 sur MacOS : /Applications/exelis/idl83/bin ou bien /Users/monlogin/Applications/exelis/idl83/bin si c'est une installation seulement sur votre compte)
> >
Il vous faudra remplacer PATH_TO_IDL_BIN par le chemin vers VOTRE installation d'idl (par exemple pour idl 8.3 sur Mac : /Applications/exelis/idl83/bin ou bien /Users/monlogin/Applications/exelis/idl83/bin si c'est une installation seulement sur votre compte)
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac).
Line: 1181 to 1181
Si vous êtes à l'extérieur du labo, continuez la lecture...
Changed:
< <
b) "Creuser" un tunnel
> >
b) Fichier de licence idl minimum
Added:
> >
Créer un fichier de licence nommé "license.dat" dans le repertoire "license" de votre installation d'idl (quelquechose comme C:\Programmes\exelis\license sur Windows et /Applications/exelis/license sur Mac), contenant les 6 lignes suivantes :
############ license file comments, do not delete ###############
# License Number(s):35689, 500181, 500448, 501255, 502304
SERVER localhost 0021856ceeec 9700
USE_SERVER
DAEMON idl_lmgrd
##################### end of license file #######################
c) "Creuser" un tunnel
Utilisateurs Mac et Linux :
Line: 1201 to 1213
(Remarque pour l'admin système : attention, sur le localhost on a le choix de la correspondance du port 1700 d'hyperion (port 9700 local) mais pas pour le 1701)
Changed:
< <
Allez maintenant à la section "c) Lancer idl"
> >
Allez maintenant à la section "d) Lancer idl"
Utilisateurs Windows (avec Putty) :
Changed:
< <
Deux choses à faire encore :
(1) Créer un fichier de licence nommé "license.dat" dans le repertoire "License" de votre installation d'idl (quelquechose comme C:\Programmes\exelis\License), contenant les 6 lignes suivantes :
############ license file comments, do not delete ###############
# License Number(s):35689, 500181, 500448, 501255, 502304
SERVER localhost 0021856ceeec 9700
USE_SERVER
DAEMON idl_lmgrd
##################### end of license file #######################
Voilà, vous avez créé un tunnel entre votre pc/mac et hyperion, passant par GATEWAY (vous êtes d'ailleurs connecté à la passerelle).
Line: 1268 to 1268
Attention, une fois la session idl terminée, ne pas oublier de détruire le tunnel en vous déconnectant d'hyperion !!! (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
Changed:
< <
d) ON RECAPITULE ?
> >
e) ON RECAPITULE ?
Une fois les étapes ci-dessus réalisées, voici ce que vous avez à faire pour exécuter idl :
(1) Créer un fichier de licence nommé "license.dat" dans le repertoire "License" de votre installation d'idl (quelquechose comme C:\Programmes\exelis\License), contenant les 6 lignes suivantes :
############ license file comments, do not delete ###############
# License Number(s):35689, 500181, 500448, 501255, 502304
SERVER localhost 0021856ceeec 9700
USE_SERVER
DAEMON idl_lmgrd
##################### end of license file #######################
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
Changed:
< <
(Pour les utilisateurs de Windows, faire un clic droit sur Poste de Travail, puis onglet "Variables d'environnement", puis entrer la variable nommée LM_LICENSE_FILE avec la valeur "1700@hyperion.cesr.fr:9700@localhost")
> >
Pour les utilisateurs de Windows:
Changed:
< <
Sur MacOS ou Linux (après avoir installé IDL), placer les 2 lignes suivantes (une fois pour toutes) dans votre fichier de démarrage .bash_login (depuis votre répertoire home, ou bien ~/.bash_login directement depuis n'importe où), pour ne plus avoir à les taper :
> >
Faire un clic droit sur Poste de Travail, puis onglet "Variables d'environnement", puis entrer la variable nommée LM_LICENSE_FILE avec la valeur "1700@hyperion.cesr.fr:9700@localhost")
Added:
> >
Pour les utilisateurs MacOS ou Linux:
Placer les 2 lignes suivantes (une fois pour toutes) dans votre fichier de démarrage .bash_login (depuis votre répertoire home, ou bien ~/.bash_login directement depuis n'importe où), pour ne plus avoir à les taper :
2) Pour vous (côté client), Il suffit de faire 2 choses sur votre pc/mac
> >
2) Pour vous (côté client), voici ce qui est à faire sur votre pc/mac
NB: For English readers, go to section 3) below
Changed:
< <
PREREQUIS : idl doit être installé localement sur votre pc
> >
PREREQUIS : idl doit être installé localement sur votre pc
a) Positionner une variable d'environnement
Line: 1164 to 1164
(Pour les utilisateurs de Windows, faire un clic droit sur Poste de Travail, puis onglet "Variables d'environnement", puis entrer la variable nommée LM_LICENSE_FILE avec la valeur "1700@hyperion.cesr.fr:9700@localhost")
(Le mieux est de placer cette ligne une fois pour toutes dans votre fichier de démarrage ~/.bash_login, pour ne plus avoir à la taper)
Sur Mac OS X, après avoir installé IDL 8.2 (par exemple) pour Mac OS, il suffira d'ajouter ces 2 lignes dans votre fichier de démarrage .bash_login :
> >
Sur MacOS ou Linux (après avoir installé IDL), placer les 2 lignes suivantes (une fois pour toutes) dans votre fichier de démarrage .bash_login (depuis votre répertoire home, ou bien ~/.bash_login directement depuis n'importe où), pour ne plus avoir à les taper :
Pour votre cas personnel, dans votre fichier .bash_login, il faudra mettre le chemin vers votre installation d'idl (par exemple /Applications/exelis/idl83/bin pour idl 8.3, ou bien /Users/monlogin/Applications/exelis/idl83/bin si c'est une installation d'idl 8.3 seulement sur votre compte)
> >
Il vous faudra remplacer PATH_TO_IDL_BIN par le chemin vers VOTRE installation d'idl (par exemple pour idl 8.3 sur MacOS : /Applications/exelis/idl83/bin ou bien /Users/monlogin/Applications/exelis/idl83/bin si c'est une installation seulement sur votre compte)
Changed:
< <
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
> >
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac).
Si vous êtes à l'extérieur du labo, continuez la lecture...
Line: 1185 to 1181
b) "Creuser" un tunnel
Changed:
< <
Utilisateurs Mac et Linux
> >
Utilisateurs Mac et Linux :
Pour les personnes qui utilisent Windows, aller à la section suivante "Utilisateurs Windows (avec Putty)"
Ouvrir un terminal
Exécuter le fichier de creation du tunnel vers hyperion :
./A_EXECUTER_DEPUIS_CHEZ_MOI_AVANT_IDL.sh
Lancer votre idl
Fermer le tunnel vers hyperion seulement quand vous avez terminé de travailler avec idl : (taper "exit" dans le terminal)
Added:
> >
* Mon poste tourne avec Windows :
Added:
> >
Ouvrir Putty et exécuter votre session nommée "use_hyperion_idl_license" (ou autre nom que vous avez donné à cette session)
Lancer votre idl
Fermer cette session seulement quand vous avez terminé de travailler avec idl
Changed:
< <
> >
Bon, on peut encore améliorer les choses... si ça vous dit, allez voir un peu plus loin, juste après la partie IN ENGLISH.
PREREQUIS : idl doit être installé localement sur votre pc
a) Positionner une variable d'environnement
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
Pour votre cas personnel, dans votre fichier .bash_login, il faudra mettre le chemin vers votre installation d'idl (par exemple /Applications/exelis/idl83/bin pour idl 8.3, ou bien /Users/monlogin/Applications/exelis/idl83/bin si c'est une installation d'idl 8.3 seulement sur votre compte)
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Si vous êtes à l'extérieur du labo, continuez la lecture...
Line: 1187 to 1191
Ouvrir un tunnel avec mise en correspondance de 2 ports :
* (remplacer MON_LOGIN_EMAIL par votre login utilisé pour le mail ou pour vous connecter à la passerelle du labo, et GATEWAY par le serveur passerelle du labo)
Changed:
< <
(remplacer MON_LOGIN_EMAIL par votre login utilisé pour le mail ou pour vous connecter à la passerelle du labo, et GATEWAY par le serveur passerelle du labo)
> >
* Sauvegarder ce fichier
* Rendre ce fichier exécutable en tapant la commande suivante : chmod +x A_EXECUTER_DEPUIS_CHEZ_MOI_AVANT_IDL.sh
* Exécuter ce fichier : ./A_EXECUTER_DEPUIS_CHEZ_MOI_AVANT_IDL.sh
* Entrer votre login et mot de passe (du webmail)
(Remarque pour l'admin système : attention, sur le localhost on a le choix de la correspondance du port 1700 d'hyperion (port 9700 local) mais pas pour le 1701)
Changed:
< <
Allez maintenant à la section "c) Se connecter"
> >
Allez maintenant à la section "c) Lancer idl"
Line: 1233 to 1249
Exécuter cette session en cliquant sur le bouton "Open"
Deleted:
< <
c) Se connecter
Entrer votre login et mot de passe (du webmail)
Added:
> >
c) Lancer idl
Voilà, vous avez créé un tunnel entre votre pc/mac et hyperion, passant par GATEWAY (vous êtes d'ailleurs connecté à la passerelle).
Il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Attention, une fois la session idl terminée, ne pas oublier de détruire le tunnel en vous déconnectant d'hyperion !!! (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
Added:
> >
d) ON RECAPITULE ?
Une fois les étapes ci-dessus réalisées, voici ce que vous avez à faire pour exécuter idl :
Je suis au labo
Rien à faire ! Juste lancer idl (ou idlde), c'est tout !
* Je suis chez moi
* Mon poste tourne avec MacOS ou Linux :
Ouvrir un terminal
Exécuter le fichier de creation du tunnel vers hyperion :
./A_EXECUTER_DEPUIS_CHEZ_MOI_AVANT_IDL.sh
Lancer votre idl
Fermer le tunnel vers hyperion seulement quand vous avez terminé de travailler avec idl : (taper "exit" dans le terminal)
* Mon poste tourne avec Windows :
Ouvrir Putty et exécuter votre session nommée "use_hyperion_idl_license" (ou autre nom que vous avez donné à cette session)
Lancer votre idl
Fermer cette session seulement quand vous avez terminé de travailler avec idl
Utiliser mon IDL au labo ou bien à l'extérieur du labo (en une seule config)
> >
Utiliser mon IDL perso (de mon pc) depuis l'extérieur du labo (mais aussi à l'intérieur) (en une seule config)
Changed:
< <
Problème : Comment exécuter mon idl (celui qui est installé localement sur mon pc/mac) au labo et même à l'extérieur du labo ???
> >
Problème : Comment exécuter mon idl (celui qui est installé localement sur mon pc/mac) à l'extérieur du labo (mais aussi à l'intérieur) ???
Réponse : en profitant des licences du serveur hyperion
Changed:
< <
En ce qui vous concerne, allez directement au point 2)
> >
Il s'agit de faire une configuration unique qui vous permettra d'utiliser votre idl installé sur votre portable, quelque soit votre situation, aussi bien :
à l'extérieur du labo
en wifi (y-compris wifi IRAP au labo)
à l'intérieur du labo, dans votre bureau, branché avec un câble réseau
Comprenez bien qu'il s'agit d'exécuter l'idl de votre portable, PAS CELUI d'HYPERION.
Donc, vous n'aurez pas accès aux données qui sont sur hyperion, sauf si vous en avez une copie locale sur votre portable.
Si vous voulez exécutez idl SUR HYPERION, alors c'est différent, il s'agit seulement de se connecter à hyperion via la passerelle
(voir à ce sujet la section "Accès à hyperion avec Putty")
Si vous êtes toujours partants, allez directement au point 2)
1) Travail à faire pour l'administrateur système sur hyperion
Line: 1145 to 1154
2) Pour vous (côté client), Il suffit de faire 2 choses sur votre pc/mac
Added:
> >
NB: For English readers, go to section 3) below
a) Positionner une variable d'environnement
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
Pour les personnes qui utilisent Windows, aller à la section suivante "Utilisateurs Windows (avec Putty)"
Ouvrir un tunnel avec mise en correspondance de 2 ports :
Line: 1180 to 1193
(Remarque pour l'admin système : attention, sur le localhost on a le choix de la correspondance du port 1700 d'hyperion (port 9700 local) mais pas pour le 1701)
Changed:
< <
Entrer le mot de passe pour GATEWAY (pour vous connecter de votre pc à GATEWAY)
Host Name = GATEWAY (nom à remplacer par le VRAI, avec son adresse complète (nom + domaine), nom que je tairai sur cette page publique)
port = 22
connection type = ssh
Déployer la catégorie "Connection/Session" (dans le panneau de gauche, en bas), et sélectionner "Tunnels"
Créer 2 tunnels :
local:9700 vers hyperion:1700 :
Source port : 9700
Destination : hyperion.cesr.fr:1700
cliquer sur bouton Add
local:1701 vers hyperion:1701 :
Source port : 1701
Destination : hyperion.cesr.fr:1701
cliquer sur bouton Add
Sauvegarder cette session
Cliquer sur la catégorie "Session" (dans le panneau de gauche, en haut)
Donner un nom à cette session dans le champ "Saved Sessions", par exemple "use_hyperion_idl_license"
Cliquer sur le bouton "Save"
Exécuter cette session en cliquant sur le bouton "Open"
c) Se connecter
Entrer votre login et mot de passe (du webmail)
Voilà, vous avez créé un tunnel entre votre pc/mac et hyperion, passant par GATEWAY (vous êtes d'ailleurs connecté à la passerelle).
Line: 1188 to 1244
Attention, une fois la session idl terminée, ne pas oublier de détruire le tunnel en vous déconnectant d'hyperion !!! (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
Added:
> >
Bon, on peut encore améliorer les choses... si ça vous dit, allez voir un peu plus loin, juste après la partie IN ENGLISH.
Changed:
< <
Now, IN ENGLISH (and for Mac/Linux users only) :
> >
3) Now, IN ENGLISH (and for Mac/Linux users only) :
(First, be sure you have removed any remaining license.dat file from your itt/license/ directory ; just drop it, you don't need it)
Changed:
< <
1) set and export LM_LICENSE_FILE
> >
3.1) set and export LM_LICENSE_FILE
Open a new terminal and set this variable :
Line: 1207 to 1266
If you are OUTSIDE the lab, you need one last step...
Changed:
< <
2) set a tunnel
> >
3.2) set a tunnel
Open a new terminal and create this tunnel :
Line: 1222 to 1281
Changed:
< <
ETAPE FACULTATIVE : On peut encore améliorer les choses... Comment ?
> >
4) ETAPE FACULTATIVE : On peut encore améliorer les choses... Comment ?
En s'arrangeant pour ne plus avoir aucun mot de passe à entrer grâce aux clés publique&privée.
Voici comment faire...
Changed:
< <
1) Créer une paire de clés privée/publique sur mon pc
> >
4.1) Créer une paire de clés privée/publique sur mon pc
$ ssh-keygen -t dsa
Line: 1240 to 1299
Your public key has been saved in /Users/pallier/.ssh/id_dsa.pub.
Changed:
< <
2) Distribuer ensuite la clé publique de mon pc sur la passerelle du labo (que nous appelerons GATEWAY pour raison de sécurité)
> >
4.2) Distribuer ensuite la clé publique de mon pc sur la passerelle du labo (que nous appelerons GATEWAY pour raison de sécurité)
La clé publique, doit être copiée sur le serveur distant dans ~/.ssh/authorized_keys. (La clé privée reste sur votre poste client)
Pour accéder au site de réservation des ressources, il suffit de faire comme au premier point ci-dessus (intranet), et de renseigner l’adresse du site : https://localhost:9443/grr
Added:
> >
Accès à hyperion avec Putty
Comment accéder à un serveur interne au labo depuis l'extérieur, avec le logiciel Putty (souvent utilisé sur Windows)
(le "-X" pas nécessaire si on ne veut pas d'affichage graphique)
(attention, ici utiliser le login hyperion, pas celui du webmail)
puis entrer votre mot de passe de hyperion (pas celui du webmail)
==> c'est bon, on est sur hyperion
11) Tester si on a bien une connexion graphique
xterm
ou bien démarrer idl et faire un plot
Si ça ne marche pas c'est qu'il faut donner le nom exact du DISPLAY dans la session putty.
Depuis hyperion, pour voir le numero exact du display (normalement quelque chose comme localhost:11.0 ou 11.1...), taper :
echo $DISPLAY
et mettre ce nom dans putty, dans SSH/X11/"X display location" (avec "Enable X11 forwarding" coché)
A. Solution avec tunnel
Si on a besoin de faire ça souvent, il vaut mieux "creuser" un tunnel d'accès direct au serveur hyperion (ou autre),
afin de pouvoir s'y connecter directement (sans l'étape passerelle, qui devient un intermédiaire transparent).
MacOS propose un "super-daemon" launchd qui regroupe les fonctionnalités de init (lance démon lors du démarrage), crond (lance démon lors de top horaires), et (x)inetd (lance démon lors de requêtes réseaux)
Added:
> >
CRON
Pour tester manuellement une entrée du cron.daily :
run-parts /etc/cron.daily
FTP
ex: installation ftp pour l'expérience RAMAN (sur ExoMars)
(le moi@PASSERELLE est nécessaire pour que je puisse aussi me connecter depuis chez moi)
/etc/init.d/sshd restart
Si j'essaye une connexion (moi ou root) depuis MONPC, ça passe
Si j'essaye une connexion (moi ou root) depuis un AUTREPC, je suis rejeté
On voit le refus de connexion dans /var/log/secure :
User root from AUTREPC not allowed because not listed in AllowUsers
Jul 16 14:57:06 planetoweb sshd[28008]: input_userauth_request: invalid user root
Jul 16 14:57:11 planetoweb sshd[28007]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=AUTREPC user=root
Jul 16 14:57:13 planetoweb sshd[28007]: Failed password for invalid user root from AUTREPC_IP port 60246 ssh2
2) Encore plus strict, AUCUN accès ssh direct en root autorisé
(il suffit de taper une seule fois "exit" pour revenir à mon pc)
Added:
> >
IDL 8.1 installer SVN
Selectionner Window/Source Control Tools/Subversion
Selectionner le connecteur SVN nommé SVNKit 1.3.0 (for svn 1.6.2) (ou un plus ancien car le serveur svn qui est sur planetoweb est une ancienne version 1.4.4)
Terminer l'installation, redémarrer IDL, c'est fait
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Ne pas oublier de noter tout ce que tu fais. Rédige au fur et à mesure (avec OpenOffice).
> >
Comment accéder au site redmine depuis l'extérieur ?
Changed:
< <
NOUVELLES MODIFS FAITES :
> >
C'est la même chose qu'au point précédent, mais en remplaçant SERVEURINTRANET par SERVEURREDMINE
Changed:
< <
4 juin :
VII-3 c) relation 1-1
> >
Réservation des ressources depuis l'extérieur du labo (avec tunnel)
Changed:
< <
16 mai :
IX-5
X - Documentation
> >
Pour accéder au site de réservation des ressources, il suffit de faire comme au premier point ci-dessus (intranet), et de renseigner l’adresse du site : https://localhost:9443/grr
By default, Vim runs in "compatible" mode. That is, it acts a lot like traditional vi, without the improvements. Unless you want a maximally vi-compatible version of vim, I recommend that you copy the standard startup files to your home directory, and name them .vimrc and .gvimrc.
Changed:
< <
(pas encore sûr, à réfléchir) ajouter un script qui permet de définir un tableau de champs obligatoires pour un Modèle donné ==> Ces champs devront obligatoirement être saisis dans les vues associées au Modèle (voir http://book.cakephp.org/1.3/view/1147/required)
File permissions are being checked...ok.
Starting XAMPP for Mac OS X 1.7.3...
XAMPP: Starting Apache...ok.
XAMPP: Starting MySQL...ok.
XAMPP: Starting ProFTPD...XAMPP/XAMPP/xamppfiles/xampp: line 184: /Applications/XAMPP/xamppfiles//var/proftpd/start.err: No such file or directory
fail.
Contents of "/Applications/XAMPP/xamppfiles//var/proftpd/start.err":
cat: /Applications/XAMPP/xamppfiles//var/proftpd/start.err: No such file or directory
Added:
> >
4) Tester
Changed:
< <
III - En s'inspirant du tutoriel "blog", commmencer à construire une architecture à partir d'un sous-ensemble de la BDD Europlanet
2) Construire un schéma d'une petite BDD avec MysqlWorkbench
Ce schéma contient 7 tables principales :
- people (lien N-1 avec institutes, status, et profiles, et 1-N avec resources) : id, name, firstname, email, password, status, active, job, created, updated (le champ "active" est un booléen VRAI par défaut)
- status : id, name (avec les valeurs suivantes pour name : NULL, 'registered', 'invalidated', 'validated')
- profiles : id, name, level (level indique la hiérarchie ; name et level ont les valeurs suivantes : {'admin',10}, {'priv',5}, {'validator',3}, {'normal',0} ; donc on a la hiérarchie admin > priv > validator > normal)
- institutes : id, name, created, updated
- expertises : id, name (lien M-N avec people)
- resources (lien M-N avec sciencases) : id, name, created, updated
- sciencecases : id, name, created, updated
resources_sciencecases : avec les champs resources_id et sciencecases_id (les 2 clés étrangères formant la clé primaire de la table)
expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table)
> >
Si plus tard on remplace la page d'accueil de XAMPP par la sienne, on peut toujours joindre la page d'accueil de XAMPP avec http://localhost/xampp/
Changed:
< <
Tous les champs sont obligatoires (NOT NULL), sauf people.job (default NULL).
> >
5) Aspects sécurité
Changed:
< <
Toutes les clés primaires (id) sont autoincrémentées.
> >
Comme cela a déjà été expliqué antérieurement XAMPP n'est pas fait pour l'emploi de production, mais seulement pour développeur et l'environnement du développement. Cela a pour suite que XAMPP est volontairement préconfiguré pour ne pas être restrictif et être au contraire trés ouvert. Pour un développeur cela est idéal qu'il ne soit pas limité par les limites du systéme. Par contre pour un emploi en production cela est absolument pas recommendable.
Changed:
< <
Les champs "created" et "updated" sont gérés automatiquement par cakephp.
> >
Ici, une liste de choses donc XAMPP est volontairement(!) insécurisé:
Changed:
< <
Ajouter la contrainte "on delete CASCADE" (avec MysqlWorkbench) sur les clés étrangères des tables M-N (resources_sciencecases et expertises_people)
> >
1. L'administrateur (root)MySQL n'a pas de mot de passe.
2. Le démon MySQL est joignable par le réseau.
3. Le démon ProFTPD utilise le mot de passe "xampp".
4. PhpMyAdmin est joignable par le réseau.
5. MySQL et Apache fonctionne sous le même utilisateur (nobody)
Changed:
< <
Ajouter la contrainte "on delete NULL" sur toutes les clés étrangères des autres tables (people, resources)
> >
Dans la page XAMPP-Demo (que l'on trouve sous http://localhost) il y a le point "Security check". À cet endroit on peut faire apparaître le niveau de sécurité actuel de XAMPP.
Changed:
< <
Générer le script sql de création de la base.
> >
Si on veut utiliser XAMPP en réseau , pour que le serveur XAMPP soit accessible par d'autres utilisateurs, alors il faut impérativement exécuter les commandes suivantes avec lesquelles ont pourra alors limiter les failles de sécurité:
Changed:
< <
Vérifier que MysqlWorkbench ajoute bien les contraintes sur les clés étrangères (FK = "Foreign Key")
> >
/Applications/XAMPP/xamppfiles/xampp security
Deleted:
< <
Alimenter les tables avec des données quelconques
Changed:
< <
3) Configurer l'accès à la BDD
login : epn
pass : pass
To start XAMPP simply open XAMPP Control and start Apache, MySQL and ProFTPD.
Changed:
< <
Par défaut, l'action "people/index" ne doit afficher que les personnes dont le champ "active" est à TRUE et le champ "status" vaut "validated"
> >
Mais, on peut aussi utiliser la commande /Applications/XAMPP/xamppfiles/xampp :
Changed:
< <
5) Lancer les tests générés par "bake" (avec phpUnit, inclus dans Xampp ?) pour tester les modèles et les contrôleurs
http://book.cakephp.org/2.0/en/development/testing.html
cake bake fixture all ?
cake bake test all ?
Depuis cakephp 2.1 :
Console/cake test app/Model/Post.php
Console/cake test app/Controller/PostsController.php
> >
on peut non seulement démarrer Xampp mais aussi exécuter d'autres commandes :
Changed:
< <
6) Ajouter la validation des champs de tous les formulaires
http://book.cakephp.org/2.0/en/models/data-validation.html
"bake" ajoute des validations par défaut. Les étendre si nécessaire pour que toutes les validations soient générées automatiquement, en fonction du type des champs.
Vérifier que les champs obligatoires sont bien obligatoires en saisie.
Ajouter un test pour s'assurer qu'une personne est obligée de remplir tous les champs (sauf people.job) quand elle s'enregistre.
> >
Pour arrêter XAMPP simplement entrer cette commande:
Added:
> >
/Applications/XAMPP/xamppfiles/xampp stop
Added:
> >
Pour démarrer Apache avec support SSL suivre les commandes suivantes:
(il suffit de placer /Applications/XAMPP/xamppfiles/bin dans mon $PATH pour que j'ai accès à toutes les commandes de xampp directement, telles que "mysql")
Changed:
< <
V - Authentification et Contrôle d'accès
> >
/Applications/XAMPP/xamppfiles/bin/mysql appelle par ex .MySQL.
Changed:
< <
1) Ajouter l'authentification (AUTH)
Login = email
Auth (et Acl) doivent avoir pour support la table "people" (et status et profiles).
Auth (et Acl) impliquent aussi l'usage des Sessions (http://book.cakephp.org/2.0/en/development/sessions.html)
Astuce : dans la session, stocker l'id de la personne, et non pas son email (car l'email peut changer, mais pas l'id)
> >
/Applications/XAMPP/htdocs/
Changed:
< <
Toute personne non authentifiée (accès anonyme) peut :
- lire (R ) toutes les tables, sauf la table "resources"
- s'enregistrer (droit C sur la table people)
> >
Le répertoire Root du serveur web Apache. Ici sont les pages web d'Apache.
Changed:
< <
Toute personne authentifiée peut :
- lire (R ) toutes les tables (y-compris "resources")
- modifier (U) sa fiche (sauf son profil), mais pas celle des autres
- créer (C ) une ressource
- modifier/supprimer (UD) une ressource qu'elle a créée, mais pas celles des autres
- modifier (U) un institut auquel elle appartient
> >
/Applications/XAMPP/etc/httpd.conf
Changed:
< <
Gérer le login et le logout
> >
Le fichier central de configuration du serveur web Apache.
Changed:
< <
Ajouter les tests nécessaires :
(Utiliser des "fixtures", cf section "Fixtures" dans http://book.cakephp.org/2.0/en/development/testing.html)
(cake bake fixture all ?)
Tester qu'une personne non authentifiée :
- peut lire la table 'resource'
- peut s'enregistrer
- ne peut pas modifier une table
Tester qu'une personne authentifiée peut :
…
Faire un test login/logout complet selon le scénario suivant :
- une personne se logue
- vérifier qu'elle peut créer une ressource
- elle se délogue
- vérifier qu'elle ne peut plus créer une ressource
> >
/Applications/XAMPP/etc/my.cnf
Added:
> >
Le fichier de configuration pour le serveur MySQL-Base de données.
Changed:
< <
2) Ajouter le contrôle d'accès (ACL)
> >
/Applications/XAMPP/etc/php.ini
Changed:
< <
Créer quelques personnes avec des rôles (profils) différents :
'user1', profil 'admin' (tous les droits)
'user2' et 'user3', profil 'normal', utilisateur normal
'user4', profil 'priv', utilisateur privilégié
'user5', profil 'validator', utilisateur pouvant valider d'autres utilisateurs
> >
Le fichier de configuration de PHP.
Changed:
< <
Une personne de profil 'admin' a un droit CRUD (créer/lire/modifier/supprimer) sur toutes les tables.
> >
/Applications/XAMPP/etc/proftpd.conf
Changed:
< <
Une personne de profil 'priv' :
a un droit CRUD seulement sur la table 'institutes'
peut modifier le profil de toutes les personnes (sauf le sien)
tester que 'user1' peut tout faire (faire juste quelques tests, pas tout)
tester que 'user4' : * peut ajouter un nouvel institut * peut modifier le profil d'une personne (mais pas le sien)
tester que 'user2' : * ne peut pas modifier une ressource qui ne lui appartient pas * peut ajouter une nouvelle ressource, et la modifier ensuite * peut modifier son email (login) et/ou son mot de passe
...
> >
8) Mes Sites Webs
Added:
> >
You can put your Websites in /Applications/XAMPP/htdocs/ and access them via http://localhost/
Changed:
< <
VI - ENREGISTREMENT DES UTILISATEURS (registration)
> >
Or you put your Websites in the Sites-Folder in your Home and access them via http://localhost/~pallier/.
Changed:
< <
1) Réalisation de la procédure d'enregistrement (inscription) d'une personne :
(voir s'il n'existe pas déjà un plugin cakephp pour gérer ça, car c'est assez classique au début)
> >
Username: root
Password: No password
Deleted:
< <
a) une personne remplit sa fiche d'enregistrement et la soumet (SUBMIT) ==> elle est enregistrée dans la table people avec "status" à NULL
Changed:
< <
b) elle reçoit un 1er mail de confirmation avec un lien de validation
> >
9) Désinstallation
Changed:
< <
c) elle clique sur le lien de validation, ce qui valide son inscription ==> son champ "status" passe à "registered" ; les validateurs reçoivent un mail pour les avertir de cette inscription, avec un lien vers la page du site permettant de valider ou invalider la personne
> >
To uninstall XAMPP just stop it and move it to the Trash.
Changed:
< <
d) elle reçoit un 2e mail de confirmation lui disant qu'elle est inscrite, MAIS qu'elle doit attendre que son inscription soit validée par un 'validateur', et qu'elle recevra un mail pour le lui confirmer
> >
Ou bien
Changed:
< <
e) si un validateur valide l'inscription, la personne reçoit un mail pour l'en informer (à partir de là, elle peut se connecter au site) ==> son "status" passe à "validated"
> >
sudo rm -rf /Applications/XAMPP
Deleted:
< <
f) si un validateur invalide l'inscription, la personne reçoit un mail pour l'en informer ==> son "status" passe à "invalidated"
Deleted:
< <
Ajouter les actions suivantes au Contrôleur "person" :
validate (profil 'validator') : pour valider une personne (champ "status")
invalidate (profil 'validator') : pour invalider une personne
deleteInvalidated (profil 'priv') : pour supprimer les personnes ayant un statut "invalidated"
activate (profil 'priv') : pour activer une personne (champ "active")
deactivate (profil 'priv') : pour désactiver une personne
Changed:
< <
Ajouter/modifier les tests nécessaires
> >
Installation AMP (Apache Mysql Php) en utilisant MacPort
Sur le formulaire de login, ajouter (à droite du bouton LOGIN) un lien "register" (pour s'enregistrer) et un lien "forgot password" (mot de passe oublié)
> >
Ouvrez le fichier .dmg que vous venez de télécharger
Changed:
< <
Le lien "forgot password" pointe vers un formulaire de modification du mot de passe (Person/PasswordUpdate) contenant juste 1 champ "email" et un bouton "SUBMIT"
> >
Lancez le fichier .pkg et suivez les instructions
Changed:
< <
L'utilisateur saisit son email et clique sur "submit" pour qu'on lui envoie un nouveau mot de passe par mail (le mot de passe est aussi mis à jour dans la database)
> >
Crée un fichier ~pallier/.bash_login qui ajoute /opt/local/bin au PATH
Changed:
< <
Test
> >
sudo port -v selfupdate
Added:
> >
Installation Apache 2
Changed:
< <
4) Procédure de désinscription (ACTION unregister)
> >
Téléchargez et installez Apache2 et ses dépendances :
Changed:
< <
a) une personne clique sur un lien "unregister"
> >
sudo port install apache2
Changed:
< <
b) une confirmation est demandée via une fenêtre javascript : "Are you sure that you want to unregister ?" OK/CANCEL
> >
Une fois l’installation terminée, vous pouvez activer lancement automatique de Apache au démarrage de l’ordinateur :
Changed:
< <
c) l'action "unregister" est exécutée, la personne n'est pas supprimée de la base, mais juste marquée "inactive"
> >
sudo port load apache2
Changed:
< <
d) la personne est automatiquement déconnectée
> >
fichiers sont dans /Library/LaunchDaemons/org.macports.apache2.plist
Actions sur Person (relation M-N avec Expertise) :
create : doit permettre d'ajouter des expertises (ET une date "since")
update : doit permettre de modifier les expertises associées
view : doit permettre de voir toutes les expertises associées
Idem pour Expertise (lien vers Person)
> >
Une fois l’installation terminée, vous pouvez lancer MySQL au démarrage de l’ordinateur :
Changed:
< <
Même chose pour Resource (relation M-N avec Sciencecase)
> >
sudo port load mysql5
Deleted:
< <
Gestion des champs supplémentaires d'une table associative : exemple de la relation entre Person et Expertise :
Changed:
< <
expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table) et le champ supplémentaire "since" (date à laquelle l'expertise a été acquise)
> >
Installation PHP 5.3
Added:
> >
Téléchargez et installez PHP 5.3 et ces dépendances. A noter ici que je choisi également d’activer le PEAR, d’où le +pear.
Changed:
< <
3) Gérer d'autres types de relations
> >
sudo port install php5 +pear
Changed:
< <
a) Ajout de plusieurs rôles différents entre 2 mêmes tables
sudo /opt/local/apache2/bin/apxs -a -e -n "php5" /opt/local/apache2/modules/libphp5.so
Changed:
< <
Une personne peut avoir plusieurs liens avec une ressource (plusieurs liens entre les tables "people" et "resources"), ce qui veut dire qu'elle peut jouer plusieurs rôles par rapport à une ressource.
Ainsi, au lieu d'avoir seulement une clé étrangère "resources_id" dans la table "people", nous en aurons plusieurs avec des noms différents :
resource_provider_id : la personne qui a donné l'information sur la ressource (et qui l'a saisit)
resource_owner_id : le propriétaire de la ressource
resource_contact_id : le contact pour la ressource
Ces 3 clés pointent toutes vers la même clé primaire resource.id, et sont donc des "alias".
Améliorer les actions CRUD en conséquence
Ajout d'une relation réflexive sur "institutes" (dans ce cas particulier, il s'agit d'une relation hiérarchique) :
un institut peut appartenir à un autre institut (de niveau hiérarchique supérieur ; par exemple, le "CNRS" regroupe plusieurs instituts, "l'OMP" regroupe plusieurs laboratoires dont l'IRAP…)
cela revient seulement à ajouter un champ "institute_id" dans la table institutes (qui pointe sur la table institute, lien réflexif)
chaque type de ressource est une spécialisation du type général "resource".
> >
Configuration de votre environnement LAMP
Deleted:
< <
On aura donc 4 nouvelles tables filles "resourcedata", "resourceinfo", "resourcewebsite", "resourcedatacenter" qui "hériteront" de la table mère (générique) "resource" pour l'étendre chacune avec sa spécificité.
Changed:
< <
On peut représenter ce lien d'héritage par une relation 1-1 entre chacune de ces 4 tables filles et la table mère "resource".
> >
Configuration Apache 2
Changed:
< <
Aucune des tables filles n'a d'existence propre, chacune dépend de la table mère "resource".
> >
Les étapes ci-dessous permettent de configurer le support de PHP dans Apache et d’activer le module UserDir (facultatif).
Changed:
< <
Ainsi, les tables filles n'ont pas de clé primaire, mais juste une clé étrangère (resource_id) qui pointe vers la clé primaire de la table mère (cette clé étrangère peut aussi leur servir de clé primaire).
> >
Activer PHP dans Apache
Éditez le fichier /opt/local/apache2/conf/httpd.conf
Ajoutez à la fin du fichier
Changed:
< <
Cette relation d'héritage a un impact sur toutes les VUES de la table "resource", car à chaque fois qu'on veut accéder à une ressource,
il faut récupérer aussi les informations spécifiques à son type dans la table fille associée (via la clé étrangère resource_id).
> >
# Include PHP configuration
Include conf/extra/mod_php.conf
Changed:
< <
Plus particulièrement, la vue "Create" (et "Update") devra contenir un sélecteur de type ("Type de ressource"),
et n'afficher que les champs spécifiques au type sélectionné (en plus des champs généraux de la table mère).
> >
Ajouter index.php dans les pages d’index reconnues par Apache
Éditez le fichier /opt/local/apache2/conf/httpd.conf
Recherchez la ligne ci-dessous :
Changed:
< <
Ajouter dans la table resource un champ "URL" (général à tous les types)
Voici les informations spécifiques à chaque type, et donc présent dans les tables filles respectives :
> >
Ajoutez sur la même ligne, à la fin :
Changed:
< <
table data :
volume (en MB) :
restricted (oui/non)
> >
index.php
Changed:
< <
table info (information, document...) :
langage (champ texte liste : English, French, Spanish...)
> >
Étape optionnelle : Activer l’extension UserDir pour Apache. Cette extension permet d’avoir des urls dédiées pour chaque utilisateur de l’ordinateur du type http://localhost/~utilisateur/
Éditez le fichier /opt/local/apache2/conf/httpd.conf
Recherchez et décommentez la ligne ci-dessous :
Changed:
< <
table website :
restricted (oui/non)
nom du webmaster (champ texte libre)
> >
#Include conf/extra/httpd-userdir.conf
Changed:
< <
table datacenter :
nom du responsable (champ texte libre)
> >
Étape optionnelle : Autoriser l’ajout/suppression d’options via un .htaccess (exemple Options +FollowSymLinks)
Éditez le fichier /opt/local/apache2/conf/extra/httpd-userdir.conf
Recherchez la ligne ci-dessous :
VIII - Ajout d'une nouvelle action dans TOUS les Contrôleurs : search
> >
Options
Changed:
< <
ex : Person/search
> >
Une fois les modifications effectuées, vous pouvez (re)démarrer Apache :
Changed:
< <
Cela amène à une nouvelle vue PersonSearch qui est équivalente au formulaire de Person/create,
sauf qu'au lieu de servir à créer une nouvelle personne, il sert à en CHERCHER.
> >
sudo /opt/local/apache2/bin/apachectl restart
Changed:
< <
L'ensemble des personnes trouvées sont affichées dans une vue "FOUND" semblable à Person/index (sauf que c'est une vue PARTIELLE et non pas COMPLETE).
Les recherches se font sans tenir compte des majuscules ou minuscules.
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier", par exemple "Apallieri"...
j'entre "Pallier" dans le champ "name", "Etienne" dans le champ "firstname", et "informaticien" dans le champ "job" :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier" ET le prénom EST EGAL à "Etienne" ET le job EST EGAL à "informaticien"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier" ET le prénom CONTIENT "Etienne" et le job CONTIENT "informaticien"
> >
sudo /opt/local/lib/mysql5/bin/mysqld_safe &
Changed:
< <
Cette VUE "search" doit être accessible par un lien qui se trouve au début de la vue "index", sous la forme d'une icône en forme de LOUPE suivie de la mention "Search"
> >
Sécurisez votre serveur MySQL. Je vous recommande de configurer le mot de passe root et de répondre « Yes » à toutes les questions.
Configurer MySQL pour PHP
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez les paramètres pdo_mysql.default_socket, mysql.default_socket, mysqli.default_socketet mettez comme valeur ceci :
Changed:
< <
1) ajouter les liens généraux suivants :
"login" (qui n'apparaît que si l'utilisateur n'est pas logué)
et les liens "logout", "update my registration" et "unregister" (qui n'apparaissent que si l'utilisateur est logué)
> >
/opt/local/var/run/mysql5/mysqld.sock
Changed:
< <
2) Vue "view" : vue détaillée d'une ligne de table
> >
Configurer le fuseau horaire par défaut
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez la ligne suivante :
Changed:
< <
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
> >
;date.timezone =
Changed:
< <
Ajouter les boutons "Edit", "Delete" et "Create a copy" (visibles uniquement avec le profil "admin")
> >
Remplacez par :
Changed:
< <
Pour le formulaire Person, le bouton "Edit" est aussi visible si la personne connectée correspond à la fiche visualisée.
> >
date.timezone = "Europe/Paris"
Changed:
< <
3) Action "index" : vue globale d'une table
> >
Étape optionnelle : Activer les archives Phar
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez et décommentez la ligne ci-dessous
Changed:
< <
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
> >
;phar.readonly = On
Changed:
< <
Masquer la clé primaire (id)
> >
Une fois les modifications terminées, redémarrez votre serveur Apache 2.
Deleted:
< <
La colonne du champ "name" est triable : en cliquant sur la colonne "name", on trie en ordre croissant, puis décroissant
Changed:
< <
Le champ "name" est cliquable : en cliquant sur un nom, on va à la vue détaillée correspondante
> >
Gestion
Changed:
< <
Afficher le champ "name" des clés étrangères ; en cliquant dessus on va sur la vue détaillée
> >
Apache :
Changed:
< <
Les colonnes des clés étrangères sont filtrables : dans la vue people/index, en cliquant sur la colonne "institutes_id" on doit pouvoir sélectionner un nom d'institut (name) et filtrer la vue en conséquence
Au-dessus de la liste d'une table, ajouter un "filtre externe" pour chaque table M-N associée :
par exemple, pour la vue people/index, ajouter au-dessus de la liste des personnes une liste d'expertises : en sélectionnant une expertise, on ne voit plus que les personnes associées à cette expertise
> >
start : sudo port load apache2 (apachectl start/stop ne semble pas marcher)
Changed:
< <
En début de page, ajouter un bouton "Add a new one"
> >
Voir les processus apache : ps -efl|grep apac
Changed:
< <
4) Ajouter les nouveaux tests nécessaires
> >
stop : sudo port load apache2
Changed:
< <
5) Ajouter une page contenant tous les tests, avec un bouton permettant de lancer tous les tests à la suite "LAUNCH ALL TESTS"
> >
(le Apache d'origine de Mac est démarré via les préférences systèmes, partage, web : on voit alors les processus avec "ps -efl | grep http")
Installation AMP (Apache Mysql Php) en utilisant les packages Mac OS pré-existant
Changed:
< <
Ajout d'une gestion de menu
> >
apache déjà installé, mais pas activé
Added:
> >
php déjà installé mais pas activé
Added:
> >
mysql à installer
Changed:
< <
XII - Ajout de modules
> >
Apache
Changed:
< <
Ajout d'un module de News
> >
Pour activer le serveur, allez dans Préférences système -> Partage et cochez la case Partage Web. Si elle est déjà cochée, décochez-la pour arrêter le serveur et recochez-là pour que la modification du fichier httpd.conf soit prise en compte.
Changed:
< <
Ajout d'un module d'upload de documents
> >
v2.2.20
Changed:
< <
Newsletter
> >
/usr/sbin/
Changed:
< <
...
> >
Documents : /Library/Webserver/Documents/
Changed:
< <
XIII - Charte graphique
> >
PHP
Changed:
< <
Gestion de la présentation avec CSS
> >
v5.3.6
Added:
> >
Php : /usr/lib/
Changed:
< <
...
> >
Pour activer PHP il faut décommenter la ligne #LoadModule php5_module libexec/apache2/libphp5.so du fichier httpd.conf situé dans le dossier apache2 du dossier etc.
Changed:
< <
XIV - Intégrer la BDD Europlanet complète
> >
Ensuite réactiver le serveur apache (voir ci-dessus)
Added:
> >
Ajouter test.php dans le rep doc de apache qui contient :
By default, Vim runs in "compatible" mode. That is, it acts a lot like traditional vi, without the improvements. Unless you want a maximally vi-compatible version of vim, I recommend that you copy the standard startup files to your home directory, and name them .vimrc and .gvimrc.
> >
su -
Changed:
< <
Ce que j'ai fait simplement :
> >
ou
Changed:
< <
1) recherche de vimrc_example :
> >
su - root
Changed:
< <
locate vimrc
> >
ou
Changed:
< <
2) Copie locale :
> >
sudo -s
Deleted:
< <
cp /usr/share/vim/vim73/vimrc_example.vim .vimrc
Changed:
< <
Installation AMP avec XAMPP (solution la plus simple, bien pour le développement, mais pas très blindée pour un serveur de production)
> >
changer définitivement le nom du mac (hostname) : pour moi c'était "mac-13"
Changed:
< <
Version 1.7.3
> >
pomme, préférences systèmes, partage : changer le nom, puis fermer
(if the domain is not specified the hostname will be automatically configured as .local)
Deleted:
< <
1) Download
Deleted:
< <
2) Install (environ 300Mo)
Changed:
< <
XAMPP est installé dans le répertoire/Applications/XAMPP
> >
Créer un script de démarrage bash
Changed:
< <
3) Démarrer
> >
vi .bash_login :
source .bash_rc
Changed:
< <
sudo /Applications/XAMPP/xamppfiles/xampp start
> >
vi .bash_rc :
alias l="ls -l"
Deleted:
< <
Sur l'écran devrait apparaitre les instructions suivantes:
Changed:
< <
Démarre XAMPP pour MacOS X 1.7.3...
XAMPP: Démarre Apache avec SSL...
XAMPP: Démarre MySQL...
XAMPP: Démarre ProFTPD...
XAMPP démarré.
> >
Installer sprinter
Changed:
< <
Moi j'ai plutôt un pb avec proftpd, sans doute incompatible avec mac :
> >
Pref Sys / Imprimantes
Changed:
< <
File permissions are being checked...ok.
Starting XAMPP for Mac OS X 1.7.3...
XAMPP: Starting Apache...ok.
XAMPP: Starting MySQL...ok.
XAMPP: Starting ProFTPD...XAMPP/XAMPP/xamppfiles/xampp: line 184: /Applications/XAMPP/xamppfiles//var/proftpd/start.err: No such file or directory
fail.
Contents of "/Applications/XAMPP/xamppfiles//var/proftpd/start.err":
cat: /Applications/XAMPP/xamppfiles//var/proftpd/start.err: No such file or directory
elle est trouvée en tant que "hp laserjet 2300 series"
Deleted:
< <
et ça marche !
Deleted:
< <
Si plus tard on remplace la page d'accueil de XAMPP par la sienne, on peut toujours joindre la page d'accueil de XAMPP avec http://localhost/xampp/
Changed:
< <
5) Aspects sécurité
> >
Partitionnement du disque :
Changed:
< <
Comme cela a déjà été expliqué antérieurement XAMPP n'est pas fait pour l'emploi de production, mais seulement pour développeur et l'environnement du développement. Cela a pour suite que XAMPP est volontairement préconfiguré pour ne pas être restrictif et être au contraire trés ouvert. Pour un développeur cela est idéal qu'il ne soit pas limité par les limites du systéme. Par contre pour un emploi en production cela est absolument pas recommendable.
Ici, une liste de choses donc XAMPP est volontairement(!) insécurisé:
> >
Applications / Utilitaires / Utilitaire de disque
Changed:
< <
1. L'administrateur (root)MySQL n'a pas de mot de passe.
2. Le démon MySQL est joignable par le réseau.
3. Le démon ProFTPD utilise le mot de passe "xampp".
4. PhpMyAdmin est joignable par le réseau.
5. MySQL et Apache fonctionne sous le même utilisateur (nobody)
> >
onglet "Partition"
Changed:
< <
Dans la page XAMPP-Demo (que l'on trouve sous http://localhost) il y a le point "Security check". À cet endroit on peut faire apparaître le niveau de sécurité actuel de XAMPP.
> >
Diminuer la partition unique "Macintosh HD" de 500 à 100Go
Changed:
< <
Si on veut utiliser XAMPP en réseau , pour que le serveur XAMPP soit accessible par d'autres utilisateurs, alors il faut impérativement exécuter les commandes suivantes avec lesquelles ont pourra alors limiter les failles de sécurité:
> >
Bouton "+" pour ajouter une nouvelle partition de 400Go
Pour montrer les éléments cachés il faut taper la commande "defaults write com.apple.finder AppleShowAllFiles 1".
Pour cacher à nouveau les fichiers et dossiers spéciaux il faut taper la commande "defaults write com.apple.finder AppleShowAllFiles 0".
L'utilitaire TinkerTool de Marcel Bresink permet de régler ces préférences d'une manière plus conviviale.
Added:
> >
Déplacement clavier :
Added:
> >
home : cmd left
end : cmd right
mot : alt left/right
Effacer le mot suivant Ctrl+Suppr
Deleted:
< <
7) FICHIERS ET RÉPERTOIRES IMPORTANTS
Changed:
< <
/Applications/XAMPP/xamppfiles/bin
> >
Navigation :
Changed:
< <
Ici les commandes pour XAMPP.
> >
entre applis : Cmd Tab
entre onglets d'une mm appli : ctrl tab
entre fenêtres d'une mm appui : (alt tab ???)
cmd * (sur clavier mac, c'est cmd `, sous le £), à droite de la lettre "m"
Deleted:
< <
(il suffit de placer /Applications/XAMPP/xamppfiles/bin dans mon $PATH pour que j'ai accès à toutes les commandes de xampp directement, telles que "mysql")
Deleted:
< <
/Applications/XAMPP/xamppfiles/bin/mysql appelle par ex .MySQL.
Deleted:
< <
/Applications/XAMPP/htdocs/
Deleted:
< <
Le répertoire Root du serveur web Apache. Ici sont les pages web d'Apache.
Changed:
< <
/Applications/XAMPP/etc/httpd.conf
> >
Transition depuis le monde Linux
Changed:
< <
Le fichier central de configuration du serveur web Apache.
> >
packages = .dmg
Changed:
< <
/Applications/XAMPP/etc/my.cnf
> >
Gestion des Services
Changed:
< <
Le fichier de configuration pour le serveur MySQL-Base de données.
> >
Pas de /etc/init.d/
Changed:
< <
/Applications/XAMPP/etc/php.ini
> >
A la place :
Changed:
< <
Le fichier de configuration de PHP.
> >
/System/Library/StartupItems et /Library/StartupItems
Changed:
< <
/Applications/XAMPP/etc/proftpd.conf
> >
Apple provides a program called SystemStarter which is used to start and stop scripts in the /System -> Library -> StartupItems and /Library -> StartupItems folders. You can use it to restart services like so:
% sudo SystemStarter restart NetInfo
Or if you've just installed GimpPrint and need to restart CUPS for it to find your printer:
% sudo SystemStarter restart PrintingServices
The one caveat is that all the start, stop, and restart options do is pass this argument to the various scripts. If the script doesn't respond to that argument, nothing happens. An example is AppServices, which controls coreservicesd. Sending stop or restart to this script has no effect.
Switch to the command line, e.g. under Windows Start-> Run -> cmd. Switch to any directory you want. Type:
Changed:
< <
Téléchargez et installez MySQL 5 et ses dépendances :
> >
java HelloWorld
Changed:
< <
sudo port install mysql5
> >
If you are not in the directory in which the compiled class is stored then the system should result an error message Exception in thread "main" java.lang.NoClassDefFoundError: test/TestClass
To use the class type the following command. Replace "mydirectory" with the directory which contains the test directory. You should again see the "HelloWorld" output.
Changed:
< <
sudo port install mysql5-server
> >
java -classpath "mydirectory" HelloWorld
Changed:
< <
Une fois l’installation terminée, vous pouvez activer le lancement automatique de MySQL au démarrage de l’ordinateur :
> >
Create an executable JAR
Changed:
< <
sudo port load mysql5-server
> >
A JAR file is a Java Archive based on the pkzip file format. A jar files can contain java classes and other resources (icons, property files) and can be executable.
JAR files are the deployment format for Java. You can distribute your program in a jar file or you can use exiting java code via jars by putting them into your classpath.
Changed:
< <
sudo -u _mysql mysql_install_db5
> >
An executable JAR means the end-user doesn't have to pull the class files out before running the program. This is done via a manifest.txt file which tells the JVM which class has the main() method. The content of the manifest.txt file:
Changed:
< <
Une fois l’installation terminée, vous pouvez lancer MySQL au démarrage de l’ordinateur :
Étape optionnelle : Activer l’extension UserDir pour Apache. Cette extension permet d’avoir des urls dédiées pour chaque utilisateur de l’ordinateur du type http://localhost/~utilisateur/
Éditez le fichier /opt/local/apache2/conf/httpd.conf
Recherchez et décommentez la ligne ci-dessous :
Étape optionnelle : Autoriser l’ajout/suppression d’options via un .htaccess (exemple Options +FollowSymLinks)
Éditez le fichier /opt/local/apache2/conf/extra/httpd-userdir.conf
Recherchez la ligne ci-dessous :
Configurer MySQL pour PHP
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez les paramètres pdo_mysql.default_socket, mysql.default_socket, mysqli.default_socketet mettez comme valeur ceci :
Deleted:
< <
/opt/local/var/run/mysql5/mysqld.sock
Changed:
< <
Configurer le fuseau horaire par défaut
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez la ligne suivante :
When you need to test something, here is what you do:
Annotate a method with @org.junit.Test
When you want to check a value, import org.junit.Assert.* statically, call assertTrue() and pass a boolean that is true if the test succeeds
(Use a method provides by JUnit to check the expected result of the code execution versus the actual result)
Changed:
< <
(le Apache d'origine de Mac est démarré via les préférences systèmes, partage, web : on voit alors les processus avec "ps -efl | grep http")
> >
For example, to test that the sum of two Moneys with the same currency contains a value which is the sum of the values of the two Moneys, write:
@Test
public void simpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
assertTrue(expected.equals(result));
}
Added:
> >
Fixture :
Added:
> >
What if you have two or more tests that operate on the same or similar sets of objects?
Added:
> >
Tests need to run against the background of a known set of objects. This set of objects is called a test fixture. When you are writing tests you will often find that you spend more time writing the code to set up the fixture than you do in actually testing values.
Added:
> >
To some extent, you can make writing the fixture code easier by paying careful attention to the constructors you write. However, a much bigger savings comes from sharing fixture code. Often, you will be able to use the same fixture for several different tests. Each case will send slightly different messages or parameters to the fixture and will check for different results.
Added:
> >
When you have a common fixture, here is what you do:
Changed:
< <
Installation AMP (Apache Mysql Php) en utilisant les packages Mac OS pré-existant
> >
Add a field for each part of the fixture
Annotate a method with @org.junit.Before and initialize the variables in that method
Annotate a method with @org.junit.After to release any permanent resources you allocated in setUp
Changed:
< <
apache déjà installé, mais pas activé
> >
For example, to write several test cases that want to work with different combinations of 12 Swiss Francs, 14 Swiss Francs, and 28 US Dollars, first create a fixture:
Changed:
< <
php déjà installé mais pas activé
> >
public class MoneyTest {
private Money f12CHF;
private Money f14CHF;
private Money f28USD;
Changed:
< <
mysql à installer
> >
@Before public void setUp() {
f12CHF= new Money(12, "CHF");
f14CHF= new Money(14, "CHF");
f28USD= new Money(28, "USD");
}
}
Changed:
< <
Apache
> >
Once you have the Fixture in place, you can write as many Test Cases as you'd like. Add as many test methods (annotated with @Test) as you'd like.
Deleted:
< <
Pour activer le serveur, allez dans Préférences système -> Partage et cochez la case Partage Web. Si elle est déjà cochée, décochez-la pour arrêter le serveur et recochez-là pour que la modification du fichier httpd.conf soit prise en compte.
Changed:
< <
v2.2.20
> >
You use a tool like Eclipse or the class "org.junit.runner.JUnitCore" to run the test.
We want to create the unit tests in a separate folder. Create therefore a new source folder "test" via right mouse click on your project, select properties and choose the "Java Build Path". Select the tab source code.
Press "Add folder" then then press "Create new folder". Create the folder "test".
The creation of an separate folder for the test is not mandatory. But it is good advice to keep the test coding separate from the normal coding.
Changed:
< <
Php : /usr/lib/
> >
Create a Java class
Changed:
< <
Pour activer PHP il faut décommenter la ligne #LoadModule php5_module libexec/apache2/libphp5.so du fichier httpd.conf situé dans le dossier apache2 du dossier etc.
> >
Create a package "de.vogella.junit.first" and the following class.
Changed:
< <
Ensuite réactiver le serveur apache (voir ci-dessus)
> >
package de.vogella.junit.first;
public class MyClass {
public int multiply(int x, int y) { return x / y; }
}
Deleted:
< <
Ajouter test.php dans le rep doc de apache qui contient :
Select your new class, right mouse click and select New ->JUnit Test case, change the source folder to JUnit. Select "New JUnit 4 test". Make sure you change the source folder to test.
The test should be failing (indicated via a red bar). This is due to the fact that our multiplier class is currently not working correctly (it does a division instead of multiplication). Fix the bug and re-run test to get a green light.
Added:
> >
If you have several tests you can combine them into a test suite. All test in this test suite will then be executed if you run the test suite. To create a new test suite, select your test classes, right mouse click-> New-> Other -> JUnit -Test Suite
Changed:
< <
Créer un mot de passe pour root
> >
Select next and select the methods you would like to have test created for.
Changed:
< <
Par défaut, root n'a pas de mot de passe, il faut donc en définir un :
If you later develop another test you can add it to @Suite.SuiteClasses
Deleted:
< <
sudo -s
Added:
> >
6) Run your test via code
Added:
> >
You can also run your test via your own coding. The class "org.junit.runner.JUnitCore" provides the method runClasses() which allows you to run one or several tests classes. As a return parameter you receive an object of type "org.junit.runner.Result". This object can be used to retrieve information about the tests and provides information about the failed tests.
Changed:
< <
changer définitivement le nom du mac (hostname) : pour moi c'était "mac-13"
> >
Create in your "test" folder a new class "MyTestRunner" with the following coding. This class will execute your test class and write potential failures to the console.
Changed:
< <
pomme, préférences systèmes, partage : changer le nom, puis fermer
> >
package de.vogella.junit.first;
Changed:
< <
(sudo hostname newname ne change que temporairement)
public class MyTestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MyClassTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
}
}
Deleted:
< <
(if the domain is not specified the hostname will be automatically configured as .local)
Added:
> >
7) Annotations and Assert statements
Added:
> >
a) Annotations
Changed:
< <
Créer un script de démarrage bash
> >
The following give an overview of the available annotations in JUnit 4.x
Changed:
< <
vi .bash_login :
source .bash_rc
> >
Annotation Description
@Test public void method() Annotation @Test identifies that this method is a test method.
@Before public void method() Will perform the method() before each test. This method can prepare the test environment (called a "fixture"), e.g. read input data, initialize the class)
@After public void method() Test method must start with test
@BeforeClass public void method() Will perform the method before the start of all tests. This can be used to perform time intensive activities for example be used to connect to a database
@AfterClass public void method() Will perform the method after all tests have finished. This can be used to perform clean-up activities for example be used to disconnect to a database
@Ignore Will ignore the test method, e.g. useful if the underlying code has been changed and the test has not yet been adapted or if the runtime of this test is just to long to be included.
@Test(expected=IllegalArgumentException.class) Tests if the method throws the named exception
@Test(timeout=100) Fails if the method takes longer then 100 milliseconds
Deleted:
< <
vi .bash_rc :
alias l="ls -l"
Added:
> >
b) Assert statements
Changed:
< <
Installer sprinter
> >
The following gives an overview of the available test methods:
Changed:
< <
Pref Sys / Imprimantes
> >
Statement Description
fail(String) Let the method fail, might be usable to check that a certain part of the code is not reached.
assertTrue(true); True
assertsEquals([String message], expected, actual) Test if the values are the same. Note: for arrays the reference is checked not the content of the arrays
assertsEquals([String message], expected, actual, tolerance) Usage for float and double; the tolerance are the number of decimals which must be the same
assertNull([message], object) Checks if the object is null
assertNotNull([message], object) Check if the object is not null
assertSame([String], expected, actual) Check if both variables refer to the same object
assertNotSame([String], expected, actual) Check that both variables refer not to the same object
assertTrue([message], boolean condition) Check if the boolean condition is true.
Vous êtes vivement encouragés à contribuer au contenu de ce site.
Changed:
< <
Pour montrer les éléments cachés il faut taper la commande "defaults write com.apple.finder AppleShowAllFiles 1".
Pour cacher à nouveau les fichiers et dossiers spéciaux il faut taper la commande "defaults write com.apple.finder AppleShowAllFiles 0".
L'utilitaire TinkerTool de Marcel Bresink permet de régler ces préférences d'une manière plus conviviale.
> >
Pour modifier n'importe quelle page du site :
cliquez sur bouton "Edit", faites vos modifs, puis cliquez sur le bouton "Save".
si vous êtes plus à l'aise avec la souris, cliquez plutot sur le bouton "WYSIWYG"
Deleted:
< <
Déplacement clavier :
Changed:
< <
home : cmd left
end : cmd right
mot : alt left/right
Effacer le mot suivant Ctrl+Suppr
> >
Faire une copie (de sauvegarde) d'un Web (pour consultation offline) :
Grace au plugin PublishContrib, on peut obtenir une copie du Web à tout instant (attention, cette copie est READ ONLY, ce n'est plus un wiki, mais juste des pages web).
Pour publier la version courante du Web, aller sur le topic PublishWeb, et cliquer sur le bouton "Publish" (en milieu de page). Par défaut, c'est l'option "zip" qui est sélectionnée, ce qui crée un zip du Web.
Il suffit maintenant de cliquer en bas de la page générée par la requete, sur le lien "Published To: NomduWeb.zip", pour télécharger ce zip (L'accès à cette adresse est protégé pour que seuls les personnes enregistrées puissent y acceder)
Dézipper et cliquer sur la page WebHome.html. Le résultat n'est pas très joli, mais le contenu y est...
Un historique de la dernière publication se trouve dans le topic PublishContribHistory (utile pour voir si tout s'est bien passé)
Added:
> >
Mise à jour d'une pièce attachée (remarque) :
Changed:
< <
Navigation :
> >
Il vaut mieux utiliser des noms de fichier assez génériques (par exemple FDD.pdf au lieu de FF_v1.4.pdf) ainsi on peut mettre à jour un document sans changer son nom et les liens vers ce fichier
Changed:
< <
entre applis : Cmd Tab
entre onglets d'une mm appli : ctrl tab
entre fenêtres d'une mm appui : (alt tab ???)
cmd * (sur clavier mac, c'est cmd `, sous le £), à droite de la lettre "m"
/System/Library/StartupItems et /Library/StartupItems
> >
Niveau Administrateur
Changed:
< <
Apple provides a program called SystemStarter which is used to start and stop scripts in the /System -> Library -> StartupItems and /Library -> StartupItems folders. You can use it to restart services like so:
% sudo SystemStarter restart NetInfo
Or if you've just installed GimpPrint and need to restart CUPS for it to find your printer:
% sudo SystemStarter restart PrintingServices
The one caveat is that all the start, stop, and restart options do is pass this argument to the various scripts. If the script doesn't respond to that argument, nothing happens. An example is AppServices, which controls coreservicesd. Sending stop or restart to this script has no effect.
Type man SystemStarter and browse through the various scripts to learn more about the program and the scripts.
Deleted:
< <
Astuces, raccourcis clavier
Deleted:
< <
RACCOURCIS
Changed:
< <
caractère DIESE : maj alt * (touche à droite du "m")
> >
IDL
Changed:
< <
Refaire (Ctrl+Maj+Z) Cmd+Maj+Z
Ouvrir un menu contextuel (Maj+F10) Ctrl+Espace
> >
Utiliser mon IDL au labo ou bien à l'extérieur du labo (en une seule config)
Changed:
< <
(Windows-E) Cmd-Maj-C Ouvre la fenêtre Computer sous Windows. / Va sur la vue Computer dans le Finder sous Mac OS X
> >
Problème : Comment exécuter mon idl (celui qui est installé localement sur mon pc/mac) au labo et même à l'extérieur du labo ???
Changed:
< <
(Ctrl-Maj-Echap) Cmd-Option-Esc Ouvre une fenêtre permettant de forcer l'arrêt d'une application
> >
Réponse : en profitant des licences du serveur hyperion
Changed:
< <
Quitter un programme +
> >
En ce qui vous concerne, allez directement au point 2)
Changed:
< <
Afficher les propriétés
<Command> + <I>
> >
1) Travail à faire pour l'administrateur système sur hyperion
Changed:
< <
Forcer à quitter : Command + Option + Escape
> >
Modifier le fichier de licences /usr/local/itt/license/license.dat, remplacer la ligne : "DAEMON idl_lmgrd" par "DAEMON idl_lmgrd port=1701"
Changed:
< <
Capture d'écran : Command + Shift + 3
> >
(cela force flexlm à utiliser le port 1701 pour idl_lmgrd)
Changed:
< <
Bureau : F11
> >
Relancer les service lmgrd et idl_lmgrd
Changed:
< <
Voir l'ensemble des appris en réduction : F9 et F10
> >
Si tout s'est bien passé, la commande "nmap hyperion.cesr.fr -p1700-1701" permet de voir que le port 1701 est bien ouvert
Changed:
< <
Masquer finder : cmd H
> >
$ nmap hyperion.cesr.fr -p1700-1701
Changed:
< <
Masquer les autres : cmd alt H
> >
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2012-10-08 18:10 CEST
Interesting ports on hyperion.cesr.fr (195.83.102.174):
PORT STATE SERVICE
1700/tcp open unknown
1701/tcp open unknown
Changed:
< <
Créer un alias : Pom-alt + déplacer une icone sur bureau
> >
Nmap finished: 1 IP address (1 host up) scanned in 0.119 seconds
Deleted:
< <
Créer un alias/raccourci : Command + L
Added:
> >
2) Pour vous (côté client), Il suffit de faire 2 choses sur votre pc/mac
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
Changed:
< <
Start a Java program
> >
(Pour les utilisateurs de Windows, faire un clic droit sur Poste de Travail, puis onglet "Variables d'environnement", puis entrer la variable nommée LM_LICENSE_FILE avec la valeur "1700@hyperion.cesr.fr:9700@localhost")
(Le mieux est de placer cette ligne une fois pour toutes dans votre fichier de démarrage ~/.bash_profile, pour ne plus avoir à la taper)
Changed:
< <
Open a command shell, e.g. under Microsoft Windows select Start -> Run and type in cmd. This should open a consle.
> >
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Changed:
< <
Switch to your output directory, e.g. by typing cd path, e.g. if you jar is located in "c:\temp" type "cd c:\temp".
> >
Si vous êtes à l'extérieur du labo, continuez la lecture...
Deleted:
< <
To run this program you need to include the jar file into your classpath.
Ouvrir un tunnel avec mise en correspondance de 2 ports :
Changed:
< <
If you are not in the directory in which the compiled class is stored then the system should result an error message Exception in thread "main" java.lang.NoClassDefFoundError: test/TestClass
To use the class type the following command. Replace "mydirectory" with the directory which contains the test directory. You should again see the "HelloWorld" output.
> >
(remplacer MON_LOGIN_EMAIL par votre login utilisé pour le mail ou pour vous connecter à la passerelle du labo, et GATEWAY par le serveur passerelle du labo)
Changed:
< <
java -classpath "mydirectory" HelloWorld
> >
(Remarque pour l'admin système : attention, sur le localhost on a le choix de la correspondance du port 1700 d'hyperion (port 9700 local) mais pas pour le 1701)
Changed:
< <
Create an executable JAR
> >
Entrer le mot de passe pour GATEWAY (pour vous connecter de votre pc à GATEWAY)
Changed:
< <
A JAR file is a Java Archive based on the pkzip file format. A jar files can contain java classes and other resources (icons, property files) and can be executable.
> >
Voilà, vous avez créé un tunnel entre votre pc/mac et hyperion, passant par GATEWAY (vous êtes d'ailleurs connecté à la passerelle).
Changed:
< <
JAR files are the deployment format for Java. You can distribute your program in a jar file or you can use exiting java code via jars by putting them into your classpath.
> >
Il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Changed:
< <
An executable JAR means the end-user doesn't have to pull the class files out before running the program. This is done via a manifest.txt file which tells the JVM which class has the main() method. The content of the manifest.txt file:
> >
Attention, une fois la session idl terminée, ne pas oublier de détruire le tunnel en vous déconnectant d'hyperion !!! (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/pallier/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/pallier/.ssh/id_dsa.
Your public key has been saved in /Users/pallier/.ssh/id_dsa.pub.
La clé publique, doit être copiée sur le serveur distant dans ~/.ssh/authorized_keys. (La clé privée reste sur votre poste client)
Changed:
< <
CA NE MARCHE PAS !!!
> >
Aller dans votre HOME
Changed:
< <
DONC, INSTALLATION MANUELLE (ci-dessous)
> >
ssh-copy-id -i .ssh/id_dsa.pub GATEWAY
(
ou bien, si on ne dispose pas de la commande ssh-copy-id, l'exemple est ici donné pour moi :
$ cat .ssh/id_dsa.pub | ssh epallier@GATEWAY "cat - >>.ssh/authorized_keys"
)
When you need to test something, here is what you do:
Annotate a method with @org.junit.Test
When you want to check a value, import org.junit.Assert.* statically, call assertTrue() and pass a boolean that is true if the test succeeds
(Use a method provides by JUnit to check the expected result of the code execution versus the actual result)
Changed:
< <
For example, to test that the sum of two Moneys with the same currency contains a value which is the sum of the values of the two Moneys, write:
@Test
public void simpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
assertTrue(expected.equals(result));
}
> >
IDL 8.1 workbench (idlde) crash sous Mac OS 10.7
Changed:
< <
Fixture :
> >
Voici ce qu'il faut faire pour corriger le pb :
Changed:
< <
What if you have two or more tests that operate on the same or similar sets of objects?
> >
cd /Applications/itt/idl/idl81/bin/bin.darwin.x86_64/
Changed:
< <
Tests need to run against the background of a known set of objects. This set of objects is called a test fixture. When you are writing tests you will often find that you spend more time writing the code to set up the fixture than you do in actually testing values.
> >
mv libcurl.4.0.1.dylib libcurl.4.0.1.dylib.bak
Changed:
< <
To some extent, you can make writing the fixture code easier by paying careful attention to the constructors you write. However, a much bigger savings comes from sharing fixture code. Often, you will be able to use the same fixture for several different tests. Each case will send slightly different messages or parameters to the fixture and will check for different results.
> >
mv libcurl.4.dylib libcurl.4.dylib.bak
Changed:
< <
When you have a common fixture, here is what you do:
> >
mv libcurl.dylib libcurl.dylib.bak
Changed:
< <
Add a field for each part of the fixture
Annotate a method with @org.junit.Before and initialize the variables in that method
Annotate a method with @org.junit.After to release any permanent resources you allocated in setUp
> >
Lire l'article complet sur le pb :
Changed:
< <
For example, to write several test cases that want to work with different combinations of 12 Swiss Francs, 14 Swiss Francs, and 28 US Dollars, first create a fixture:
How to set IDL to use "software rendering" (IDL 8 issue) ?
Changed:
< <
3) Créer un projet Java
> >
From IDLDE
Changed:
< <
Create a new project "de.vogella.junit.first".
> >
Fenêtre/Préférences/IDL/Graphiques :
Changed:
< <
We want to create the unit tests in a separate folder. Create therefore a new source folder "test" via right mouse click on your project, select properties and choose the "Java Build Path". Select the tab source code.
Press "Add folder" then then press "Create new folder". Create the folder "test".
The creation of an separate folder for the test is not mandatory. But it is good advice to keep the test coding separate from the normal coding.
> >
Méthode de rendu pour les objets graphiques : sélectionner "Logiciel" au lieu de "Matériel"
Changed:
< <
Create a Java class
> >
From the idl console
Changed:
< <
Create a package "de.vogella.junit.first" and the following class.
> >
There are a couple of ways to set IDL to use software rendering, besides from the IDLDE.
Changed:
< <
package de.vogella.junit.first;
public class MyClass {
public int multiply(int x, int y) { return x / y; }
}
> >
If you want to set the entire IDL session to use software rendering, then when you start up IDL, you could use this command:
Added:
> >
idl -IDL_GR_WIN_RENDERER 1 (for Windows)
or
idl -IDL_GR_X_RENDERER 1 (for X Windows)
Changed:
< <
4) Create a JUnit test
> >
If you want to switch from the default hardware rendering to software rendering in the middle of an IDL session, you could use this command:
Changed:
< <
Select your new class, right mouse click and select New ->JUnit Test case, change the source folder to JUnit. Select "New JUnit 4 test". Make sure you change the source folder to test.
> >
PREF_SET, 'IDL_GR_WIN_RENDERER', '1', /COMMIT (for Windows)
or
PREF_SET, 'IDL_GR_X_RENDERER', '1', /COMMIT (for X Windows)
Deleted:
< <
Press next and select the methods which you want to test.
Changed:
< <
If you have not yet JUnit in your classpath, Eclipse will asked you if it should be added to the classpath.
> >
Conseils pour bien documenter son code
Changed:
< <
Create a test with the following code.
> >
Voir conseils généraux (Michael Galloy) "A style guide" : styleguide.pdf
Changed:
< <
> >
Je livre ici une synthèse des conseils de Michael Galloy pour bien documenter un code IDL (Lire "A style guide" pour la version complète avec justifications) :
public class MyClassTest {
@Test public void testMultiply() {
MyClass tester = new MyClass();
assertEquals("Result", 50, tester.multiply(10, 5));
}
}
> >
1. Code is for humans.
Changed:
< <
> >
2. Do not mix styles.
Added:
> >
3. Avoid redundancy.
Changed:
< <
5) Run your test via Eclipse
> >
4. Use an easy to maintain style.
Changed:
< <
Right click on your new test class and select Run-As-> Junit Test.
> >
2. Layout
Changed:
< <
The test should be failing (indicated via a red bar). This is due to the fact that our multiplier class is currently not working correctly (it does a division instead of multiplication). Fix the bug and re-run test to get a green light.
> >
1. Layout should enhance the logical structure of the code.
Changed:
< <
If you have several tests you can combine them into a test suite. All test in this test suite will then be executed if you run the test suite. To create a new test suite, select your test classes, right mouse click-> New-> Other -> JUnit -Test Suite
> >
2. Use two spaces (not tabs) per indentation level.
Changed:
< <
Select next and select the methods you would like to have test created for.
; get random nIndices by finding the indices of the smallest
; nIndices in an array of random values
values = randomu(seed, nValues)
Changed:
< <
}
> >
; our random values are uniformly distributed, so ideally
; the nIndices smallest values are in the first bin of the
; below histogram
nBins = nValues / nIndices
h = histogram(values, nbins=nBins, reverse_indices=ri)
Changed:
< <
> >
; the candidates for being in the first nIndices will live in
; bins 0..bin
nCandidates = 0L
for bin = 0L, nBins - 1L do begin
nCandidates += h[bin]
if (nCandidates ge nIndices) then break
endfor
Changed:
< <
If you later develop another test you can add it to @Suite.SuiteClasses
> >
; get the candidates and sort them
candidates = ri[ri[0] : ri[bin + 1L] - 1L]
sortedCandidates = sort(values[candidates])
Added:
> >
; return the first nIndices of them
return, (candidates[sortedCandidates])[0:nIndices-1L]
end
Changed:
< <
6) Run your test via code
> >
5. Insert two blank lines between routines.
Changed:
< <
You can also run your test via your own coding. The class "org.junit.runner.JUnitCore" provides the method runClasses() which allows you to run one or several tests classes. As a return parameter you receive an object of type "org.junit.runner.Result". This object can be used to retrieve information about the tests and provides information about the failed tests.
> >
One blank line separates "paragraphs"; two blank lines separate "sections."
Deleted:
< <
Create in your "test" folder a new class "MyTestRunner" with the following coding. This class will execute your test class and write potential failures to the console.
public class MyTestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MyClassTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
}
}
> >
2. Keep comments up to date with the code.
Added:
> >
3. For a short comment, use a phrase with lowercase first letter and no period. For longer comments, use all
normal grammar rules.
Changed:
< <
7) Annotations and Assert statements
> >
5. Write a complete header for each routine.
Changed:
< <
a) Annotations
> >
Use comments between ;+ and ;- before the routine. Document the purpose of the routine, the return value (if
a function), and side effects of the routine (which you should strive to eliminate). Each parameter should be
documented with whether it is an input and/or output, optional or required, data type expected, default value (if
any) and a description of its purpose.
Changed:
< <
The following give an overview of the available annotations in JUnit 4.x
> >
For example, the below is an IDLdoc formatted header for the routine listed above:
Changed:
< <
Annotation Description
@Test public void method() Annotation @Test identifies that this method is a test method.
@Before public void method() Will perform the method() before each test. This method can prepare the test environment (called a "fixture"), e.g. read input data, initialize the class)
@After public void method() Test method must start with test
@BeforeClass public void method() Will perform the method before the start of all tests. This can be used to perform time intensive activities for example be used to connect to a database
@AfterClass public void method() Will perform the method after all tests have finished. This can be used to perform clean-up activities for example be used to disconnect to a database
@Ignore Will ignore the test method, e.g. useful if the underlying code has been changed and the test has not yet been adapted or if the runtime of this test is just to long to be included.
@Test(expected=IllegalArgumentException.class) Tests if the method throws the named exception
@Test(timeout=100) Fails if the method takes longer then 100 milliseconds
> >
;+
; Get nIndices random indices for an array of size nValues (do
; not repeat an index).
;
; :Returns: lonarr(nIndices)
;
; :Params:
; nValues : in, required, type=long
; size of array to choose indices from
; nIndices : in, required, type=long
; number of indices needed
;
; :Keywords:
; seed : in, out, optional, type=long or lonarr(36)
; seed to use for random number generation, a new seed
; will be output
;-
function mg_sample, nValues, nIndices, seed=seed
Added:
> >
6. Indent a comment along with the code it's documenting.
Changed:
< <
b) Assert statements
The following gives an overview of the available test methods:
> >
7. Document paragraph by paragraph.
Changed:
< <
Statement Description
fail(String) Let the method fail, might be usable to check that a certain part of the code is not reached.
assertTrue(true); True
assertsEquals([String message], expected, actual) Test if the values are the same. Note: for arrays the reference is checked not the content of the arrays
assertsEquals([String message], expected, actual, tolerance) Usage for float and double; the tolerance are the number of decimals which must be the same
assertNull([message], object) Checks if the object is null
assertNotNull([message], object) Check if the object is not null
assertSame([String], expected, actual) Check if both variables refer to the same object
assertNotSame([String], expected, actual) Check that both variables refer not to the same object
assertTrue([message], boolean condition) Check if the boolean condition is true.
> >
Each paragraph of code may need a comment to document its purpose, but inside a paragraph use only end-of-line
comments to comment particular lines.
It can be helpful to write the comments first, providing an outline of the code to write.
for i = 0, 10 do begin
print, i, format='("The index is ", I0, ".")'
end
Changed:
< <
Commentaire
> >
But never write:
Changed:
< <
Html comment =
<-- comment -->
Twiki comment = # comment
> >
for i = 0, 10 do $
print, i, format='("The index is ", I0, ".")'
Changed:
< <
Voir ce qui change sur le site
Pour savoir ce qui a changé (en ordre chronologique) sur le web Team, consulter cette page : WebChanges
Changements survenus sur le web "twiki" : WebChanges
on peut aussi s'inscrire sur cette page pour recevoir les changements du web Team par email : WebNotify
Contribuer (enrichir le site)
Vous êtes vivement encouragés à contribuer au contenu de ce site.
Pour modifier n'importe quelle page du site :
cliquez sur bouton "Edit", faites vos modifs, puis cliquez sur le bouton "Save".
si vous êtes plus à l'aise avec la souris, cliquez plutot sur le bouton "WYSIWYG"
> >
4.5. Define structures one field per line unless the entire definition can fit on one line.
Added:
> >
For example, use:
point = { x: 0.0, y:0.0 }
state = { x: 0.0, $
y: 0.0, $
pdata: ptr_new(), $ ; image data
drawId: 0L $ ; window identifier
}
Changed:
< <
Faire une copie (de sauvegarde) d'un Web (pour consultation offline) :
Grace au plugin PublishContrib, on peut obtenir une copie du Web à tout instant (attention, cette copie est READ ONLY, ce n'est plus un wiki, mais juste des pages web).
Pour publier la version courante du Web, aller sur le topic PublishWeb, et cliquer sur le bouton "Publish" (en milieu de page). Par défaut, c'est l'option "zip" qui est sélectionnée, ce qui crée un zip du Web.
Il suffit maintenant de cliquer en bas de la page générée par la requete, sur le lien "Published To: NomduWeb.zip", pour télécharger ce zip (L'accès à cette adresse est protégé pour que seuls les personnes enregistrées puissent y acceder)
Dézipper et cliquer sur la page WebHome.html. Le résultat n'est pas très joli, mais le contenu y est...
Un historique de la dernière publication se trouve dans le topic PublishContribHistory (utile pour voir si tout s'est bien passé)
> >
4.6. Add one space around most operators.
Changed:
< <
Mise à jour d'une pièce attachée (remarque) :
> >
ex:
Changed:
< <
Il vaut mieux utiliser des noms de fichier assez génériques (par exemple FDD.pdf au lieu de FF_v1.4.pdf) ainsi on peut mettre à jour un document sans changer son nom et les liens vers ce fichier
in each routine to prevent issues with IDL confusing arrays and functions calls.
Added:
> >
5. Variables
Added:
> >
1. Use good variable names.
Changed:
< <
IDL
> >
2. Variable names should be in camel case.
Changed:
< <
Utiliser mon IDL au labo ou bien à l'extérieur du labo (en une seule config)
> >
Camel case uppercases the first letter of each word in the name except for the first letter.
Changed:
< <
Problème : Comment exécuter mon idl (celui qui est installé localement sur mon pc/mac) au labo et même à l'extérieur du labo ???
> >
Uppercase each letter in an abbreviation that appears in a variable name unless it starts the name:
Changed:
< <
Réponse : en profitant des licences du serveur hyperion
> >
noaaWeatherURL.
Changed:
< <
En ce qui vous concerne, allez directement au point 2)
> >
Prefix the name with "n" for variables that hold counts, "o" for object references, "p" for pointers, "id" for
iTools identifiers.
Changed:
< <
1) Travail à faire pour l'administrateur système sur hyperion
> >
Examples that follow this convention,
nFiles
oModel
pState
idPlot
Changed:
< <
Modifier le fichier de licences /usr/local/itt/license/license.dat, remplacer la ligne : "DAEMON idl_lmgrd" par "DAEMON idl_lmgrd port=1701"
> >
3. Prefer pointers, objects, and passing local variables over common blocks or system variables.
Changed:
< <
(cela force flexlm à utiliser le port 1701 pour idl_lmgrd)
> >
Occasionally there is a reason to use common blocks or system variables, but you should have a good argument
for it.
Changed:
< <
Relancer les service lmgrd et idl_lmgrd
> >
When using direct graphics, prefer using graphics keywords of the plotting routines over setting system
variables directly.
Changed:
< <
Si tout s'est bien passé, la commande "nmap hyperion.cesr.fr -p1700-1701" permet de voir que le port 1701 est bien ouvert
> >
4. Define common blocks and named structures in only one location.
Changed:
< <
$ nmap hyperion.cesr.fr -p1700-1701
> >
Define the variables in a common block only once in a batch file. Include that file where needed.
Changed:
< <
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2012-10-08 18:10 CEST
Interesting ports on hyperion.cesr.fr (195.83.102.174):
PORT STATE SERVICE
1700/tcp open unknown
1701/tcp open unknown
> >
map_proj_init_commonblock.pro is an example of this.
Changed:
< <
Nmap finished: 1 IP address (1 host up) scanned in 0.119 seconds
> >
Define a named structure using automatic structure definition. For example, define MG_Point in a routine
named MG_POINT__DEFINE in a file named mg_point__define.pro.
Changed:
< <
2) Pour vous (côté client), Il suffit de faire 2 choses sur votre pc/mac
> >
6. Routines
Changed:
< <
a) Positionner une variable d'environnement
> >
1. For any file containing IDL code, filenames should always be in lower case and use the ".pro" extension.
Changed:
< <
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
> >
2. Each file should include only one routine called from outside the file.
Changed:
< <
(Pour les utilisateurs de Windows, faire un clic droit sur Poste de Travail, puis onglet "Variables d'environnement", puis entrer la variable nommée LM_LICENSE_FILE avec la valeur "1700@hyperion.cesr.fr:9700@localhost")
> >
Each file should contain only one routine called from outside that file. Add the ".pro" extension to the routine
name of the externally called routine to get the filename. For example, the routine MG_LINEAR_FUNCTION
should be in a file named mg_linear_function.pro. If there are multiple routines in the file, make sure the
externally called routine is last in the file.
3. Routine names should be lower case, begin with a short organization prefix, and separate words with
underscores.
Changed:
< <
(Le mieux est de placer cette ligne une fois pour toutes dans votre fichier de démarrage ~/.bash_profile, pour ne plus avoir à la taper)
> >
The prefix indicates the individual or group responsible for the code. It is usually the initials of the individual or
orgranization. Limit to two or three letters. Don't use the "IDL", "RSI", "ITT", "cw", "it", or empty prefixes.
Changed:
< <
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
> >
4. Routines should fit on one screen.
Changed:
< <
Si vous êtes à l'extérieur du labo, continuez la lecture...
> >
5. Keywords should always be optional for the caller; positional parameters should generally be required.
Added:
> >
Keywords should either be an optional input with a reasonable default value or an extra output (i.e. not the
main purpose of the routine).
Changed:
< <
b) "Creuser" un tunnel
> >
6. Keyword names should be lowercase and separate words with underscores.
9. Status and error codes should be returned via keyword.
Deleted:
< <
(remplacer MON_LOGIN_EMAIL par votre login utilisé pour le mail ou pour vous connecter à la passerelle du labo, et GATEWAY par le serveur passerelle du labo)
Changed:
< <
(Remarque pour l'admin système : attention, sur le localhost on a le choix de la correspondance du port 1700 d'hyperion (port 9700 local) mais pas pour le 1701)
> >
7. Object-oriented programming
Changed:
< <
Entrer le mot de passe pour GATEWAY (pour vous connecter de votre pc à GATEWAY)
> >
1. Class names should begin with a prefix indicating organization and a code indicating the class' area of use.
Each word should be capitalized
Changed:
< <
Voilà, vous avez créé un tunnel entre votre pc/mac et hyperion, passant par GATEWAY (vous êtes d'ailleurs connecté à la passerelle).
> >
Use the same prefix as given to normal routine names; avoid "IDL", "ITT", "RSI", and the empty prefix.
Changed:
< <
Il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
> >
Codes already in use by IDL: an (analysis), com (COM), db (database), ex (example), ff (file format), gr
(graphics), it (iTools), sys (system), net (network), and _ (general use). Make use of the existing codes and
make up new ones as necessary.
Changed:
< <
Attention, une fois la session idl terminée, ne pas oublier de détruire le tunnel en vous déconnectant d'hyperion !!! (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
> >
Use all caps for abbreviations in class names, as in IDLnetURL.
Changed:
< <
Bon, on peut encore améliorer les choses... si ça vous dit, allez voir un peu plus loin, juste après la partie IN ENGLISH.
> >
2. Put all the methods and the routine defining the instance variables for a class into a single file.
Changed:
< <
Now, IN ENGLISH (and for Mac/Linux users only) :
> >
For the definition of MGexClass, the file should be named mgexclass__define.pro. The last routine in this file
should be MGEXCLASS__DEFINE and should define the instance variables for the class (i.e. create a named
structure with name MGexClass).
Changed:
< <
(First, be sure you have removed any remaining license.dat file from your itt/license/ directory ; just drop it, you don't need it)
> >
Define only one structure/class name in the __DEFINE routine.
Changed:
< <
1) set and export LM_LICENSE_FILE
> >
3. Method names should be a verb phrase in camel case.
Changed:
< <
Open a new terminal and set this variable :
> >
For example, here are some method names following these conventions:
Use the conventions that are used by the IDL library classes. For example, use the GETPROPERTY and
SETPROPERTY scheme of procedures to handle getting and setting properties of a class.
Changed:
< <
(you can also write this line once and for all in your ~/.bash_profile file, so that you won't have to do it every day)
> >
4. Begin "protected" methods' names with a underscore.
Changed:
< <
If you are INSIDE the lab, you are finished. Just launch your (local) idl : $ idlde (or idl) (or from the Applications launcher)
> >
For example,
Changed:
< <
If you are OUTSIDE the lab, you need one last step...
is a helper method called by other methods in MGexSomeClass, but should not be called from outside of
MGexSomeClass.
Changed:
< <
2) set a tunnel
> >
5. Beware of multiple inheritance.
Changed:
< <
Open a new terminal and create this tunnel :
> >
Use multiple inheritance as a last resort. Prefer delegation for one of the parent classes i.e. make the new class
contain the secondary parent class as an instance variable.
Only once finished with idl, don't forget to destroy the tunnel by closing the connexion to GATEWAY !!!
> >
8. Exemple de commentaires proposé par ITT dans examples/template.pro
Added:
> >
;+
; NAME:
; ROUTINE_NAME
;
; PURPOSE:
; Tell what your routine does here. I like to start with the words:
; "This function (or procedure) ..."
; Try to use the active, present tense.
;
; CATEGORY:
; Put a category (or categories) here. For example:
; Widgets.
;
; CALLING SEQUENCE:
; Write the calling sequence here. Include only positional parameters
; (i.e., NO KEYWORDS). For procedures, use the form:
;
; ROUTINE_NAME, Parameter1, Parameter2, Foobar
;
; Note that the routine name is ALL CAPS and arguments have Initial
; Caps. For functions, use the form:
;
; Result = FUNCTION_NAME(Parameter1, Parameter2, Foobar)
;
; Always use the "Result = " part to begin. This makes it super-obvious
; to the user that this routine is a function!
;
; INPUTS:
; Parm1: Describe the positional input parameters here. Note again
; that positional parameters are shown with Initial Caps.
;
; OPTIONAL INPUTS:
; Parm2: Describe optional inputs here. If you don't have any, just
; delete this section.
;
; KEYWORD PARAMETERS:
; KEY1: Document keyword parameters like this. Note that the keyword
; is shown in ALL CAPS!
;
; KEY2: Yet another keyword. Try to use the active, present tense
; when describing your keywords. For example, if this keyword
; is just a set or unset flag, say something like:
; "Set this keyword to use foobar subfloatation. The default
; is foobar superfloatation."
;
; OUTPUTS:
; Describe any outputs here. For example, "This function returns the
; foobar superflimpt version of the input array." This is where you
; should also document the return value for functions.
;
; OPTIONAL OUTPUTS:
; Describe optional outputs here. If the routine doesn't have any,
; just delete this section.
;
; COMMON BLOCKS:
; BLOCK1: Describe any common blocks here. If there are no COMMON
; blocks, just delete this entry.
;
; SIDE EFFECTS:
; Describe "side effects" here. There aren't any? Well, just delete
; this entry.
;
; RESTRICTIONS:
; Describe any "restrictions" here. Delete this section if there are
; no important restrictions.
;
; PROCEDURE:
; You can describe the foobar superfloatation method being used here.
; You might not need this section for your routine.
;
; EXAMPLE:
; Please provide a simple example here. An example from the
; DIALOG_PICKFILE documentation is shown below. Please try to
; include examples that do not rely on variables or data files
; that are not defined in the example code. Your example should
; execute properly if typed in at the IDL command line with no
; other preparation.
;
; Create a DIALOG_PICKFILE dialog that lets users select only
; files with the extension `pro'. Use the `Select File to Read'
; title and store the name of the selected file in the variable
; file. Enter:
;
; file = DIALOG_PICKFILE(/READ, FILTER = '*.pro')
;
; MODIFICATION HISTORY:
; Written by: Your name here, Date.
; July, 1994 Any additional mods get described here. Remember to
; change the stuff above if you add a new keyword or
; something!
;-
Changed:
< <
> >
PRO TEMPLATE
Changed:
< <
ETAPE FACULTATIVE : On peut encore améliorer les choses... Comment ?
> >
PRINT, "This is an example header file for documenting IDL routines"
Changed:
< <
En s'arrangeant pour ne plus avoir aucun mot de passe à entrer grâce aux clés publique&privée.
> >
END
Deleted:
< <
Voici comment faire...
Changed:
< <
1) Créer une paire de clés privée/publique sur mon pc
> >
Le même bloc de commentaires, mais vide :
Changed:
< <
$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/pallier/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/pallier/.ssh/id_dsa.
Your public key has been saved in /Users/pallier/.ssh/id_dsa.pub.
2) Distribuer ensuite la clé publique de mon pc sur la passerelle du labo (que nous appelerons GATEWAY pour raison de sécurité)
Deleted:
< <
La clé publique, doit être copiée sur le serveur distant dans ~/.ssh/authorized_keys. (La clé privée reste sur votre poste client)
Changed:
< <
Aller dans votre HOME
> >
OUTILS pour documenter le code
doc_library
doc_library affiche seulement "tel quel" le bloc de commentaires complet compris entre ";+" et ";-", et affiche le chemin du fichier.
Pour documenter une fonction ou une procédure :
Fonction "dist":
Changed:
< <
ssh-copy-id -i .ssh/id_dsa.pub GATEWAY
(
ou bien, si on ne dispose pas de la commande ssh-copy-id, l'exemple est ici donné pour moi :
$ cat .ssh/id_dsa.pub | ssh epallier@GATEWAY "cat - >>.ssh/authorized_keys"
)
> >
IDL> doc_library, 'DIST'
Changed:
< <
> >
Documentation for C:\Program Files\ITT\IDL\IDL80\lib\dist.pro
PURPOSE:
Create a rectangular array in which each element is proportional
to its frequency. This array may be used for a variety
of purposes, including frequency-domain filtering and
making pretty pictures.
Changed:
< <
On peut désormais se connecter directement sans mot de passe !!!
> >
CATEGORY:
Signal Processing.
Changed:
< <
4) Faire de même entre GATEWAY et hyperion
> >
CALLING SEQUENCE:
Result = DIST(N [, M])
Changed:
< <
Maintenant, il suffit de faire la même chose que 2) et 3) mais depuis GATEWAY (et vers hyperion)
> >
INPUTS:
N = number of columns in result.
M = number of rows in result. If omitted, N is used to return
a square array.
Changed:
< <
Quand c'est fait, depuis GATEWAY, on peut maintenant se connecter directement à hyperion sans mot de passe :
> >
OUTPUTS:
Returns an (N,M) floating array in which:
MODIFICATION HISTORY:
Very Old.
SMR, March 27, 1991 - Added the NOZERO keyword to increase efficiency.
(Recomended by Wayne Landsman)
DMS, July, 1992. - Added M parameter to make non-square arrays.
CT, RSI, March 2000: Changed i^2 to i^2. to avoid overflow.
Changed:
< <
Il suffit alors de taper "tunnel" pour qu'il soit créé.
> >
Fonction plot:
Added:
> >
IDL> doc_library, 'plot'
Changed:
< <
Autre Méthode (pour info)
> >
Documentation for C:\Program Files\ITT\IDL\IDL80\lib\graphics\plot.pro
Changed:
< <
Pour automatiser le "rebond" via GATEWAY*
> >
:Description:
Create IDL Plot graphic.
Changed:
< <
On va maintenant rendre transparent le passage via GATEWAY. Il suffit pour cela de créer un fichier de config :
Dans ce dernier exemple (plot), on se rend compte que depuis idl 8, les nouvelles fonctions/procédures (telles que la fonction plot) ne sont plus commentées
au format "idl" mais "rst", qui semble donc être le nouveau format à utiliser pour commenter du code idl.
Ce dernier format ("idl") a juste le "mérite" d'être un standard pour les routines IDL, mais il est peu et mal exploité par IdlDoc qui ne reconnait que très peu de balises de commentaires (seulement 6) parmis celles proposées dans template.pro, et les met mal en valeur dans la doc générée.
Changed:
< <
The "Direct Rendering Infrastructure" (DRI) or "Direct hardware rendering" is described here :
Voir conseils généraux (Michael Galloy) "A style guide" : styleguide.pdf
> >
Installation
Changed:
< <
Je livre ici une synthèse des conseils de Michael Galloy pour bien documenter un code IDL (Lire "A style guide" pour la version complète avec justifications) :
> >
(NB: sur hyperion, c'est déjà installé sous /usr/local/itt/idldoc/idldoc)
Changed:
< <
1. General principles
> >
1) Download
Changed:
< <
1. Code is for humans.
> >
2) Copier et dézipper dans un dossier de mon choix (ex : D:/idldoc/idldoc-3.3)
Changed:
< <
2. Do not mix styles.
> >
3) Ajouter le chemin vers idldoc dans le IDL_PATH (Fenêtre/Preferences/IDL/Chemins/Insérer (puis Appliquer)
Deleted:
< <
3. Avoid redundancy.
Changed:
< <
4. Use an easy to maintain style.
> >
Utilisation
Changed:
< <
2. Layout
> >
Pour générer la doc avec idldoc :
Changed:
< <
1. Layout should enhance the logical structure of the code.
2. Use two spaces (not tabs) per indentation level.
> >
Puis, 2clic sur index.html
Changed:
< <
3. Use a maximum line length of 79 characters.
> >
Exemple plus complet:
Changed:
< <
4. Write code in paragraphs.
> >
IDL> idldoc, root='path_vers_mon_repertoire_source', output='path_vers_mon_repertoire_doc', title='DOC pour mon projet', subtitle='generated with idldoc 3.3', format_style='rst', overview='path_vers_mon_fichier_overview'
Changed:
< <
Example:
function mg_sample, nValues, nIndices, seed=seed
compile_opt strictarr
> >
Remarque: format_style peut prendre les 3 valeurs "rst", "idl" ou "idldoc"
Deleted:
< <
; get random nIndices by finding the indices of the smallest
; nIndices in an array of random values
values = randomu(seed, nValues)
Deleted:
< <
; our random values are uniformly distributed, so ideally
; the nIndices smallest values are in the first bin of the
; below histogram
nBins = nValues / nIndices
h = histogram(values, nbins=nBins, reverse_indices=ri)
Changed:
< <
; the candidates for being in the first nIndices will live in
; bins 0..bin
nCandidates = 0L
for bin = 0L, nBins - 1L do begin
nCandidates += h[bin]
if (nCandidates ge nIndices) then break
endfor
> >
Enregistrer une image dans un fichier
Changed:
< <
; get the candidates and sort them
candidates = ri[ri[0] : ri[bin + 1L] - 1L]
sortedCandidates = sort(values[candidates])
> >
; envoi vers fichier postscript
set_plot, 'ps'
Changed:
< <
; return the first nIndices of them
return, (candidates[sortedCandidates])[0:nIndices-1L]
end
> >
; éventuellement donner un nom
device, filename='toto.ps'
plot, findgen(2)
; retour à l'affichage sur écran
device, /close
set_plot, 'x'
Deleted:
< <
5. Insert two blank lines between routines.
Changed:
< <
One blank line separates "paragraphs"; two blank lines separate "sections."
$f1= function () {
echo "<p>Hello, World!</p>";
};
Changed:
< <
3. Comments
> >
$f2= function ($param) {
echo "
Hello, $param!
";
};
Changed:
< <
1. Document intent.
> >
call :
Changed:
< <
2. Keep comments up to date with the code.
> >
$f1();
Changed:
< <
3. For a short comment, use a phrase with lowercase first letter and no period. For longer comments, use all
normal grammar rules.
> >
$f2('there');
Changed:
< <
5. Write a complete header for each routine.
> >
call_user_func($f1);
Changed:
< <
Use comments between ;+ and ;- before the routine. Document the purpose of the routine, the return value (if
a function), and side effects of the routine (which you should strive to eliminate). Each parameter should be
documented with whether it is an input and/or output, optional or required, data type expected, default value (if
any) and a description of its purpose.
> >
call_user_func($f2, 'You');
Changed:
< <
For example, the below is an IDLdoc formatted header for the routine listed above:
> >
call_user_func_array($f1, array());
Changed:
< <
;+
; Get nIndices random indices for an array of size nValues (do
; not repeat an index).
;
; :Returns: lonarr(nIndices)
;
; :Params:
; nValues : in, required, type=long
; size of array to choose indices from
; nIndices : in, required, type=long
; number of indices needed
;
; :Keywords:
; seed : in, out, optional, type=long or lonarr(36)
; seed to use for random number generation, a new seed
; will be output
;-
function mg_sample, nValues, nIndices, seed=seed
> >
call_user_func_array($f2, array('You'));
Changed:
< <
6. Indent a comment along with the code it's documenting.
Each paragraph of code may need a comment to document its purpose, but inside a paragraph use only end-of-line
comments to comment particular lines.
It can be helpful to write the comments first, providing an outline of the code to write.
Don't document bad code—rewrite it. (Kernighan and Plauger, The Elements of Programming Style)
> >
Utilisé pour les fonctions anonymes, le mot-clef "use" permet d’importer (en lecture seule) des variables externes, issues de l’espace de noms « global », au sein de la fonction lambda.
Changed:
< <
4. Statement formatting
> >
$var = 'World';
$f2 = function () use ($var) {
echo "<p>Hello, $var!</p>";
};
Changed:
< <
4.1. Use lowercase for reserved words, operators, and compile_opt option names.
> >
$f2(); // Hello, World!
Deleted:
< <
For example, use:
compile_opt strictarr
if (not done) then readf, lun, line
Changed:
< <
4.2. Use only one statement per line.
> >
En quelque sorte, "use" fait penser à l’instruction "global", que nous rencontrions parfois auparavant… Mais global ne répond pas aux besoins des closures
Changed:
< <
For example, don't write:
> >
Import de variable par référence :
Changed:
< <
a = 1 & b = 2
> >
Changed:
< <
4.3. Prefer begin/end blocks unless the entire statements fits on one line.
> >
$var = 0;
Changed:
< <
For a single, long statement, use:
for i = 0, 10 do begin
print, i, format='("The index is ", I0, ".")'
end
> >
$func2 = function () use (& $var) {
echo "
Début 2 : $var
";
$var = 2;
echo "
Fin 2 : $var
";
};
Changed:
< <
But never write:
for i = 0, 10 do $
print, i, format='("The index is ", I0, ".")'
> >
et le résultat :
Changed:
< <
4.5. Define structures one field per line unless the entire definition can fit on one line.
> >
echo "
Avant 2 : $var
"; // Avant 2 : 0
$func2(); // Début 2 : 0
// Fin 2 : 2
echo "
Après 2 : $var
"; // Après 2 : 2
Deleted:
< <
For example, use:
point = { x: 0.0, y:0.0 }
state = { x: 0.0, $
y: 0.0, $
pdata: ptr_new(), $ ; image data
drawId: 0L $ ; window identifier
}
Changed:
< <
4.6. Add one space around most operators.
> >
Mais, qu'est-ce qu'une fonction anonyme pour php ?
Changed:
< <
ex:
> >
$func = function ($param) {
echo "<p>Hello, $param!</p>";
};
Changed:
< <
slope = (y0 - y1) / (x0 - x1)
> >
var_dump($func);
Changed:
< <
tvscl, im, true=1
> >
Le résultat obtenu est le suivant :
Changed:
< <
bin = arr[r[r[i]:r[i + 1] - 1]]
> >
object(Closure)[1]
Changed:
< <
point = { x: 0.0, y: 0.0 }
> >
Pour PHP, une fonction anonyme — une lambda — est un objet : une instance de classe Closure…
Deleted:
< <
Also, don't add extra spaces in order to align values.
Changed:
< <
4.7. Use single quotes for strings.
> >
Closures
Changed:
< <
Use double single quotes if you need a single quote. For example,
Une closure est une fonction qui est évaluée dans un environnement contenant une ou plusieurs variables liées, auxquelles elle peut accéder au moment de son exécution.
Changed:
< <
4.9. Use capital letters to indicate the type of constant, use lowercase to indicate base of integers.
> >
Dans certains langages — dont Javascript, et PHP >= 5.3 — une closure peut exister lorsqu’une fonction est définie au sein d’une autre, et que la fonction interne fait référence à des variables de la fonction externe.
A l’exécution, une closure est formée : elle est constituée du code de la fonction interne et des références aux variables externes utilisées par celle-ci.
Changed:
< <
Use 0L not 0l because "l" (lowercase letter el) looks like "1" (integer one). Use '5'o and '5'x, not '5'O and
'5'X.
> >
En PHP, une closure se construit de la manière suivante :
Changed:
< <
4.10. Use square brackets for array indices.
> >
Une variable locale est créée dans une première fonction "externe",
Une seconde fonction "interne" est définie à l’intérieur de la première fonction, sous forme d’une fonction anonyme,
Et cette fonction "interne" importe la variable locale de la fonction "externe", à l’aide du mot-clef use.
Changed:
< <
Use
> >
Closure en lecture-seule :
Changed:
< <
compile_opt strictarr
> >
Ex :
Changed:
< <
in each routine to prevent issues with IDL confusing arrays and functions calls.
> >
$func = function ($arg) {
$compteur = $arg; // Copie privée, en lecture seule
return function () use ($compteur) {
return ++$compteur;
};
};
3. Prefer pointers, objects, and passing local variables over common blocks or system variables.
> >
Changed:
< <
Occasionally there is a reason to use common blocks or system variables, but you should have a good argument
for it.
> >
Le mécanisme de closure permet donc de créer des variables au sein de la fonction "externe", qui conserveront leur valeur aussi longtemps que l’on aura conservé un pointeur sur la fonction "interne".
Ces variables seront accessibles par la fonction interne, éventuellement en écriture si nous avons utilisé & lors de leur import, tout en n’étant pas visibles du reste de notre script.
Deleted:
< <
When using direct graphics, prefer using graphics keywords of the plotting routines over setting system
variables directly.
Changed:
< <
4. Define common blocks and named structures in only one location.
> >
Appel de fonction sur un objet
Changed:
< <
Define the variables in a common block only once in a batch file. Include that file where needed.
> >
PHP 5.3 ajoute la possibilité d’utiliser la syntaxe d’un appel de fonction sur un objet, en lui appliquant l’opérateur ().
Changed:
< <
map_proj_init_commonblock.pro is an example of this.
> >
Pour cela, une nouvelle méthode magique a été ajoutée : __invoke :
Changed:
< <
Define a named structure using automatic structure definition. For example, define MG_Point in a routine
named MG_POINT__DEFINE in a file named mg_point__define.pro.
> >
lors d’un appel de fonction sur une instance de classe comportant une méthode __invoke, c’est cette méthode qui sera appelée.
Added:
> >
Voici une classe d’exemple :
Changed:
< <
6. Routines
> >
class MyString {
public $str;
public function __construct($a) {
$this->str = $a;
}
Changed:
< <
1. For any file containing IDL code, filenames should always be in lower case and use the ".pro" extension.
> >
// Appelée quand on appelle dynamiquement un
// objet instance de cette classe
public function __invoke($a) {
var_dump(METHOD);
$this->str = $a;
}
}
Deleted:
< <
2. Each file should include only one routine called from outside the file.
Changed:
< <
Each file should contain only one routine called from outside that file. Add the ".pro" extension to the routine
name of the externally called routine to get the filename. For example, the routine MG_LINEAR_FUNCTION
should be in a file named mg_linear_function.pro. If there are multiple routines in the file, make sure the
externally called routine is last in the file.
> >
Session
Changed:
< <
3. Routine names should be lower case, begin with a short organization prefix, and separate words with
underscores.
> >
Endroit où sont stockés les fichiers (temporaires) de session : session.save_path (php.ini)
Changed:
< <
The prefix indicates the individual or group responsible for the code. It is usually the initials of the individual or
orgranization. Limit to two or three letters. Don't use the "IDL", "RSI", "ITT", "cw", "it", or empty prefixes.
> >
Dans xampp : session.save_path = "D:\xampp\tmp"
Changed:
< <
4. Routines should fit on one screen.
> >
Sur linux : session.save_path = "/var/lib/php/session" (/etc/php.ini)
Changed:
< <
5. Keywords should always be optional for the caller; positional parameters should generally be required.
> >
La façon la plus sécurisée est d'utiliser les cookies
Changed:
< <
Keywords should either be an optional input with a reasonable default value or an extra output (i.e. not the
main purpose of the routine).
> >
1) Le client (navigateur) demande un identifiant de session (jeton)
Changed:
< <
6. Keyword names should be lowercase and separate words with underscores.
> >
2) Le serveur crée l'identifiant et le retourne au client
Changed:
< <
For example,
filename
ntests
eye_separation
left_image
> >
3) Le client stocke sur son disque dur cet identifiant sous la forme d'un cookie qu'il enverra désormais à chaque requête
Changed:
< <
7. Always use the full keyword name when calling the routine.
> >
Nom du jeton par défaut = PHPSESSID (cf php.ini session.name et fonction session_name())
Changed:
< <
8. If the purpose of a routine is to return a value, use a function, otherwise use a procedure.
> >
Sur le serveur, ce jeton aura le nom "sess_" suivi de sa valeur
Changed:
< <
9. Status and error codes should be returned via keyword.
> >
Valeur du jeton = string générée aléatoirement par php (fonction session_id() retourne cette valeur et permet éventuellement de la fixer, mais déconseilllé)
Added:
> >
Paramètres php.ini à positionner (on peut utiliser session_set_cookie_params() pour cela, il y a aussi ini_get() et ini_set()) :
Changed:
< <
7. Object-oriented programming
> >
session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0 (si cookies pas acceptés, ne pas pour autant transmettre l'id de session dans l'url)
session.cookie_lifetime = 0 (jusqu'au moment de quitter le navigateur)
session.auto_start = 0
session.save_handler = files
session.save_path = ...
Changed:
< <
1. Class names should begin with a prefix indicating organization and a code indicating the class' area of use.
Each word should be capitalized
> >
La fonction session_start() crée ou restaure une session (à mettre en première ligne du bootstrap)
Changed:
< <
Use the same prefix as given to normal routine names; avoid "IDL", "ITT", "RSI", and the empty prefix.
> >
session_regenerate_id() regénère l'id de session afin d'éviter une fixation de la session
Changed:
< <
Codes already in use by IDL: an (analysis), com (COM), db (database), ex (example), ff (file format), gr
(graphics), it (iTools), sys (system), net (network), and _ (general use). Make use of the existing codes and
make up new ones as necessary.
> >
appeler session_destroy() à la déconnexion du user
Deleted:
< <
Use all caps for abbreviations in class names, as in IDLnetURL.
Deleted:
< <
2. Put all the methods and the routine defining the instance variables for a class into a single file.
Deleted:
< <
For the definition of MGexClass, the file should be named mgexclass__define.pro. The last routine in this file
should be MGEXCLASS__DEFINE and should define the instance variables for the class (i.e. create a named
structure with name MGexClass).
Deleted:
< <
Define only one structure/class name in the __DEFINE routine.
Deleted:
< <
3. Method names should be a verb phrase in camel case.
Deleted:
< <
For example, here are some method names following these conventions:
Use the conventions that are used by the IDL library classes. For example, use the GETPROPERTY and
SETPROPERTY scheme of procedures to handle getting and setting properties of a class.
Changed:
< <
4. Begin "protected" methods' names with a underscore.
Use multiple inheritance as a last resort. Prefer delegation for one of the parent classes i.e. make the new class
contain the secondary parent class as an instance variable.
Added:
> >
Créer un projet Zend
Changed:
< <
8. Exemple de commentaires proposé par ITT dans examples/template.pro
;+
; NAME:
; ROUTINE_NAME
;
; PURPOSE:
; Tell what your routine does here. I like to start with the words:
; "This function (or procedure) ..."
; Try to use the active, present tense.
;
; CATEGORY:
; Put a category (or categories) here. For example:
; Widgets.
;
; CALLING SEQUENCE:
; Write the calling sequence here. Include only positional parameters
; (i.e., NO KEYWORDS). For procedures, use the form:
;
; ROUTINE_NAME, Parameter1, Parameter2, Foobar
;
; Note that the routine name is ALL CAPS and arguments have Initial
; Caps. For functions, use the form:
;
; Result = FUNCTION_NAME(Parameter1, Parameter2, Foobar)
;
; Always use the "Result = " part to begin. This makes it super-obvious
; to the user that this routine is a function!
;
; INPUTS:
; Parm1: Describe the positional input parameters here. Note again
; that positional parameters are shown with Initial Caps.
;
; OPTIONAL INPUTS:
; Parm2: Describe optional inputs here. If you don't have any, just
; delete this section.
;
; KEYWORD PARAMETERS:
; KEY1: Document keyword parameters like this. Note that the keyword
; is shown in ALL CAPS!
;
; KEY2: Yet another keyword. Try to use the active, present tense
; when describing your keywords. For example, if this keyword
; is just a set or unset flag, say something like:
; "Set this keyword to use foobar subfloatation. The default
; is foobar superfloatation."
;
; OUTPUTS:
; Describe any outputs here. For example, "This function returns the
; foobar superflimpt version of the input array." This is where you
; should also document the return value for functions.
;
; OPTIONAL OUTPUTS:
; Describe optional outputs here. If the routine doesn't have any,
; just delete this section.
;
; COMMON BLOCKS:
; BLOCK1: Describe any common blocks here. If there are no COMMON
; blocks, just delete this entry.
;
; SIDE EFFECTS:
; Describe "side effects" here. There aren't any? Well, just delete
; this entry.
;
; RESTRICTIONS:
; Describe any "restrictions" here. Delete this section if there are
; no important restrictions.
;
; PROCEDURE:
; You can describe the foobar superfloatation method being used here.
; You might not need this section for your routine.
;
; EXAMPLE:
; Please provide a simple example here. An example from the
; DIALOG_PICKFILE documentation is shown below. Please try to
; include examples that do not rely on variables or data files
; that are not defined in the example code. Your example should
; execute properly if typed in at the IDL command line with no
; other preparation.
;
; Create a DIALOG_PICKFILE dialog that lets users select only
; files with the extension `pro'. Use the `Select File to Read'
; title and store the name of the selected file in the variable
; file. Enter:
;
; file = DIALOG_PICKFILE(/READ, FILTER = '*.pro')
;
; MODIFICATION HISTORY:
; Written by: Your name here, Date.
; July, 1994 Any additional mods get described here. Remember to
; change the stuff above if you add a new keyword or
; something!
;-
> >
Le contrôleur de Zend Framework réserve une action "index" comme action par défaut. C'est-à-dire que pour l'URI "http://localhost/tutoriel-zf/actualités/", l'action "index" est exécutée. Le framework réserve également un nom de contrôleur si aucun n'est fourni dans l'URI : aucune surprise qu'il soit également appelé "index". Ainsi, l'URI "http://localhost/tutoriel-zf/" appelle le contrôleur "index" avec l'action "index".
Changed:
< <
PRO TEMPLATE
> >
1) install
Changed:
< <
PRINT, "This is an example header file for documenting IDL routines"
> >
Download zf
Changed:
< <
END
> >
Copier dans D:\ProgFilesNoInstall\zf
Added:
> >
Ajouter D:\ProgFilesNoInstall\zf\bin dans PATH windows
Dans Eclipse, créer un projet PHP nommé "zfquickstart"
Added:
> >
Ouvrir une console DOS
Changed:
< <
OUTILS pour documenter le code
> >
Aller dans xampp/htdocs
Changed:
< <
doc_library
> >
zf create project zfquickstart
Changed:
< <
doc_library affiche seulement "tel quel" le bloc de commentaires complet compris entre ";+" et ";-", et affiche le chemin du fichier.
> >
crée 3 dossiers :
Changed:
< <
Pour documenter une fonction ou une procédure :
> >
- application/ qui contient Bootstrap.php et configs/application.ini
Changed:
< <
Fonction "dist":
> >
- public/
Changed:
< <
IDL> doc_library, 'DIST'
> >
- library/
Changed:
< <
Documentation for C:\Program Files\ITT\IDL\IDL80\lib\dist.pro
> >
public/ contient 2 fichiers importants :
Changed:
< <
NAME:
DIST
> >
.htaccess :
Changed:
< <
PURPOSE:
Create a rectangular array in which each element is proportional
to its frequency. This array may be used for a variety
of purposes, including frequency-domain filtering and
making pretty pictures.
index.php : qui lance $application->bootstrap() et ->run()
Deleted:
< <
CALLING SEQUENCE:
Result = DIST(N [, M])
Deleted:
< <
INPUTS:
N = number of columns in result.
M = number of rows in result. If omitted, N is used to return
a square array.
Deleted:
< <
OUTPUTS:
Returns an (N,M) floating array in which:
Deleted:
< <
R(i,j) = SQRT(F(i)^2 + G(j)^2) where:
F(i) = i IF 0 <= i <= n/2
= n-i IF i > n/2
G(i) = i IF 0 <= i <= m/2
= m-i IF i > m/2
Changed:
< <
SIDE EFFECTS:
None.
> >
3) The Bootstrap
Changed:
< <
RESTRICTIONS:
None.
> >
Your Bootstrap class defines what resources and components to initialize. By default, Zend Framework's Front Controller is initialized, and it uses the application/controllers/ as the default directory in which to look for action controllers
Changed:
< <
PROCEDURE:
Straightforward. The computation is done a row at a time.
> >
Changed:
< <
MODIFICATION HISTORY:
Very Old.
SMR, March 27, 1991 - Added the NOZERO keyword to increase efficiency.
(Recomended by Wayne Landsman)
DMS, July, 1992. - Added M parameter to make non-square arrays.
CT, RSI, March 2000: Changed i^2 to i^2. to avoid overflow.
> >
// application/Bootstrap.php
Changed:
< <
Fonction plot:
> >
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
Changed:
< <
IDL> doc_library, 'plot'
> >
4) Configuration
Changed:
< <
Documentation for C:\Program Files\ITT\IDL\IDL80\lib\graphics\plot.pro
> >
While Zend Framework is itself configurationless, you often need to configure your application. The default configuration is placed in application/configs/application.ini, and contains some basic directives for setting your PHP environment (for instance, turning error reporting on and off), indicating the path to your bootstrap class (as well as its class name), and the path to your action controllers.
Dans ce dernier exemple (plot), on se rend compte que depuis idl 8, les nouvelles fonctions/procédures (telles que la fonction plot) ne sont plus commentées
au format "idl" mais "rst", qui semble donc être le nouveau format à utiliser pour commenter du code idl.
Cet outil génère une doc html d'un fichier ou même d'un répertoire complet :
> >
First, when using INI-style configuration, you can reference constants directly and expand them; APPLICATION_PATH is actually a constant.
Changed:
< <
ex: documentation du fichier dist.pro:
> >
Additionally note that there are several sections defined: production, staging, testing, and development. The latter three inherit settings from the "production" environment. This is a useful way to organize configuration to ensure that appropriate settings are available in each stage of application development.
Changed:
< <
MK_HTML_HELP, 'C:\Program Files\ITT\IDL\IDL80\lib\dist.pro', 'help_dist.html' ; La doc générée est help_dist.html
> >
5) Action Controllers
Changed:
< <
ex: documentation d'une arborescence complète:
> >
Your application's action controllers contain your application workflow, and do the work of mapping your requests to the appropriate models and views.
Changed:
< <
MK_HTML_HELP, 'C:\Program Files\ITT\IDL\IDL80\lib', 'help.html' ; La doc générée est help.html
> >
An action controller should have one or more methods ending in "Action"; these methods may then be requested via the web. By default, Zend Framework URLs follow the schema /controller/action, where "controller" maps to the action controller name (minus the "Controller" suffix) and "action" maps to an action method (minus the "Action" suffix).
Added:
> >
Typically, you always need an IndexController, which is a fallback controller and which also serves the home page of the site, and an ErrorController, which is used to indicate things such as HTTP 404 errors (controller or action not found) and HTTP 500 errors (application errors).
public function errorAction()
{
$errors = $this->_getParam('error_handler');
Changed:
< <
rst : le format le plus récent, qui tend à devenir le nouveau standard, il apporte beaucoup de possibilités
idldoc : le format historique de idldoc, qui ressemble à celui utilisé par des outils plus génériques, tels que Doxygen
idl : le format utilisé par ITT (et proposé dans examples/template.pro)
> >
switch ($errors->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
Changed:
< <
Ce dernier format ("idl") a juste le "mérite" d'être un standard pour les routines IDL, mais il est peu et mal exploité par IdlDoc qui ne reconnait que très peu de balises de commentaires (seulement 6) parmis celles proposées dans template.pro, et les met mal en valeur dans la doc générée.
> >
// 404 error -- controller or action not found
$this->getResponse()->setHttpResponseCode(404);
$this->view->message = 'Page not found';
break;
default:
// application error
$this->getResponse()->setHttpResponseCode(500);
$this->view->message = 'Application error';
break;
}
You'll note that the IndexController contains no real code, and the ErrorController makes reference to a "view" property. That leads nicely into our next subject.
Deleted:
< <
; SIDE EFFECTS:
Changed:
< <
; RESTRICTIONS:
> >
6) Views
Changed:
< <
; PROCEDURE:
> >
Views in Zend Framework are written in plain old PHP. View scripts are placed in application/views/scripts/, where they are further categorized using the controller names. In our case, we have an IndexController and an ErrorController, and thus we have corresponding index/ and error/ subdirectories within our view scripts directory. Within these subdirectories, you will then find and create view scripts that correspond to each controller action exposed; in the default case, we thus have the view scripts index/index.phtml and error/error.phtml.
Changed:
< <
; EXAMPLE:
> >
View scripts may contain any markup you want, and use the closing tag to insert PHP directives.
There are several things to note. First, note that the DocumentRoot setting specifies the public subdirectory of our project; this means that only files under that directory can ever be served directly by the server. Second, note the AllowOverride, Order, and Allow directives; these are to allow us to use htacess files within our project. During development, this is a good practice, as it prevents the need to constantly restart the web server as you make changes to your site directives; however, in production, you should likely push the content of your htaccess file into your server configuration and disable this. Third, note the SetEnv directive. What we are doing here is setting an environment variable for your virtual host; this variable will be picked up in the index.php and used to set the APPLICATION_ENV constant for our Zend Framework application. In production, you can omit this directive (in which case it will default to the value "production") or set it explicitly to "production".
Changed:
< <
Exemple plus complet:
> >
Avec un , il faudrait aussi faire ceci :
Changed:
< <
IDL> idldoc, root='path_vers_mon_repertoire_source', output='path_vers_mon_repertoire_doc', title='DOC pour mon projet', subtitle='generated with idldoc 3.3', format_style='rst', overview='path_vers_mon_fichier_overview'
> >
Finally, you will need to add an entry in your hosts file corresponding to the value you place in your ServerName directive. On *nix-like systems, this is usually /etc/hosts; on Windows, you'll typically find it in C:\WINDOWS\system32\drivers\etc. Regardless of the system, the entry will look like the following:
Changed:
< <
Remarque: format_style peut prendre les 3 valeurs "rst", "idl" ou "idldoc"
> >
127.0.0.1 zfquickstart.local
Added:
> >
Start your webserver (or restart it), and you should be ready to go.
NB: il faut ajouter le chemin vers ZF ("D:\ProgFilesNoInstall\zf\library") :
Changed:
< <
; envoi vers fichier postscript
set_plot, 'ps'
> >
soit dans php.ini,
soit, mieux, dans le fichier index.php du dossier "public/" du projet : chercher la ligne "set_include_path" et insérer en tête de liste, ce qui donne :
Changed:
< <
; éventuellement donner un nom
device, filename='toto.ps'
> >
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
Changed:
< <
plot, findgen(2)
> >
//EP added :
"D:\ProgFilesNoInstall\zf\library",
Changed:
< <
; retour à l'affichage sur écran
device, /close
set_plot, 'x'
To get started using Zend_Layout, first we need to inform our bootstrap to use the Layout resource. This can be done using the zf enable layout command:
Changed:
< <
Fonctions anonymes (lambda)
> >
% zf enable layout
Layouts have been enabled, and a default layout created at
application/layouts/scripts/layout.phtml
A layout entry has been added to the application config file.
As noted by the command, application/configs/application.ini is updated, and now contains the following within the production section:
Changed:
< <
$f1= function () {
echo "
Hello, World!
";
};
> >
; application/configs/application.ini
Changed:
< <
$f2= function ($param) {
echo "
Hello, $param!
";
};
> >
; Add to [production] section:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
Changed:
< <
call :
$f1();
> >
We also want to ensure we have an XHTML DocType declaration for our application. To enable this, we need to add a resource to our bootstrap.
Changed:
< <
$f2('there');
> >
The simplest way to add a bootstrap resource is to simply create a protected method beginning with the phrase _init. In this case, we want to initialize the doctype, so we'll create an _initDoctype() method within our bootstrap class.
Changed:
< <
call_user_func($f1);
> >
Within that method, we need to hint to the view to use the appropriate doctype. But where will the view object come from? The easy solution is to initialize the View resource; once we have, we can pull the view object from the bootstrap and use it.
Changed:
< <
call_user_func($f2, 'You');
> >
To initialize the view resource, add the following line to your application/configs/application.ini file, in the section marked production:
Changed:
< <
call_user_func_array($f1, array());
> >
resources.view[] =
Changed:
< <
call_user_func_array($f2, array('You'));
> >
This tells us to initialize the view with no options (the '[]' indicates that the "view" key is an array, and we pass nothing to it).
Changed:
< <
Exemple d'utilisation avec array_map :
> >
Now that we have a view, let's flesh out our _initDoctype() method. In it, we will first ensure the View resource has run, fetch the view object, and then configure it:
Le résultat obtenu sera exactement le même que juste au-dessus, à savoir :
> >
We grab our application content using the layout() view helper, and accessing the "content" key. You may render to other response segments if you wish to, but in most cases, this is all that's necessary.
Note also the use of the headLink() placeholder. This is an easy way to generate the HTML for elements, as well as to keep track of them throughout your application. If you need to add additional CSS sheets to support a single action, you can do so, and be assured it will be present in the final rendered page.
Deleted:
< <
Utilisé pour les fonctions anonymes, le mot-clef "use" permet d’importer (en lecture seule) des variables externes, issues de l’espace de noms « global », au sein de la fonction lambda.
Changed:
< <
$var = 'World';
$f2 = function () use ($var) {
echo "<p>Hello, $var!</p>";
};
Your application bootstrap will by default use the module prefix "Application". As such, our models, forms, and table classes will all begin with the class prefix "Application_".
Changed:
< <
En quelque sorte, "use" fait penser à l’instruction "global", que nous rencontrions parfois auparavant… Mais global ne répond pas aux besoins des closures
> >
zf configure db-adapter 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' production
"; // Avant 2 : 0
$func2(); // Début 2 : 0
// Fin 2 : 2
echo "
Après 2 : $var
"; // Après 2 : 2
> >
This will create a new controller, GuestbookController, in application/controllers/GuestbookController.php, with a single action method, indexAction(). It will also create a view script directory for the controller, application/views/scripts/guestbook/, with a view script for the index action.
Changed:
< <
> >
We'll use the "index" action as a landing page to view all guestbook entries.
Changed:
< <
Mais, qu'est-ce qu'une fonction anonyme pour php ?
> >
Now, let's flesh out the basic application logic. On a hit to indexAction(), we'll display all guestbook entries. This would look like the following:
class GuestbookController extends Zend_Controller_Action
{
public function indexAction()
{
$guestbook = new Application_Model_GuestbookMapper();
$this->view->entries = $guestbook->fetchAll();
}
}
Deleted:
< <
Le résultat obtenu est le suivant :
Changed:
< <
object(Closure)[1]
> >
And, of course, we need a view script to go along with that. Edit application/views/scripts/guestbook/index.phtml to read as follows:
Une closure est une fonction qui est évaluée dans un environnement contenant une ou plusieurs variables liées, auxquelles elle peut accéder au moment de son exécution.
> >
% zf create form Guestbook
Changed:
< <
Dans certains langages — dont Javascript, et PHP >= 5.3 — une closure peut exister lorsqu’une fonction est définie au sein d’une autre, et que la fonction interne fait référence à des variables de la fonction externe.
A l’exécution, une closure est formée : elle est constituée du code de la fonction interne et des références aux variables externes utilisées par celle-ci.
> >
Next, we will add a signAction() to our GuestbookController which will process the form upon submission. To create the action and related view script, execute the following:
Changed:
< <
En PHP, une closure se construit de la manière suivante :
> >
% zf create action sign Guestbook
Changed:
< <
Une variable locale est créée dans une première fonction "externe",
Une seconde fonction "interne" est définie à l’intérieur de la première fonction, sous forme d’une fonction anonyme,
Et cette fonction "interne" importe la variable locale de la fonction "externe", à l’aide du mot-clef use.
La syntaxe Heredoc se comporte exactement comme une chaîne à guillemets doubles, sans les guillemets doubles. Cela signifie que vous n'avez pas à échapper les guillemets (simples ou doubles) dans cette syntaxe. Les variables sont remplacées par leur valeur et le même soin doit leur être apporté que dans les chaînes à guillemets doubles.
Exemple de chaîne HereDoc
Deleted:
< <
$func = function ($arg) {
$compteur = $arg; // Copie privée, en lecture / écriture
return function () use (& $compteur) {
return ++$compteur;
};
};
<?php
$str = <<<EOD
Exemple de chaîne
s'étalant sur
plusieurs lignes
avec la syntaxe heredoc
EOD;
Changed:
< <
Le mécanisme de closure permet donc de créer des variables au sein de la fonction "externe", qui conserveront leur valeur aussi longtemps que l’on aura conservé un pointeur sur la fonction "interne".
Ces variables seront accessibles par la fonction interne, éventuellement en écriture si nous avons utilisé & lors de leur import, tout en n’étant pas visibles du reste de notre script.
> >
/* Exemple plus complexe, avec des variables. */
class foo {
var $foo;
var $bar;
function foo() {
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
Added:
> >
$foo = new foo();
$name = 'MonNom';
Changed:
< <
Appel de fonction sur un objet
> >
echo <<foo.
Maintenant, j'affiche un {$foo->bar[1]}.
Ceci se traduit par un 'A' majuscule : \x41
EOT;
?>
Deleted:
< <
PHP 5.3 ajoute la possibilité d’utiliser la syntaxe d’un appel de fonction sur un objet, en lui appliquant l’opérateur ().
Changed:
< <
Pour cela, une nouvelle méthode magique a été ajoutée : __invoke :
> >
Changed:
< <
lors d’un appel de fonction sur une instance de classe comportant une méthode __invoke, c’est cette méthode qui sera appelée.
> >
Changed:
< <
Voici une classe d’exemple :
> >
Fonctions anonymes (exemples d'algo de tri et de somme)
Changed:
< <
class MyString {
public $str;
public function __construct($a) {
$this->str = $a;
}
> >
<?php
Changed:
< <
// Appelée quand on appelle dynamiquement un
// objet instance de cette classe
public function __invoke($a) {
var_dump(METHOD);
$this->str = $a;
}
}
Sur linux : session.save_path = "/var/lib/php/session" (/etc/php.ini)
Changed:
< <
La façon la plus sécurisée est d'utiliser les cookies
> >
Travail sur les chaînes
Changed:
< <
1) Le client (navigateur) demande un identifiant de session (jeton)
> >
- Supprimer une partie de la chaîne : str_replace()
Changed:
< <
2) Le serveur crée l'identifiant et le retourne au client
> >
- sous-chaîne : substr()
Changed:
< <
3) Le client stocke sur son disque dur cet identifiant sous la forme d'un cookie qu'il enverra désormais à chaque requête
> >
- tester la présence d'une sous-chaine dans la chaine (et récupérer sa position) : strpos()
Changed:
< <
Nom du jeton par défaut = PHPSESSID (cf php.ini session.name et fonction session_name())
> >
- parser une chaine de paramètres html, et les placer dans un tableau : parse_str($chaine, $args)
Changed:
< <
Sur le serveur, ce jeton aura le nom "sess_" suivi de sa valeur
> >
- remplacer une partie de la chaine : $bodytag = str_replace("%body%", "black", "");
Deleted:
< <
Valeur du jeton = string générée aléatoirement par php (fonction session_id() retourne cette valeur et permet éventuellement de la fixer, mais déconseilllé)
Changed:
< <
Paramètres php.ini à positionner (on peut utiliser session_set_cookie_params() pour cela, il y a aussi ini_get() et ini_set()) :
> >
Travail sur les arrays
Changed:
< <
session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0 (si cookies pas acceptés, ne pas pour autant transmettre l'id de session dans l'url)
session.cookie_lifetime = 0 (jusqu'au moment de quitter le navigateur)
session.auto_start = 0
session.save_handler = files
session.save_path = ...
> >
- merge : $GET = array_merge($GET,$args)
Changed:
< <
La fonction session_start() crée ou restaure une session (à mettre en première ligne du bootstrap)
Le contrôleur de Zend Framework réserve une action "index" comme action par défaut. C'est-à-dire que pour l'URI "http://localhost/tutoriel-zf/actualités/", l'action "index" est exécutée. Le framework réserve également un nom de contrôleur si aucun n'est fourni dans l'URI : aucune surprise qu'il soit également appelé "index". Ainsi, l'URI "http://localhost/tutoriel-zf/" appelle le contrôleur "index" avec l'action "index".
> >
top -n 1 -b -p affiche de l'information à propos d'un processus en désignant ce dernier par son PID.
Deleted:
< <
1) install
Changed:
< <
Download zf
> >
LINUX
Deleted:
< <
Copier dans D:\ProgFilesNoInstall\zf
Changed:
< <
Ajouter D:\ProgFilesNoInstall\zf\bin dans PATH windows
index.php : qui lance $application->bootstrap() et ->run()
> >
This tells me how many connections of different types of state I have on my machine.
I can run a similar command to see a complete picture of the state of all the connections made to my web server:
Your Bootstrap class defines what resources and components to initialize. By default, Zend Framework's Front Controller is initialized, and it uses the application/controllers/ as the default directory in which to look for action controllers
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
> >
Plus précisément :
Changed:
< <
4) Configuration
> >
Exact number of available cores, virtual or not (8 pour hyperion, soit 2 proc x 4 cores) : grep -c processor /proc/cpuinfo
Changed:
< <
While Zend Framework is itself configurationless, you often need to configure your application. The default configuration is placed in application/configs/application.ini, and contains some basic directives for setting your PHP environment (for instance, turning error reporting on and off), indicating the path to your bootstrap class (as well as its class name), and the path to your action controllers.
> >
Nb de processeurs "physiques" (2 pour hyperion) : grep core\ id /proc/cpuinfo | grep -c \ 0$
Changed:
< <
; application/configs/application.ini
> >
The following (clumsy) group of commands will return the number of physical CPUs regardless of if there is only a single core per CPU (2 pour planetoweb et surfasafe) :
First, when using INI-style configuration, you can reference constants directly and expand them; APPLICATION_PATH is actually a constant.
Changed:
< <
Additionally note that there are several sections defined: production, staging, testing, and development. The latter three inherit settings from the "production" environment. This is a useful way to organize configuration to ensure that appropriate settings are available in each stage of application development.
> >
CPU utilization
Changed:
< <
5) Action Controllers
> >
TOP : Informations sur la charge CPU et la consommation mémoire provoquée par les processus
Changed:
< <
Your application's action controllers contain your application workflow, and do the work of mapping your requests to the appropriate models and views.
An action controller should have one or more methods ending in "Action"; these methods may then be requested via the web. By default, Zend Framework URLs follow the schema /controller/action, where "controller" maps to the action controller name (minus the "Controller" suffix) and "action" maps to an action method (minus the "Action" suffix).
Typically, you always need an IndexController, which is a fallback controller and which also serves the home page of the site, and an ErrorController, which is used to indicate things such as HTTP 404 errors (controller or action not found) and HTTP 500 errors (application errors).
> >
La commande top classe tous les processus par leur consommation de la CPU et de la mémoire.
public function errorAction()
{
$errors = $this->_getParam('error_handler');
> >
mpstat -P ALL
Changed:
< <
switch ($errors->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
> >
You can display today’s CPU activity, with sar
Changed:
< <
// 404 error -- controller or action not found
$this->getResponse()->setHttpResponseCode(404);
$this->view->message = 'Page not found';
break;
default:
// application error
$this->getResponse()->setHttpResponseCode(500);
$this->view->message = 'Application error';
break;
}
For example display comparison of CPU utilization; 2 seconds apart; 5 times, use:
Changed:
< <
You'll note that the IndexController contains no real code, and the ErrorController makes reference to a "view" property. That leads nicely into our next subject.
> >
# sar -u 2 5
Added:
> >
(for each 2 seconds. 5 lines are displayed)
Changed:
< <
6) Views
> >
To get multiple samples and multiple reports, set an output file for the sar command. Run the sar command as a background process using.
Changed:
< <
Views in Zend Framework are written in plain old PHP. View scripts are placed in application/views/scripts/, where they are further categorized using the controller names. In our case, we have an IndexController and an ErrorController, and thus we have corresponding index/ and error/ subdirectories within our view scripts directory. Within these subdirectories, you will then find and create view scripts that correspond to each controller action exposed; in the default case, we thus have the view scripts index/index.phtml and error/error.phtml.
> >
# sar -o output.file 12 8 >/dev/null 2>&1 &
Changed:
< <
View scripts may contain any markup you want, and use the closing tag to insert PHP directives.
> >
Better use nohup command so that you can logout and check back report later on:
ps command displays every process (-e) with a user-defined format (-o pcpu). First field is pcpu (cpu utilization). It is sorted in reverse order to display top 10 CPU eating process.
Changed:
< <
env): ?>
> >
iostat :
Changed:
< <
Exception information:
Message: exception->getMessage() ?>
> >
It can be use to find out your system's average CPU utilization since the last reboot.
Changed:
< <
Stack trace:
exception->getTraceAsString() ?>
> >
$ iostat
Changed:
< <
Request Parameters:
request->getParams(), 1) ?>
> >
This gives you three outputs every 5 seconds (as previous command gives information since the last reboot):
Changed:
< <
> >
$ iostat -xtc 5 3
Added:
> >
gnome-system-monitor : allows you to view and control the processes
There are several things to note. First, note that the DocumentRoot setting specifies the public subdirectory of our project; this means that only files under that directory can ever be served directly by the server. Second, note the AllowOverride, Order, and Allow directives; these are to allow us to use htacess files within our project. During development, this is a good practice, as it prevents the need to constantly restart the web server as you make changes to your site directives; however, in production, you should likely push the content of your htaccess file into your server configuration and disable this. Third, note the SetEnv directive. What we are doing here is setting an environment variable for your virtual host; this variable will be picked up in the index.php and used to set the APPLICATION_ENV constant for our Zend Framework application. In production, you can omit this directive (in which case it will default to the value "production") or set it explicitly to "production".
Finally, you will need to add an entry in your hosts file corresponding to the value you place in your ServerName directive. On *nix-like systems, this is usually /etc/hosts; on Windows, you'll typically find it in C:\WINDOWS\system32\drivers\etc. Regardless of the system, the entry will look like the following:
soit, mieux, dans le fichier index.php du dossier "public/" du projet : chercher la ligne "set_include_path" et insérer en tête de liste, ce qui donne :
> >
This account is restricted by rssh.
Allowed commands: scp sftp rsync
Changed:
< <
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
> >
If you believe this is in error, please contact your system administrator.
1) le plus simple, méthode manuelle (depuis mon pc)
Changed:
< <
To get started using Zend_Layout, first we need to inform our bootstrap to use the Layout resource. This can be done using the zf enable layout command:
> >
ssh GATEWAY (entrer le mot de passe utilisé pour le mail)
Changed:
< <
% zf enable layout
Layouts have been enabled, and a default layout created at
application/layouts/scripts/layout.phtml
A layout entry has been added to the application config file.
> >
puis
Changed:
< <
As noted by the command, application/configs/application.ini is updated, and now contains the following within the production section:
> >
ssh hyperion.cesr.fr (entrer votre mot de passe hyperion)
Changed:
< <
; application/configs/application.ini
> >
(NB : "ssh -X GATEWAY", puis "ssh -X hyperion" si on veut l'affichage graphique)
Changed:
< <
; Add to [production] section:
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
> >
Il faut taper 2 fois "exit" pour revenir à mon pc.
Deleted:
< <
We also want to ensure we have an XHTML DocType declaration for our application. To enable this, we need to add a resource to our bootstrap.
Changed:
< <
The simplest way to add a bootstrap resource is to simply create a protected method beginning with the phrase _init. In this case, we want to initialize the doctype, so we'll create an _initDoctype() method within our bootstrap class.
> >
2) Pour accélérer la connexion : ETAPE 1, générer des clés ssh
Changed:
< <
Within that method, we need to hint to the view to use the appropriate doctype. But where will the view object come from? The easy solution is to initialize the View resource; once we have, we can pull the view object from the bootstrap and use it.
> >
DEPUIS MON PC, je génère une paire de clés privée et publique :
Changed:
< <
To initialize the view resource, add the following line to your application/configs/application.ini file, in the section marked production:
> >
ssh-keygen -t dsa
Changed:
< <
resources.view[] =
> >
Puis, je distribue ensuite la clé publique à la fois sur GATEWAY ET sur hyperion :
Changed:
< <
This tells us to initialize the view with no options (the '[]' indicates that the "view" key is an array, and we pass nothing to it).
Now that we have a view, let's flesh out our _initDoctype() method. In it, we will first ensure the View resource has run, fetch the view object, and then configure it:
Malheureusement, il faut encore entrer un mot de passe pour se connecter à hyperion, bouh...
Changed:
< <
> >
(je tape 2 fois "exit" pour revenir à mon pc)
Deleted:
< <
We grab our application content using the layout() view helper, and accessing the "content" key. You may render to other response segments if you wish to, but in most cases, this is all that's necessary.
Changed:
< <
Note also the use of the headLink() placeholder. This is an easy way to generate the HTML for elements, as well as to keep track of them throughout your application. If you need to add additional CSS sheets to support a single action, you can do so, and be assured it will be present in the final rendered page.
> >
3) Pour accélérer la connexion : ETAPE 2, automatiser le "rebond" par GATEWAY
Added:
> >
On va maintenant rendre transparent le passage via GATEWAY. Il suffit pour cela de créer un fichier de config :
Changed:
< <
9) Create a Model and Database Table
> >
DEPUIS MON PC, j'édite le fichier /home/USERNAME/.ssh/config, et j'y mets le contenu suivant :
Your application bootstrap will by default use the module prefix "Application". As such, our models, forms, and table classes will all begin with the class prefix "Application_".
On n'a plus besoin de rentrer aucun mot de passe (ni de GATEWAY, ni de hyperion), c'est direct !
Changed:
< <
zf create controller Guestbook
> >
(il suffit de taper une seule fois "exit" pour revenir à mon pc)
Deleted:
< <
This will create a new controller, GuestbookController, in application/controllers/GuestbookController.php, with a single action method, indexAction(). It will also create a view script directory for the controller, application/views/scripts/guestbook/, with a view script for the index action.
Changed:
< <
We'll use the "index" action as a landing page to view all guestbook entries.
> >
SED (substitution de texte)
Changed:
< <
Now, let's flesh out the basic application logic. On a hit to indexAction(), we'll display all guestbook entries. This would look like the following:
remplacer tutu par toto, mais seulement des lignes 3 à 6 :
Changed:
< <
class GuestbookController extends Zend_Controller_Action
{
public function indexAction()
{
$guestbook = new Application_Model_GuestbookMapper();
$this->view->entries = $guestbook->fetchAll();
}
}
> >
cat monfichier.txt | sed -e 3,6"s/tutu/toto/" >| monfichiertemp.txt
Added:
> >
remplacer tutu par toto, mais seulement entre les lignes "titi" et "toto" :
Changed:
< <
And, of course, we need a view script to go along with that. Edit application/views/scripts/guestbook/index.phtml to read as follows:
N'afficher que les lignes utiles (tout sauf commentaires et lignes vides) :
Changed:
< <
Next, we will add a signAction() to our GuestbookController which will process the form upon submission. To create the action and related view script, execute the following:
> >
egrep -v '^(#|$)' fichier
Deleted:
< <
% zf create action sign Guestbook
Changed:
< <
Now browse to "http://localhost/guestbook/sign".
> >
RSYNC
Added:
> >
Sauvegarder (de façon incrémentielle) des répertoires du poste A vers le poste B :
Le fichier standard php.ini a été réorganisé, et renommé :
> >
option -v = verbose
Changed:
< <
php.ini-development contient les options qui sont recommandées pour un environnement de développement.
php.ini-production contient les configurations recommandées pour la production.
> >
attention aux slashes '/' :
Changed:
< <
On les trouve dans /usr/share/doc/php-common-5.3.3
> >
/rep/rep1 écrit un répertoire rep1 sur B
Changed:
< <
Voici la différence entre les 2 :
> >
/rep/rep1/ écrit directement le contenu du répertoire rep1 sur B
Changed:
< <
[root@planetoweb etc]# diff /usr/share/doc/php-common-5.3.3/php.ini-development /usr/share/doc/php-common-5.3.3/php.ini-production
514c514
< error_reporting = E_ALL | E_STRICT
---
> error_reporting = E_ALL & ~E_DEPRECATED
531c531
< display_errors = On
---
> display_errors = Off
542c542
< display_startup_errors = On
---
> display_startup_errors = Off
586c586
< track_errors = On
---
> track_errors = Off
604c604
< html_errors = On
---
> html_errors = Off
1248a1249,1256
> ; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
> ; http://php.net/mysqli.allow_local_infile
> ;mysqli.allow_local_infile = On
>
> ; Allow or prevent persistent links.
> ; http://php.net/mysqli.allow-persistent
> mysqli.allow_persistent = On
>
1297c1305
< mysqlnd.collect_memory_statistics = On
---
> mysqlnd.collect_memory_statistics = Off
1566c1574
< session.bug_compat_42 = On
---
> session.bug_compat_42 = Off
1575c1583
< session.bug_compat_warn = On
---
> session.bug_compat_warn = Off
1593d1600
< session.entropy_file =
> >
2) ... ou Depuis B
Changed:
< <
> >
rsync -avz A:/rep/rep1 A:/rep/rep2 ./rep
Deleted:
< <
HereDoc
Added:
> >
FIND
Changed:
< <
La syntaxe Heredoc se comporte exactement comme une chaîne à guillemets doubles, sans les guillemets doubles. Cela signifie que vous n'avez pas à échapper les guillemets (simples ou doubles) dans cette syntaxe. Les variables sont remplacées par leur valeur et le même soin doit leur être apporté que dans les chaînes à guillemets doubles.
Exemple de chaîne HereDoc
> >
Chercher le fichier "foo" sur tout le disque :
Changed:
< <
> >
find / -name foo
Changed:
< <
<?php
$str = <<<EOD
Exemple de chaîne
s'étalant sur
plusieurs lignes
avec la syntaxe heredoc
EOD;
> >
(si on n'est pas root, on voit plein de messages d'erreur, donc pour éviter ça :
Changed:
< <
/* Exemple plus complexe, avec des variables. */
class foo {
var $foo;
var $bar;
function foo() {
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
> >
find / -name foo 2>/dev/null
Deleted:
< <
$foo = new foo();
$name = 'MonNom';
Changed:
< <
echo <<foo.
Maintenant, j'affiche un {$foo->bar[1]}.
Ceci se traduit par un 'A' majuscule : \x41
EOT;
?>
> >
Supprimer tous les répertoires CVS/ dans toute une arborescence (à partir du répertoire courant) :
- parser une chaine de paramètres html, et les placer dans un tableau : parse_str($chaine, $args)
> >
Par exemple, je veux forwarder mes mails de pallier@planetoweb.cesr.fr vers ma boite LABO ou encore ma boite perso :
Changed:
< <
- remplacer une partie de la chaine : $bodytag = str_replace("%body%", "black", "");
> >
cd ~
Added:
> >
créer un fichier ".forward" contenant mon adresse LABO ou perso
Changed:
< <
Travail sur les arrays
> >
S'il s'agit de forwarder les mails adressés à root@planetoweb.cesr.fr, on peut utiliser la même solution, mais on peut aussi
ajouter cette ligne tout à la fin du fichier /etc/aliases
export PRINTER=sprinter (mettre le nom de votre imprimante à la place de "sprinter")
Changed:
< <
Voir les connexions au port 8080 sur mon pc :
> >
Pour imprimer du texte, on peut utiliser les utilitaires "a2ps" ou "enscript"
Deleted:
< <
$> netstat -ant|grep 8080
Changed:
< <
tcp4 0 0 195.83.102.52.54533 195.83.102.176.8080 ESTABLISHED
tcp6 0 0 ::1.8080 ::1.53481 ESTABLISHED
tcp6 0 0 ::1.53481 ::1.8080 ESTABLISHED
tcp6 0 0 ::1.8080 ::1.50287 ESTABLISHED
tcp6 0 0 ::1.50287 ::1.8080 ESTABLISHED
tcp46 0 0 .8080 *. LISTEN
> >
Visualiser des images (jpeg, ps, ...) en mode console
display
Changed:
< <
Je vois ainsi que ma machine est connectée à 195.83.102.176 via le port 8080 en TCP
> >
Note : display permet aussi de convertir une image d'un format vers un autre (enregistrer sous...)
Changed:
< <
Pour savoir qui c'est, j'utilise la commande "host" ou "nslookup" :
> >
Voir aussi "xv" et "gthumb"
Deleted:
< <
$> host 195.83.102.176
Changed:
< <
Idem pour mysql :
> >
Convertir une image d'un format vers un autre
Changed:
< <
$> netstat -ant | grep 3306
> >
PS to PDF : ps2pdf
Changed:
< <
This tells me how many connections of different types of state I have on my machine.
I can run a similar command to see a complete picture of the state of all the connections made to my web server:
Exact number of available cores, virtual or not (8 pour hyperion, soit 2 proc x 4 cores) : grep -c processor /proc/cpuinfo
Changed:
< <
Nb de processeurs "physiques" (2 pour hyperion) : grep core\ id /proc/cpuinfo | grep -c \ 0$
> >
IPTABLES (FIREWALL)
Changed:
< <
The following (clumsy) group of commands will return the number of physical CPUs regardless of if there is only a single core per CPU (2 pour planetoweb et surfasafe) :
Exceptionnellement, sur un projet avec différents groupes (mais uniquement si nécessaire car ralentit les accès svn et alourdit la gestion) :
Changed:
< <
Better use nohup command so that you can logout and check back report later on:
> >
- ACL : contrôle d'accès basé sur les chemins :
(grâce au module authz_svn_module et à la directive AuthzSVNAccessFile), pour pouvoir réserver certains répertoires à certains groupes...
Deleted:
< <
# nohup sar -o output.file 12 8 >/dev/null 2>&1 &
Changed:
< <
puis pour lire : sar -f output.file
> >
Exemple de config (chemcam) authentifiée mais SANS ACL :
Changed:
< <
%user = % temps cpu utilisé par les applications
> >
Changed:
< <
%system = % temps cpu utilisé par le kernel
> >
DAV svn
Changed:
< <
%iowait = % temps cpu utilisé à attendre une requête I/O
> >
ErrorDocument 404 default
# Only 1 repository :
SVNPath /home/projects/chemcam/svn
# Many repositories :
# any "/svn/foo" URL will map to a repository /home/svn/foo
#SVNParentPath /home/svn
#SVNListParentPath on
Added:
> >
# Desactiver completement les controles sur les chemins (par defaut = on)
SVNPathAuthz off
Changed:
< <
displays the top 10 CPU users :
> >
# For any operations other than these (GET, PROFIND...), require an authenticated user
#
Require valid-user
#
ps command displays every process (-e) with a user-defined format (-o pcpu). First field is pcpu (cpu utilization). It is sorted in reverse order to display top 10 CPU eating process.
> >
# For any operations other than these, require an authenticated user (this would allow anybody to READ without authentication)
Changed:
< <
iostat :
> >
# Custom log file and format :
LogFormat "%t %u %h %{SVN-ACTION}e" svn
CustomLog logs/journal-svn.log svn env=SVN-ACTION
Changed:
< <
It can be use to find out your system's average CPU utilization since the last reboot.
> >
Deleted:
< <
$ iostat
Changed:
< <
This gives you three outputs every 5 seconds (as previous command gives information since the last reboot):
> >
Exemple de config (chemcam) authentifiée et AVEC ACL :
DAV svn
ErrorDocument 404 default
# Only 1 repository :
SVNPath /home/projects/chemcam/svn
# Many repositories :
# any "/svn/foo" URL will map to a repository /home/svn/foo
#SVNParentPath /home/svn
#SVNListParentPath on
Changed:
< <
$ iostat -xtc 5 3
> >
# Desactiver completement les controles sur les chemins (par defaut = on)
SVNPathAuthz on
Changed:
< <
gnome-system-monitor : allows you to view and control the processes
> >
# ACL
# politique de controle d'acces (uses apache module mod_authz_svn)
AuthzSVNAccessFile /chemin/vers/fichier/police_acces_svn
[groups]
# Virtual Machine only group :
cc-vm = user1, user20, user7
# Privileged access group :
cc-privileged = user3, user2, user6, user8, user30
Changed:
< <
depuis planetoweb:
> >
[/]
# cc-privileged group has total access to the project (and no one else)
@cc-privileged = rw
# access given to ALL users !!!
#* = rw
Changed:
< <
# ssh surfasafe "ls -l"
> >
[/trunk/vm]
# cc-vm group has read only access to the /vm dir (and no other dir)
@cc-vm = r
# cc-vm group has no access at all to the /vm dir
#@cc-vm =
LVM can be used to effectively manage storage to make expansion, snapshots, and other aspects of storage fairly easy.
Changed:
< <
This account is restricted by rssh.
> >
LVM allows you to abstract various pieces of physical storage into groups that can be carved into chunks that form the basis of file systems (virtual partitions if you like). It also allows you to combine physical partitions into groups, resize these groups (grow or shrink), and effectively manage these groups.
Changed:
< <
Allowed commands: scp sftp rsync
> >
1) h physical hd découpés chacun en p physical partitions (PP) (pas forcément le même nb de partitions pour chaque hd)
Changed:
< <
If you believe this is in error, please contact your system administrator.
> >
ex : sda découpé en /dev/sda1, /dev/sda2 et sdb découpé en /dev/sdb1, /dev/sdb2, /dev/sdb3
Added:
> >
2) mapping identité entre les partitions physiques (PP) et virtuelles (PV) : 1 PV = 1 PP
Changed:
< <
Simplifier une connexion ssh avec rebond
> >
Make sure the partition type for the physical volumes is correct. The partition type should be “8e”.
Changed:
< <
Par exemple, depuis chez moi, je veux me connecter à hyperion
> >
# fdisk -l /dev/sdb
Changed:
< <
Il me faut donc passer par GATEWAY (la passerelle du labo)
> >
Disk /dev/sdb: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Changed:
< <
1) le plus simple, méthode manuelle (depuis mon pc)
> >
Device Boot Start End Blocks Id System
/dev/sdb1 1 30400 244187968+ 8e Linux LVM
/dev/sdb2 30401 60801 244196032+ 8e Linux LVM
Changed:
< <
ssh GATEWAY (entrer le mot de passe utilisé pour le mail)
> >
# pvcreate /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Physical volume "/dev/sdb1" successfully created
Physical volume "/dev/sdb2" successfully created
Physical volume "/dev/sdc1" successfully created
Physical volume "/dev/sdc2" successfully created
Changed:
< <
puis
> >
# pvdisplay
"/dev/sdb1" is a new physical volume of "232.88 GB"
--- NEW Physical volume ---
PV Name /dev/sdb1
VG Name
PV Size 232.88 GB
Allocatable NO
PE Size (KByte) 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID j4XKT6-OI2y-cPMK-YpNR-gmgc-es67-ey4CV2
Changed:
< <
ssh hyperion.cesr.fr (entrer votre mot de passe hyperion)
> >
"/dev/sdb2" is a new physical volume of "232.88 GB"
--- NEW Physical volume ---
...
Changed:
< <
(NB : "ssh -X GATEWAY", puis "ssh -X hyperion" si on veut l'affichage graphique)
> >
Notice that each PV is given a PV UUID
Changed:
< <
Il faut taper 2 fois "exit" pour revenir à mon pc.
> >
3) Les PV sont regroupés en 1 à n volume group (VG) (a VG can be seen as a "virtual hd")
Added:
> >
ex : le VG primary_vg regroupera /dev/sda1, /dev/sda2 , /dev/sdb1, et /dev/sdb3
Changed:
< <
2) Pour accélérer la connexion : ETAPE 1, générer des clés ssh
> >
# vgcreate primary_vg /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Volume group "primary_vg" successfully created
Changed:
< <
DEPUIS MON PC, je génère une paire de clés privée et publique :
> >
# vgdisplay
--- Volume group ---
VG Name primary_vg
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 4
Act PV 4
VG Size 931.52 GB
PE Size 4.00 MB
Total PE 238468
Alloc PE / Size 0 / 0
Free PE / Size 238468 / 931.52 GB
VG UUID oNH6jk-PBE0-mR0c-aaDi-3Fys-y5SQ-0tVaxX
Changed:
< <
ssh-keygen -t dsa
> >
If you don't happen to remember the name of a VG or you happen upon a new system to administer, then you can use a command called "vgscan" that will tell what VG's are on the system.
Changed:
< <
Puis, je distribue ensuite la clé publique à la fois sur GATEWAY ET sur hyperion :
> >
# vgscan
Reading all physical volumes. This may take a while...
Found volume group "primary_vg" using metadata type lvm2
DEPUIS MON PC, j'édite le fichier /home/USERNAME/.ssh/config, et j'y mets le contenu suivant :
> >
For example, if the file system says it has 29G used (29 GB), then you should snapshot a little larger – perhaps 30-32 GB (always good to have a cushion). This cushion isn’t strictly necessary, but a little safety never hurts...
ssh hyp (avec l'option -X pour l'affichage graphique)
> >
Vous pouvez faire vos tests sur des fichiers ou des clefs USB pour commencer...
Remplacez simplement le "device" par un fichier existant. Ex : /dev/sdX par /home/moi/raid-test/disque-1.img.
Changed:
< <
(ou "ssh hyperion" ou "ssh hyperion.cesr.fr")
> >
Pour créer un fichier quelque part avec la bonne taille : dd if=/dev/zero of=/home/moi/raid-test/disque-1.img count=10000 bs=65535.
Pour en savoir plus : man dd.
Changed:
< <
On n'a plus besoin de rentrer aucun mot de passe (ni de GATEWAY, ni de hyperion), c'est direct !
> >
Apres on fait un : mdadm --create /dev/md0 --level=1 --raid-devices=/home/moi/raid-test/disque-1.img,/home/moi/raid-test/disque-2.img
Changed:
< <
(il suffit de taper une seule fois "exit" pour revenir à mon pc)
> >
Et voila un RAID 1 créé avec deux fichiers stockés sur le disque dur.
Added:
> >
J'ai testé le Raid0 sur 2DD externes de 2,5" en USB, et j'arrive à 45Mo sec avec mon portable...
Changed:
< <
SED (substitution de texte)
> >
Avant de mettre un raid sur une machine en production VERIFIEZ les noms des disques et des partitions !!! Préférez les /dev/disk/by-id, vous ferez moins facilement des erreurs qu'en mettant seulement /dev/sde, surtout si vous ajoutez des disques par la suite...
L'outil magique de management du RAID sous Linux : mdadm
Changed:
< <
remplacer tutu par toto, mais seulement des lignes 3 à 6 :
> >
Quelques exemples : (vous noterez que l'on utilise la syntaxe /dev/sdX alors que c'est mal.. mais c'est plus lisible que /dev/disk/by-id/ata-ST3250310AS_6RY7R988-part1)
Changed:
< <
cat monfichier.txt | sed -e 3,6"s/tutu/toto/" >| monfichiertemp.txt
> >
création d'une pile raid :
Changed:
< <
remplacer tutu par toto, mais seulement entre les lignes "titi" et "toto" :
crée un device /dev/mdX (X étant un chiffre) de niveau (--level) 0 (stripping), 1 (mirroring), 4 (comme le 5 mais la parité est toujours sur le même disque), 5 ou 6 (2 disques de parité) à partir des devices /dev/sdYZ (Y est une lettre indiquant un disque physique , Z un chiffre indicant un numéro de partition).
On peut également mettre missing dans la liste des devices. C'est très utile lorsque l'on passe son système sur un raid 1
Changed:
< <
ou encore :
> >
Mise en échec d'un disque (pour test par ex.) :
mdadm --manage /dev/mdX --failed /dev/sdYZ
Changed:
< <
sed -e "/$debut/,/$fin/"'s#HostId="t3://.*\n#HostId="t3://'"$WLS_ADM_HOST:$PORT\"/" < "$file1" > "$file2"
> >
"Ejection" d'un disque d'une pile :
mdadm --manage /dev/mdX --remove /dev/sdYZ
Added:
> >
Ajout d'un disque à une pile :
mdadm --manage /dev/mdX --add /dev/sdYZ
Changed:
< <
GREP (recherche textuelle)
> >
Liste des périphériques d'une pile :
mdadm --misc --detail /dev/mdX
Changed:
< <
Afficher uniquement les lignes de commentaire:
> >
On peux aussi faire :
Changed:
< <
egrep '^#' fichier
> >
cat /proc/mdstat
Deleted:
< <
Ne pas afficher les lignes de commentaire:
Changed:
< <
egrep -v '^#' fichier
> >
Agrandir une partition
Changed:
< <
N'afficher que les lignes utiles (tout sauf commentaires et lignes vides) :
> >
La première étape consiste à repérer quel device correspond aux partitions que tu veux redimensionner. Pour cela tu peux utiliser la commande :
Sauvegarder (de façon incrémentielle) des répertoires du poste A vers le poste B :
> >
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
Affecter des droits spécifiques à certains éléments d'un répertoire (tout le contenu, y-compris sous-dossiers) :
> >
The basic command is structured as follows:
Changed:
< <
dossiers:
> >
dd if= of= bs=(usually some power of 2, not less than 512 bytes(ie, 512, 1024, 2048, 4096, 8192, 16384, but can be any number.) skip= seek= conv=.
Changed:
< <
find /home/jsmith/awstats/ -type d | xargs chmod 0755
> >
Source is the data being read. Target is where the data gets written. If you mess up, and accidentally reverse the source and target, you can wipe out a lot of data.
Changed:
< <
fichiers:
> >
(http://www.efense.com/helix is a good boot cd : The helix boot environment contains the DoD version of dd called dcfldd. It works the same way, but is has a progress bar)
Deleted:
< <
find /home/jsmith/awstats/ -type f | xargs chmod 0644
Changed:
< <
fichiers perl:
> >
Using dd you can create backups of an entire harddisk or just a parts of it. This is also usefull to quickly copy installations to similar machines. It will only work on disks that are exactly the same in disk geometry, meaning they have to the same model from the same brand.
Changed:
< <
find /home/jsmith/awstats/ -type f -name *.pl | xargs chmod 0755
Par exemple, je veux forwarder mes mails de pallier@planetoweb.cesr.fr vers ma boite LABO ou encore ma boite perso :
> >
gzip -dc /path/to/image.gz | dd of=/dev/hdx
Changed:
< <
cd ~
> >
MBR backup
Changed:
< <
créer un fichier ".forward" contenant mon adresse LABO ou perso
> >
In order to backup only the first few bytes containing the MBR and the partition table you can use dd as well.
Changed:
< <
S'il s'agit de forwarder les mails adressés à root@planetoweb.cesr.fr, on peut utiliser la même solution, mais on peut aussi
ajouter cette ligne tout à la fin du fichier /etc/aliases
rechercher "mot" dans les fichiers idl du répertoire courant
> >
sda2, sdb2 are partitions. You want to copy sda2 to sdb2. If sdb2 doesn't exist, dd will start at the beginning of the disk, and create it. Be careful with order of if and of. You can write a blank disk to a good disk if you get confused.
Changed:
< <
grep "mot" *.pro
> >
Make an iso image of a CD:
Changed:
< <
rechercher "mot" dans tous les fichiers du répertoire courant
CD sectors are 2048 bytes, so this copies sector for sector. The result will be a hard disk image file of the CD. You can use "chmod a+rwx mycd.iso" to make the image writable. You can mount the image with "mkdir /mnt/mycd", this line in fstab: "/home/sam/mycd.iso /mnt/mycd iso9660 rw,user,noauto 0 0", save fstab, "mount -o loop /mnt/mycd". Then the file system will be viewable as files and directories in the directory /mnt/mycd. You can edit the image as you wish, and the new file will be "/home/sam/mycd.iso" dd does not write to CD's. You need to use a burning utility, or the cdrdao command
Changed:
< <
L'option "-i" permet de ne pas tenir compte de la casse
> >
Cloning an entire hard disk:
Changed:
< <
rechercher "mot" dans tous les fichiers du répertoire courant ainsi que dans tous les sous-rep (récursif) :
> >
dd if=/dev/sda of=/dev/sdb conv=notrunc,noerror
Changed:
< <
grep -r -i "mot" .
> >
In this example, sda is the source. sdb is the target. Do not reverse the intended source and target. Surprisingly many people do. notrunc means to not truncate. noerror means to keep going if there is an error. Normally dd stops at any error. if you have a question about a hard drive on whether or not it works, you can try to use it as the source drive for the dd command. You should get an error if it is not working. target drives need to be really messed up to give an error in dd.
Added:
> >
Copy MBR only of a hard drive:
Changed:
< <
Faire une action sur un ensemble de dossiers et fichiers
Depuis répertoire courant, supprimer tous les dossiers "CVS" (récursivement) :
> >
this will copy the first 446 bytes of the hard drive to a file. If you haven't already guessed, reversing the objects of if and of, in the dd command line reverses the direction of the write.
Changed:
< <
find . -name CVS -exec rm -rf {} \;
> >
Back up your MBR
Added:
> >
dd if=/dev/sda of=mbr.bin count=1
Changed:
< <
Créer un alias
> >
Put this on a floppy you make with
Changed:
< <
Exemple : quand on tape "l" ça fera "ls -l"
> >
dd if=boot.img of=/dev/fd0
Changed:
< <
alias l="ls -l"
> >
Along with dd. Boot from the floppy and
Changed:
< <
Cette ligne doit être placée dans votre ~/.bashrc
> >
dd if=mbr.bin of=/dev/sda count=1
Changed:
< <
Configurer mon environnement
> >
Will restore the MBR
Changed:
< <
Pour les configurations perso, les placer dans son ~/.bash_profile (ce script appelle ~/.bashrc qui doit contenir les alias et fonctions)
> >
Copy a disk partition to a file on a different partition (Do not copy a partition to the same partition)
Changed:
< <
Mettre les configurations générales dans /etc/profile.d/profile_etienne.sh (elles seront ainsi valables pour TOUS les users du serveur)
Pour installer l'imprimante "sprinter", voir SprinterPrinter
> >
This way you can get a bazonga hard drive and partition it so you can back up your root partition. If you mess up your root partition, you just boot from the helix cd and restore the image.
Deleted:
< <
Pour faire de cette imprimante l'imprimante par défaut, ajouter cette ligne dans votre ~/.bash_profile :
Deleted:
< <
export PRINTER=sprinter (mettre le nom de votre imprimante à la place de "sprinter")
Changed:
< <
Pour imprimer du texte, on peut utiliser les utilitaires "a2ps" ou "enscript"
> >
Copie de disque ou partition (image "ghost") avec partimage (SystemRescueCd)
Added:
> >
J'ai un disque qui montre des faiblesses
Changed:
< <
Visualiser des images (jpeg, ps, ...) en mode console
display
> >
Je veux le remplacer par un nouveau disque
Changed:
< <
Note : display permet aussi de convertir une image d'un format vers un autre (enregistrer sous...)
> >
Je dois donc faire une image du disque et la copier ensuite sur le nouveau disque
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
Disque /dev/md0 ne contient pas une table de partition valide
Deleted:
< <
3) /etc/init.d/iptables restart
Changed:
< <
4) /etc/init.d/iptables save
> >
# fdisk /dev/sda
...
Changed:
< <
5) /etc/init.d/iptables status (vérifier que les nouvelles règles apparaissent bien)
> >
Commande (m pour l'aide): p
Added:
> >
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
La virtualisation consiste à faire cohabiter plusieurs (VM) machines "virtuelles" (OS) sur une même machine physique
Changed:
< <
Voir l'exemple de la configuration pour chemcam : /etc/httpd/conf.d/vhosts/chemcam.conf (planetoweb)
> >
Prérequis :
Changed:
< <
Besoins à considérer avant de mettre en place une solution svn :
> >
Les processeurs doivent être virtualisables (cpuinfo doit contenir le flag vmx pour un processeur intel, et svm pour AMD) : egrep '(vmx|svm)' /proc/cpuinfo
Changed:
< <
- accès via apache (et non pas seulement en svnserve) pour assurer un accès depuis l'extérieur et qui passe les firewall
3 disques raid5 avec un LVM dessus pour stocker les images disques des VM
Deleted:
< <
Exceptionnellement, sur un projet avec différents groupes (mais uniquement si nécessaire car ralentit les accès svn et alourdit la gestion) :
Changed:
< <
- ACL : contrôle d'accès basé sur les chemins :
(grâce au module authz_svn_module et à la directive AuthzSVNAccessFile), pour pouvoir réserver certains répertoires à certains groupes...
> >
Serveur de gestion de versions (de code source) SUBVERSION
ErrorDocument 404 default
# Only 1 repository :
SVNPath /home/projects/chemcam/svn
# Many repositories :
# any "/svn/foo" URL will map to a repository /home/svn/foo
#SVNParentPath /home/svn
#SVNListParentPath on
# Desactiver completement les controles sur les chemins (par defaut = on)
SVNPathAuthz off
> >
Le serveur X tourne localement sur mon pc (win ou lin), c'est à dire le pc avec un écran (output), un clavier et une souris (inputs).
Changed:
< <
# For any operations other than these (GET, PROFIND...), require an authenticated user
#
Require valid-user
#
> >
Il se connecte à un display manager (xdm ou gdm ou kdm...) qui peut être local ou distant (sur un autre pc) :
Si le DM est local, il démarre un ou plusieurs serveurs X, affiche l'écran de connexion (login) au démarrage et chaque fois qu'un user se délogge.
Si le DM est distant, il est utilisé via le protocole XDMCP : un user lance des programmes depuis le pc distant (qui exécute le DM) alors que ses input/output se passent sur son pc local.
Ainsi, le serveur X (local) communique avec différents clients graphiques (qui peuvent être distants) à qui il envoit les inputs et de qui il reçoit les outputs.
Changed:
< <
# For any operations other than these, require an authenticated user (this would allow anybody to READ without authentication)
> >
Pour CentOS, le DM par défaut est sélectionné dans /etc/X11/prefdm (qui regarde si un DM par défaut est donné dans /etc/sysconfig/desktop)
Changed:
< <
# Custom log file and format :
LogFormat "%t %u %h %{SVN-ACTION}e" svn
CustomLog logs/journal-svn.log svn env=SVN-ACTION
> >
C'est le fichier /etc/X11/xinit/Xsession qui exécute notre environnement.
Changed:
< <
> >
xdm : voir /etc/X11/
Added:
> >
kdm : voir /etc/kdm/
Changed:
< <
Exemple de config (chemcam) authentifiée et AVEC ACL :
> >
gdm : voir /etc/gdm/ Il devrait s'y trouver un gdm.conf
Changed:
< <
> >
gdm appelle /etc/X11/xinit/Xsession avec les bonnes options
ErrorDocument 404 default
# Only 1 repository :
SVNPath /home/projects/chemcam/svn
# Many repositories :
# any "/svn/foo" URL will map to a repository /home/svn/foo
#SVNParentPath /home/svn
#SVNListParentPath on
> >
Attention, X et XDMCP sont tous les 2 non sécurisés !!!
Changed:
< <
# Desactiver completement les controles sur les chemins (par defaut = on)
SVNPathAuthz on
> >
Vérifier /etc/resolv.conf
Changed:
< <
# ACL
# politique de controle d'acces (uses apache module mod_authz_svn)
AuthzSVNAccessFile /chemin/vers/fichier/police_acces_svn
> >
Vérifier /etc/init.d/xfs (font server)
Changed:
< <
# For any operations other than these (GET, PROFIND...), require an authenticated user
#
Require valid-user
#
> >
Vérifier que dans /etc/inittab, le default runlevel est bien 5 :
Format du fichier de police d'accès aux répertoires du projet svn (nommé police_acces_svn ci-dessus) :
> >
Log de X : /var/log/Xorg.0.log
Changed:
< <
> >
Config de X : /etc/X11/xorg.conf
Deleted:
< <
[groups]
# Virtual Machine only group :
cc-vm = user1, user20, user7
# Privileged access group :
cc-privileged = user3, user2, user6, user8, user30
Changed:
< <
[/]
# cc-privileged group has total access to the project (and no one else)
@cc-privileged = rw
# access given to ALL users !!!
#* = rw
> >
BOOT LINUX
Changed:
< <
[/trunk/vm]
# cc-vm group has read only access to the /vm dir (and no other dir)
@cc-vm = r
# cc-vm group has no access at all to the /vm dir
#@cc-vm =
> >
I - Le boot : tryptique noyau, arguments, et ramdisk
Synthèse du workflow :
bootloader ==> noyau + initramfs + arguments ==> montage de la racine
Changed:
< <
> >
1) Chargeur de boot (bootloader)
C'est le 1er prog à s'exécuter. Différent selon les architectures (pc x86, station Sun, Mac PPC...)
Rôle: mettre en RAM le noyau (kernel), lui passer des arguments, copier un ramdisk en RAM, et passer la main au noyau
Ex: lilo, grup, outils syslinux (bien adapté à partifion FAT, clé usb, cd)
Etapes :
- allumage électrique
- POST (Power On Self Test)
- BIOS (dans lequel le periph d'amorçage est défini)
- lancement bootloader installé sur periph amorcé
Ex: noyau grub, /boot/bzImage-2.6
Ex: ramdisk grub, /boot/initrd.img
Changed:
< <
LVM (Logical Volume Management)
> >
2) Le noyau
Rôle : monter la racine et lancer /sbin/init situé dessus
Au boot, le noyau décourvre son environnement (ram, cpu, disque...). Ces périph sont gérés par des pilotes (drivers), des "modules" qui sont compilés dans le noyau ou dans des fichiers externes (souvent dans /lib/modules/). Les fichiers modules sont situés sur une partition qui n'est pas encore montée, et donc les périph correspondants ne peuvent pas être utilisés.
Le noyau monte sa racine avec /bin/mount
ex: montage de /dev/sda1 en lecture seule avec sys de fichier ext4
$ mount -t ext4 -o ro /dev/sda1 /
Les arguments passés au noyau peuvent être relus après boot :
$ cat /proc/cmdline
On peut aussi passer l'argument "init=/bin/bash" pour accéder au système au démarrage avec un shell bash.
Rôle : permettre une détection plus intelligente de la racine ainsi qu'une facilité de configuration.
S'appelait initrd, mais est de plus en plus remplacé par initramfs
L'initramsf est un ensemble de fichiers qui vont être directement copiés dans le cache de système de fichiers sous la racine (tous les sys 2.6 utilisent un rootfs, cf "cat /proc/mounts"). Il doit au moins contenir un programme /init exécutable que le noyau va lancer pour qu'il trouve la racine et la monte. C'est un microsystème linux à part entière. Le prog /init est souvent un script shell, simple à lire.
Avec un initramfs, il devient possible de conserver un noyau minimal et de mettre les modules essentiels au boot dans l'initramfs (évite de devoir recompiler le noyau). Il contient aussi l'image qui permet un affichage graphique pendant le boot.
/init parse donc la ligne /proc/cmdline, cherche la racine, et la monte pour ensuite basculer le noyau dessus, et enfin s'autoremplace par le vrai binaire /sbin/init.
Changed:
< <
LVM can be used to effectively manage storage to make expansion, snapshots, and other aspects of storage fairly easy.
> >
II - init et inittab
Changed:
< <
LVM allows you to abstract various pieces of physical storage into groups that can be carved into chunks that form the basis of file systems (virtual partitions if you like). It also allows you to combine physical partitions into groups, resize these groups (grow or shrink), and effectively manage these groups.
> >
Arrivé à ce point, la noyau tourne, la racine de la distrib est montée (souvent en "ro") et le binaire /sbin/init est lancé, premier processus.
Changed:
< <
1) h physical hd découpés chacun en p physical partitions (PP) (pas forcément le même nb de partitions pour chaque hd)
> >
Si ce processus meurt (pid=1), le noyau fait un kernel panic. Il est aussi responsable de l'extinction de la machine.
Si on passe au noyau l'argument "init=/bin/bash", seul "bash" est lancé (à la place de /sbin/init) et on a ainsi un accès root sur la racine (utile pour réparer une distrib, ou modifier mot passe root dans /etc/shadow)
Changed:
< <
ex : sda découpé en /dev/sda1, /dev/sda2 et sdb découpé en /dev/sdb1, /dev/sdb2, /dev/sdb3
> >
/sbin/init a pour fichier de conf, /etc/inittab : décrit les processus lancés au démarrage et à surveiller durant le fonctionnement normal du système.
Init à 7 runlevels (0=stop, ..., 6=reboot). Runlevel 1 est pour la maintenance (nb minimum de processus et user root only).
Chaque ligne est composée de 4 paramètres :
référence:runlevel:manière de lancer la commande:commande
Runlevel par défaut (ici, le 3):
id:3:initdefault:
On peut modifier ça avec un argument au noyau, par ex:
root=/dev/hda2 ro 1
Runlevel courant ?
$ runlevel
Changer de runlevel ?
$ init n
Changed:
< <
2) mapping identité entre les partitions physiques (PP) et virtuelles (PV) : 1 PV = 1 PP
> >
sysinit est lancé au boot, mais avant les cdes boot:
si::sysinit:/etc/rc.d/rc.sysinit
Changed:
< <
Make sure the partition type for the physical volumes is correct. The partition type should be “8e”.
> >
reset:
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
Changed:
< <
# fdisk -l /dev/sdb
> >
wait, lance un process et attend sa fin pour continuer:
l5:5:wait:/etc/rc.d/rc 5
Changed:
< <
Disk /dev/sdb: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
> >
respawn, relance le process quand il se termine (ex: les gettys texte, alt-F1... relancés dès qu'on se délogue)
5:2345:respawn:/sbin/mingetty tty5
Changed:
< <
Device Boot Start End Blocks Id System
/dev/sdb1 1 30400 244187968+ 8e Linux LVM
/dev/sdb2 30401 60801 244196032+ 8e Linux LVM
> >
Relecture de inittab après modif ?
kill -HUP 1
Changed:
< <
# pvcreate /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Physical volume "/dev/sdb1" successfully created
Physical volume "/dev/sdb2" successfully created
Physical volume "/dev/sdc1" successfully created
Physical volume "/dev/sdc2" successfully created
> >
inittab lance des script rc (run command) de 2 façons selon les familles de systèmes linux :
# pvdisplay
"/dev/sdb1" is a new physical volume of "232.88 GB"
--- NEW Physical volume ---
PV Name /dev/sdb1
VG Name
PV Size 232.88 GB
Allocatable NO
PE Size (KByte) 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID j4XKT6-OI2y-cPMK-YpNR-gmgc-es67-ey4CV2
> >
Voyons ici la façon SystemV (plus élaborée que BSD)
Changed:
< <
"/dev/sdb2" is a new physical volume of "232.88 GB"
--- NEW Physical volume ---
...
> >
en fait, inittab lance le script rc général et lui passe le runlevel en argument:
l5:5:wait:/etc/rc.d/rc 5
rc va lancer les scripts du runlevel associé, dans l'ordre alpha.
/etc/rc.d/ contient un dossier rcN.d/ par runlevel (N)
ex: /etc/rc.d/rc5.d/
Ce dossier contient simplement des liens vers les scripts de /etc/init.d/ (qui doivent accepter au moins les arguments "start" et "stop")
Ces liens sont préfixés par S (Start) ou K (Kill).
Quand on entre dans un runlevel, tous les liens S* de ce runlevel sont exécutés (dans l'ordre alpha)
Quand on sort d'un runlevel, tous les liens K* de ce runlevel sont exécutés
Ex:
S85httpd lancera "/etc/init.d/httpd start"
Un lien /etc/rc.d/rc5.d/S42foobar sera exécuté à l'entrée du runlevel 5, et appellera /etc/init.d/foobar start
Il sera exécuté avant l'appel de S95barqux
Sur RedHat, seul le runlevel 5 lance X :
x:5:respawn:/etc/X11/prefdm -nodaemon
Changed:
< <
Notice that each PV is given a PV UUID
> >
Le dernier script à être lancé est /etc/rc.d/rc.local
(on peut y mettre tout ce qu'on veut voir exécuter au boot)
Le prog update-rc.d peut être utilisé pour activer/désactiver des scripts au démarrage.
Changed:
< <
3) Les PV sont regroupés en 1 à n volume group (VG) (a VG can be seen as a "virtual hd")
> >
Ubuntu propose Upstart en remplacement du couple init/inittab
MacOS propose un "super-daemon" launchd qui regroupe les fonctionnalités de init (lance démon lors du démarrage), crond (lance démon lors de top horaires), et (x)inetd (lance démon lors de requêtes réseaux)
Deleted:
< <
ex : le VG primary_vg regroupera /dev/sda1, /dev/sda2 , /dev/sdb1, et /dev/sdb3
Changed:
< <
# vgcreate primary_vg /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Volume group "primary_vg" successfully created
> >
FTP
Changed:
< <
# vgdisplay
--- Volume group ---
VG Name primary_vg
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 4
Act PV 4
VG Size 931.52 GB
PE Size 4.00 MB
Total PE 238468
Alloc PE / Size 0 / 0
Free PE / Size 238468 / 931.52 GB
VG UUID oNH6jk-PBE0-mR0c-aaDi-3Fys-y5SQ-0tVaxX
> >
ex: installation ftp pour l'expérience RAMAN (sur ExoMars)
Changed:
< <
If you don't happen to remember the name of a VG or you happen upon a new system to administer, then you can use a command called "vgscan" that will tell what VG's are on the system.
# vgscan
Reading all physical volumes. This may take a while...
Found volume group "primary_vg" using metadata type lvm2
> >
Mission
Changed:
< <
4) Chaque VG est redécoupé en m logical volume (LV) : 1 VG = m LV (a LV can be seen as a "virtual partition")
> >
La mission ExoMars, de l’Agence Spatiale Européenne (ESA), est une mission du programme Aurora. Son objectif est de caractériser l’environnement biologique martien pour préparer l’exploration humaine de la planète rouge.
Changed:
< <
ex : le VG primary_vg est redécoupé en 2 LV : /dev/primary_vg/home_lv et /dev/primary_vg/data_lv
> >
Instrument LABO
Changed:
< <
# lvcreate --name /dev/primary_vg/home_lv --size 450G
Logical volume "home_lv" created
> >
EXLIBRIS serait capable d’effectuer une ablation des roches puis l’analyse de la composition de cette roche à la fois en chimie élémentaire (ultra-violet), en minéraux et composés organiques (Raman). Le LABO serait responsable de la partie LIBS (ultra-violet) et de la calibration de l’instrument. F. Rull Pérez (Centro de Astrobiologia , Espagne) serait en charge de la partie Raman.
Contexte de réalisation
Faire en sorte que ftpread n'est qu'un accès en lecture seule (via son groupe ftpgroup) :
Changed:
< <
For example, if the file system says it has 29G used (29 GB), then you should snapshot a little larger – perhaps 30-32 GB (always good to have a cushion). This cushion isn’t strictly necessary, but a little safety never hurts...
Vous pouvez faire vos tests sur des fichiers ou des clefs USB pour commencer...
Remplacez simplement le "device" par un fichier existant. Ex : /dev/sdX par /home/moi/raid-test/disque-1.img.
Deleted:
< <
Pour créer un fichier quelque part avec la bonne taille : dd if=/dev/zero of=/home/moi/raid-test/disque-1.img count=10000 bs=65535.
Pour en savoir plus : man dd.
Deleted:
< <
Apres on fait un : mdadm --create /dev/md0 --level=1 --raid-devices=/home/moi/raid-test/disque-1.img,/home/moi/raid-test/disque-2.img
Deleted:
< <
Et voila un RAID 1 créé avec deux fichiers stockés sur le disque dur.
Deleted:
< <
J'ai testé le Raid0 sur 2DD externes de 2,5" en USB, et j'arrive à 45Mo sec avec mon portable...
Changed:
< <
Avant de mettre un raid sur une machine en production VERIFIEZ les noms des disques et des partitions !!! Préférez les /dev/disk/by-id, vous ferez moins facilement des erreurs qu'en mettant seulement /dev/sde, surtout si vous ajoutez des disques par la suite...
> >
LOGS
Changed:
< <
L'outil magique de management du RAID sous Linux : mdadm
> >
/var/log
Changed:
< <
Quelques exemples : (vous noterez que l'on utilise la syntaxe /dev/sdX alors que c'est mal.. mais c'est plus lisible que /dev/disk/by-id/ata-ST3250310AS_6RY7R988-part1)
> >
auth.log ou secure (sur Redhat)
Changed:
< <
création d'une pile raid :
> >
Outil de visualisation graphique des logs : gnome-system-log
/var/log/message: General message and system related stuff
/var/log/auth.log: Authenication logs
/var/log/kern.log: Kernel logs
/var/log/cron.log: Crond logs (cron job)
/var/log/maillog: Mail server logs
/var/log/qmail/ : Qmail log directory (more files inside this directory)
/var/log/httpd/: Apache access and error logs directory
/var/log/lighttpd: Lighttpd access and error logs directory
/var/log/boot.log : System boot log
/var/log/mysqld.log: MySQL database server log file
/var/log/secure: Authentication log
/var/log/utmp or /var/log/wtmp : Login records file
/var/log/yum.log: Yum log files
Changed:
< <
crée un device /dev/mdX (X étant un chiffre) de niveau (--level) 0 (stripping), 1 (mirroring), 4 (comme le 5 mais la parité est toujours sur le même disque), 5 ou 6 (2 disques de parité) à partir des devices /dev/sdYZ (Y est une lettre indiquant un disque physique , Z un chiffre indicant un numéro de partition).
On peut également mettre missing dans la liste des devices. C'est très utile lorsque l'on passe son système sur un raid 1
> >
In short /var/log is the location where you should find all Linux logs file. However some applications such as httpd have a directory within /var/log/ for their own log files. You can rotate log file using logrotate software and monitor logs files using logwatch software.
Deleted:
< <
Mise en échec d'un disque (pour test par ex.) :
mdadm --manage /dev/mdX --failed /dev/sdYZ
Changed:
< <
"Ejection" d'un disque d'une pile :
mdadm --manage /dev/mdX --remove /dev/sdYZ
> >
logrotate
Changed:
< <
Ajout d'un disque à une pile :
mdadm --manage /dev/mdX --add /dev/sdYZ
> >
/etc/logrotate.conf
Changed:
< <
Liste des périphériques d'une pile :
mdadm --misc --detail /dev/mdX
> >
/etc/logrotate.d/
Changed:
< <
On peux aussi faire :
> >
Forcer une rotation :
Changed:
< <
cat /proc/mdstat
> >
sudo logrotate -f /etc/logrotate.conf
Added:
> >
==> new file "messages", "messages" devient "messages1", "messages1" devient "messages2"...
Changed:
< <
Agrandir une partition
> >
logwatch
Changed:
< <
La première étape consiste à repérer quel device correspond aux partitions que tu veux redimensionner. Pour cela tu peux utiliser la commande :
> >
by default, runs daily on yesterday's logs (/etc/cron.daily/0logwatch qui pointe sur /usr/share/logwatch/scripts/logwatch.pl), includes all services, and sends a mail to root
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
watchfor /invalid|repeated|incomplete/
echo
write khess
mail addresses=khess@localhost, subject=Authentication Problems
Changed:
< <
The basic command is structured as follows:
> >
/etc/init.d/swatch start ==> créer un pid dans /var/run/swatch.pid et un fichier /root/.swatch_script.xxxx (avec xxxx = pid - 2)
Deleted:
< <
dd if= of= bs=(usually some power of 2, not less than 512 bytes(ie, 512, 1024, 2048, 4096, 8192, 16384, but can be any number.) skip= seek= conv=.
Changed:
< <
Source is the data being read. Target is where the data gets written. If you mess up, and accidentally reverse the source and target, you can wipe out a lot of data.
> >
SSH, config plus stricte
Changed:
< <
(http://www.efense.com/helix is a good boot cd : The helix boot environment contains the DoD version of dd called dcfldd. It works the same way, but is has a progress bar)
> >
vi /etc/ssh/sshd_config
Added:
> >
Port 22 : on pourrait mettre ici un autre port, genre 2010, histoire de brouiller les pirates...
Changed:
< <
Using dd you can create backups of an entire harddisk or just a parts of it. This is also usefull to quickly copy installations to similar machines. It will only work on disks that are exactly the same in disk geometry, meaning they have to the same model from the same brand.
Voir aussi si messages d'erreur disques dans /var/log/messsages
Changed:
< <
sda2, sdb2 are partitions. You want to copy sda2 to sdb2. If sdb2 doesn't exist, dd will start at the beginning of the disk, and create it. Be careful with order of if and of. You can write a blank disk to a good disk if you get confused.
> >
Tester aussi la commande dmesg (equivalent à /var/log/dmesg)
CD sectors are 2048 bytes, so this copies sector for sector. The result will be a hard disk image file of the CD. You can use "chmod a+rwx mycd.iso" to make the image writable. You can mount the image with "mkdir /mnt/mycd", this line in fstab: "/home/sam/mycd.iso /mnt/mycd iso9660 rw,user,noauto 0 0", save fstab, "mount -o loop /mnt/mycd". Then the file system will be viewable as files and directories in the directory /mnt/mycd. You can edit the image as you wish, and the new file will be "/home/sam/mycd.iso" dd does not write to CD's. You need to use a burning utility, or the cdrdao command
> >
Annuler l'information sur les updates disponibles :
Changed:
< <
Cloning an entire hard disk:
> >
/etc/init.d/yum-updatesd stop
Changed:
< <
dd if=/dev/sda of=/dev/sdb conv=notrunc,noerror
> >
su -c 'chkconfig --level 2345 yum-updatesd off'
Changed:
< <
In this example, sda is the source. sdb is the target. Do not reverse the intended source and target. Surprisingly many people do. notrunc means to not truncate. noerror means to keep going if there is an error. Normally dd stops at any error. if you have a question about a hard drive on whether or not it works, you can try to use it as the source drive for the dd command. You should get an error if it is not working. target drives need to be really messed up to give an error in dd.
> >
Every other workaround seems to only kill yum-updatesd for runlevel 5.
Keep in mind that you will no longer be informed that there updates available and as such you will need to check periodically with yum check-update
Changed:
< <
this will copy the first 446 bytes of the hard drive to a file. If you haven't already guessed, reversing the objects of if and of, in the dd command line reverses the direction of the write.
> >
Quels sont les packages commençant par "mesa-" installés + à installer ? --> yum list mesa-*
Deleted:
< <
Back up your MBR
Deleted:
< <
dd if=/dev/sda of=mbr.bin count=1
Changed:
< <
Put this on a floppy you make with
> >
Samba
Changed:
< <
dd if=boot.img of=/dev/fd0
> >
Créer un new user "toto" : sbmpasswd -a toto
Changed:
< <
Along with dd. Boot from the floppy and
> >
Mettre à jour le pass de "toto" : smbpasswd toto
Changed:
< <
dd if=mbr.bin of=/dev/sda count=1
> >
Est-ce que samba est à l'écoute ? : service smb status
Changed:
< <
Will restore the MBR
> >
Redémarrer samba : service smb restart
Changed:
< <
Copy a disk partition to a file on a different partition (Do not copy a partition to the same partition)
This way you can get a bazonga hard drive and partition it so you can back up your root partition. If you mess up your root partition, you just boot from the helix cd and restore the image.
Deleted:
< <
Copie de disque ou partition (image "ghost") avec partimage (SystemRescueCd)
Deleted:
< <
J'ai un disque qui montre des faiblesses
Changed:
< <
Je veux le remplacer par un nouveau disque
> >
Changed:
< <
Je dois donc faire une image du disque et la copier ensuite sur le nouveau disque
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
> >
<--
Cocher "Disable encryption of all traffic" (pour accélerer la connexion)
Cliquer sur le bouton Key et y coller l'intégralité de la clé publique suivante à la place de la clé courante :
Changed:
< <
Disque /dev/md0 ne contient pas une table de partition valide
> >
(pour info, cette clé provient du fichier /etc/nxserver/client.id_dsa.key dans l'installation du serveur freenx)
Added:
> >
Par soucis de sécurité, je ne diffuse pas la clé ici (vous l'avez reçue par mail)
Changed:
< <
# fdisk /dev/sda
...
> >
cliquer sur "Save", puis "Ok" pour revenir à la fenêtre de connexion
Changed:
< <
Commande (m pour l'aide): p
> >
Entrer votre login/pass pour hyperion
Changed:
< <
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
> >
Cliquer sur "Login"
Changed:
< <
# cat /proc/partitions
major minor #blocks name
> >
Et voilà !
Changed:
< <
0 244198584 sda
1 200781 sda1
2 4096575 sda2
3 239898645 sda3
16 244198584 sdb
17 244196001 sdb1
32 244198584 sdc
33 244196001 sdc1
48 244198584 sdd
49 244196001 sdd1
0 488391680 md0
> >
(Lorsque votre bureau hyperion s'affiche, répondre à la question posée en choisissant "GNOME")
Added:
> >
Si le clavier est qwerty, pour passer à un clavier azerty :
Changed:
< <
# cat /etc/fstab
> >
aller dans le menu Système / Préférences / Clavier
cliquer sur onglet "Agencements"
cliquer sur bouton "+ Ajouter"
sélectionner France puis cliquer sur Valider
sélectionner France puis cliquer sur "Vers le haut"
4) C'est très bien tout ça, mais comment je fais depuis chez moi ???
Changed:
< <
La virtualisation consiste à faire cohabiter plusieurs (VM) machines "virtuelles" (OS) sur une même machine physique
> >
C'est un peu plus compliqué car il faut installer un tunnel qui passe par le GATEWAY LABO.
Changed:
< <
Prérequis :
> >
a) Creuser un tunnel
Changed:
< <
Les processeurs doivent être virtualisables (cpuinfo doit contenir le flag vmx pour un processeur intel, et svm pour AMD) : egrep '(vmx|svm)' /proc/cpuinfo
> >
Sur Windows, on crée le tunnel avec le logiciel Putty
Changed:
< <
RAM : au moins 8Go (pour 2 VM)
> >
Exécuter Putty
Changed:
< <
Disques :
au moins 2x500Go (en raid1 par exemple)
bonne config type :
2 disques raid1 pour le système de base
3 disques raid5 avec un LVM dessus pour stocker les images disques des VM
> >
Si vous avez déjà une session vers GATEWAY, inutile d'en recréer une autre, vous pouvez l'utiliser. Sinon, il faut créer une nouvelle session :
Added:
> >
Host name : GATEWAY
Changed:
< <
Serveur de gestion de versions (de code source) SUBVERSION
Le serveur X tourne localement sur mon pc (win ou lin), c'est à dire le pc avec un écran (output), un clavier et une souris (inputs).
> >
Cliquer sur bouton "Add"
Changed:
< <
Il se connecte à un display manager (xdm ou gdm ou kdm...) qui peut être local ou distant (sur un autre pc) :
Si le DM est local, il démarre un ou plusieurs serveurs X, affiche l'écran de connexion (login) au démarrage et chaque fois qu'un user se délogge.
Si le DM est distant, il est utilisé via le protocole XDMCP : un user lance des programmes depuis le pc distant (qui exécute le DM) alors que ses input/output se passent sur son pc local.
> >
Dans le panneau de gauche (Category:), cliquer sur l'arbre "Session"
Changed:
< <
Ainsi, le serveur X (local) communique avec différents clients graphiques (qui peuvent être distants) à qui il envoit les inputs et de qui il reçoit les outputs.
> >
Cliquer sur bouton "Save"
Changed:
< <
Pour CentOS, le DM par défaut est sélectionné dans /etc/X11/prefdm (qui regarde si un DM par défaut est donné dans /etc/sysconfig/desktop)
> >
Ouvrir cette session (GATEWAY) que vous venez de créer, et se connecter sur GATEWAY (avec votre mot de passe mail).
Deleted:
< <
C'est le fichier /etc/X11/xinit/Xsession qui exécute notre environnement.
Changed:
< <
xdm : voir /etc/X11/
> >
b) Créer une session graphique
Changed:
< <
kdm : voir /etc/kdm/
> >
Suivre toutes les étapes du point 3) mais en remplaçant "hyperion.cesr.fr (port 22)" par "localhost (port 9022)"
Changed:
< <
gdm : voir /etc/gdm/ Il devrait s'y trouver un gdm.conf
> >
Ya pu ka tester !
Deleted:
< <
gdm appelle /etc/X11/xinit/Xsession avec les bonnes options
I - Le boot : tryptique noyau, arguments, et ramdisk
Synthèse du workflow :
bootloader ==> noyau + initramfs + arguments ==> montage de la racine
> >
Installer GhostScript (engine) puis GhostView (frontend)
Changed:
< <
1) Chargeur de boot (bootloader)
C'est le 1er prog à s'exécuter. Différent selon les architectures (pc x86, station Sun, Mac PPC...)
Rôle: mettre en RAM le noyau (kernel), lui passer des arguments, copier un ramdisk en RAM, et passer la main au noyau
Ex: lilo, grup, outils syslinux (bien adapté à partifion FAT, clé usb, cd)
Etapes :
- allumage électrique
- POST (Power On Self Test)
- BIOS (dans lequel le periph d'amorçage est défini)
- lancement bootloader installé sur periph amorcé
Ex: noyau grub, /boot/bzImage-2.6
Ex: ramdisk grub, /boot/initrd.img
Rôle : monter la racine et lancer /sbin/init situé dessus
Au boot, le noyau décourvre son environnement (ram, cpu, disque...). Ces périph sont gérés par des pilotes (drivers), des "modules" qui sont compilés dans le noyau ou dans des fichiers externes (souvent dans /lib/modules/). Les fichiers modules sont situés sur une partition qui n'est pas encore montée, et donc les périph correspondants ne peuvent pas être utilisés.
Le noyau monte sa racine avec /bin/mount
ex: montage de /dev/sda1 en lecture seule avec sys de fichier ext4
$ mount -t ext4 -o ro /dev/sda1 /
Les arguments passés au noyau peuvent être relus après boot :
$ cat /proc/cmdline
On peut aussi passer l'argument "init=/bin/bash" pour accéder au système au démarrage avec un shell bash.
> >
Convertir un fichier Postscript en JPEG (ou autre) avec GhostScript (en mode batch)
Changed:
< <
3) Le ramdisk initial : initramfs
Rôle : permettre une détection plus intelligente de la racine ainsi qu'une facilité de configuration.
S'appelait initrd, mais est de plus en plus remplacé par initramfs
L'initramsf est un ensemble de fichiers qui vont être directement copiés dans le cache de système de fichiers sous la racine (tous les sys 2.6 utilisent un rootfs, cf "cat /proc/mounts"). Il doit au moins contenir un programme /init exécutable que le noyau va lancer pour qu'il trouve la racine et la monte. C'est un microsystème linux à part entière. Le prog /init est souvent un script shell, simple à lire.
Avec un initramfs, il devient possible de conserver un noyau minimal et de mettre les modules essentiels au boot dans l'initramfs (évite de devoir recompiler le noyau). Il contient aussi l'image qui permet un affichage graphique pendant le boot.
/init parse donc la ligne /proc/cmdline, cherche la racine, et la monte pour ensuite basculer le noyau dessus, et enfin s'autoremplace par le vrai binaire /sbin/init.
> >
Pour info, sur Linux, c'est très simple, il suffit d'utiliser la commande "convert" (ou plus spécifique "ps2...")
Changed:
< <
II - init et inittab
> >
Sous Windows, c'est un peu plus compliqué.
Changed:
< <
Arrivé à ce point, la noyau tourne, la racine de la distrib est montée (souvent en "ro") et le binaire /sbin/init est lancé, premier processus.
Si ce processus meurt (pid=1), le noyau fait un kernel panic. Il est aussi responsable de l'extinction de la machine.
Si on passe au noyau l'argument "init=/bin/bash", seul "bash" est lancé (à la place de /sbin/init) et on a ainsi un accès root sur la racine (utile pour réparer une distrib, ou modifier mot passe root dans /etc/shadow)
> >
1) Télécharger la version Windows de GhostScript et l'installer
Changed:
< <
/sbin/init a pour fichier de conf, /etc/inittab : décrit les processus lancés au démarrage et à surveiller durant le fonctionnement normal du système.
Init à 7 runlevels (0=stop, ..., 6=reboot). Runlevel 1 est pour la maintenance (nb minimum de processus et user root only).
Chaque ligne est composée de 4 paramètres :
référence:runlevel:manière de lancer la commande:commande
Runlevel par défaut (ici, le 3):
id:3:initdefault:
On peut modifier ça avec un argument au noyau, par ex:
root=/dev/hda2 ro 1
Runlevel courant ?
$ runlevel
Changer de runlevel ?
$ init n
Aller dans le dossier qui contient le fichier PS (somefile.ps) à convertir (cd ...)
Changed:
< <
Voyons ici la façon SystemV (plus élaborée que BSD)
> >
L'instruction suivante créera un fichier somefile.jpg dans c:\temp :
Changed:
< <
en fait, inittab lance le script rc général et lui passe le runlevel en argument:
l5:5:wait:/etc/rc.d/rc 5
rc va lancer les scripts du runlevel associé, dans l'ordre alpha.
/etc/rc.d/ contient un dossier rcN.d/ par runlevel (N)
ex: /etc/rc.d/rc5.d/
Ce dossier contient simplement des liens vers les scripts de /etc/init.d/ (qui doivent accepter au moins les arguments "start" et "stop")
Ces liens sont préfixés par S (Start) ou K (Kill).
Quand on entre dans un runlevel, tous les liens S* de ce runlevel sont exécutés (dans l'ordre alpha)
Quand on sort d'un runlevel, tous les liens K* de ce runlevel sont exécutés
Ex:
S85httpd lancera "/etc/init.d/httpd start"
Un lien /etc/rc.d/rc5.d/S42foobar sera exécuté à l'entrée du runlevel 5, et appellera /etc/init.d/foobar start
Il sera exécuté avant l'appel de S95barqux
Sur RedHat, seul le runlevel 5 lance X :
x:5:respawn:/etc/X11/prefdm -nodaemon
Le dernier script à être lancé est /etc/rc.d/rc.local
(on peut y mettre tout ce qu'on veut voir exécuter au boot)
Le prog update-rc.d peut être utilisé pour activer/désactiver des scripts au démarrage.
Ubuntu propose Upstart en remplacement du couple init/inittab
MacOS propose un "super-daemon" launchd qui regroupe les fonctionnalités de init (lance démon lors du démarrage), crond (lance démon lors de top horaires), et (x)inetd (lance démon lors de requêtes réseaux)
> >
REMARQUE : pour faire la même chose en mode graphique,
il existe une interface graphique qui s'installe par-dessus GhostScript (en frontend),
c'est GhostView (gsview) :
La mission ExoMars, de l’Agence Spatiale Européenne (ESA), est une mission du programme Aurora. Son objectif est de caractériser l’environnement biologique martien pour préparer l’exploration humaine de la planète rouge.
Deleted:
< <
Instrument LABO
Changed:
< <
EXLIBRIS serait capable d’effectuer une ablation des roches puis l’analyse de la composition de cette roche à la fois en chimie élémentaire (ultra-violet), en minéraux et composés organiques (Raman). Le LABO serait responsable de la partie LIBS (ultra-violet) et de la calibration de l’instrument. F. Rull Pérez (Centro de Astrobiologia , Espagne) serait en charge de la partie Raman.
Contexte de réalisation
> >
Migrer de Windows XP vers Windows 7
Changed:
< <
Mission ESA : Tir prévu en 2013.
> >
Il faut acheter la licence Microsoft. La démarche dépend de la marque du PC.
Envoyer des mails avec Outlook quand on n'est pas au LABO
Deleted:
< <
Les autoriser en les ajoutant dans dans /etc/vsftpd/user_list
Changed:
< <
(chroot doit être activé par défaut pour tous les users internes)
> >
1) "Creuser" un tunnel avec Putty
Changed:
< <
/etc/init.d/vsftpd restart
> >
Créer une nouvelle session que vous appelerez par exemple "tunnel_mail_LABO",
et qui créera un tunnel entre le port local 9025 et le port SMTP (25) du serveur de mail LABO (GATEWAY).
Il faudra lancer cette session (et la garder ouverte en tâche de fond) avant d'envoyer un mail
Added:
> >
2) Configurer votre client mail Outlook
Added:
> >
Menu Outils/Paramètres du compte
Clic sur bouton "Modifier"
Dans le champ "Serveur de courrier sortant (SMTP)", remplacer "mailhost.cesr.fr" par "localhost"
Clic sur bouton "Paramètres supplémentaires...", clic sur onglet "Options avancées"
Dans le champ "Serveur Sortant (SMTP)", remplacer "25" par "9025"
Added:
> >
Bien sûr, il faut tout remettre en place quand on revient au LABO (en fait, on pourrait aussi fonctionner en permanence avec le tunnel, même au LABO...)
Added:
> >
Synchroniser Outlook 2007 Calendar et Google Calendar
Installer un serveur X sur Windows pour afficher les fenêtres graphiques de linux
Changed:
< <
Outil de visualisation graphique des logs : gnome-system-log
> >
On propose d'utiliser Xming qui est un serveur X gratuit pour Windows
Changed:
< <
Common Linux log files name and usage :
/var/log/message: General message and system related stuff
/var/log/auth.log: Authenication logs
/var/log/kern.log: Kernel logs
/var/log/cron.log: Crond logs (cron job)
/var/log/maillog: Mail server logs
/var/log/qmail/ : Qmail log directory (more files inside this directory)
/var/log/httpd/: Apache access and error logs directory
/var/log/lighttpd: Lighttpd access and error logs directory
/var/log/boot.log : System boot log
/var/log/mysqld.log: MySQL database server log file
/var/log/secure: Authentication log
/var/log/utmp or /var/log/wtmp : Login records file
/var/log/yum.log: Yum log files
> >
Il suffit d'éxécuter Xming avant de lancer une session graphique via putty (ou autre shell)
Changed:
< <
In short /var/log is the location where you should find all Linux logs file. However some applications such as httpd have a directory within /var/log/ for their own log files. You can rotate log file using logrotate software and monitor logs files using logwatch software.
2) Installer Xming-fonts (surtout nécessaire pour Emacs)
Deleted:
< <
/etc/logrotate.d/
Deleted:
< <
Forcer une rotation :
Deleted:
< <
sudo logrotate -f /etc/logrotate.conf
Changed:
< <
==> new file "messages", "messages" devient "messages1", "messages1" devient "messages2"...
> >
HARDWARE
Changed:
< <
logwatch
> >
Disques SATA
Deleted:
< <
by default, runs daily on yesterday's logs (/etc/cron.daily/0logwatch qui pointe sur /usr/share/logwatch/scripts/logwatch.pl), includes all services, and sends a mail to root
(pas encore sûr, à réfléchir) ajouter un script qui permet de définir un tableau de champs obligatoires pour un Modèle donné ==> Ces champs devront obligatoirement être saisis dans les vues associées au Modèle (voir http://book.cakephp.org/1.3/view/1147/required)
Every other workaround seems to only kill yum-updatesd for runlevel 5.
Changed:
< <
Try yum update after that.
> >
III - En s'inspirant du tutoriel "blog", commmencer à construire une architecture à partir d'un sous-ensemble de la BDD Europlanet
Changed:
< <
Keep in mind that you will no longer be informed that there updates available and as such you will need to check periodically with yum check-update
> >
1) Ce projet est géré en versions avec subversion (plugin Eclipse subclipse)
Changed:
< <
Quels sont les packages commençant par "mesa-" installés + à installer ? --> yum list mesa-*
> >
2) Construire un schéma d'une petite BDD avec MysqlWorkbench
Ce schéma contient 7 tables principales :
- people (lien N-1 avec institutes, status, et profiles, et 1-N avec resources) : id, name, firstname, email, password, status, active, job, created, updated (le champ "active" est un booléen VRAI par défaut)
- status : id, name (avec les valeurs suivantes pour name : NULL, 'registered', 'invalidated', 'validated')
- profiles : id, name, level (level indique la hiérarchie ; name et level ont les valeurs suivantes : {'admin',10}, {'priv',5}, {'validator',3}, {'normal',0} ; donc on a la hiérarchie admin > priv > validator > normal)
- institutes : id, name, created, updated
- expertises : id, name (lien M-N avec people)
- resources (lien M-N avec sciencases) : id, name, created, updated
- sciencecases : id, name, created, updated
Par défaut, l'action "people/index" ne doit afficher que les personnes dont le champ "active" est à TRUE et le champ "status" vaut "validated"
Added:
> >
5) Lancer les tests générés par "bake" (avec phpUnit, inclus dans Xampp ?) pour tester les modèles et les contrôleurs
http://book.cakephp.org/2.0/en/development/testing.html
cake bake fixture all ?
cake bake test all ?
Depuis cakephp 2.1 :
Console/cake test app/Model/Post.php
Console/cake test app/Controller/PostsController.php
Added:
> >
6) Ajouter la validation des champs de tous les formulaires
http://book.cakephp.org/2.0/en/models/data-validation.html
"bake" ajoute des validations par défaut. Les étendre si nécessaire pour que toutes les validations soient générées automatiquement, en fonction du type des champs.
Vérifier que les champs obligatoires sont bien obligatoires en saisie.
Ajouter un test pour s'assurer qu'une personne est obligée de remplir tous les champs (sauf people.job) quand elle s'enregistre.
1) Ajouter l'authentification (AUTH)
Login = email
Auth (et Acl) doivent avoir pour support la table "people" (et status et profiles).
Auth (et Acl) impliquent aussi l'usage des Sessions (http://book.cakephp.org/2.0/en/development/sessions.html)
Astuce : dans la session, stocker l'id de la personne, et non pas son email (car l'email peut changer, mais pas l'id)
Changed:
< <
3) Exemple : Configurer une session graphique vers hyperion (depuis le boulot)
> >
Toute personne non authentifiée (accès anonyme) peut :
- lire (R ) toutes les tables, sauf la table "resources"
- s'enregistrer (droit C sur la table people)
Changed:
< <
Démarrer le "NX Connection Wizard" (un des programmes installés avec le client)
> >
Toute personne authentifiée peut :
- lire (R ) toutes les tables (y-compris "resources")
- modifier (U) sa fiche (sauf son profil), mais pas celle des autres
- créer (C ) une ressource
- modifier/supprimer (UD) une ressource qu'elle a créée, mais pas celles des autres
- modifier (U) un institut auquel elle appartient
Changed:
< <
Cliquer sur Next
> >
Gérer le login et le logout
Changed:
< <
Session : donner un nom à votre session graphique (par exemple "connexion à hyperion depuis le boulot")
> >
Ajouter les tests nécessaires :
(Utiliser des "fixtures", cf section "Fixtures" dans http://book.cakephp.org/2.0/en/development/testing.html)
(cake bake fixture all ?)
Tester qu'une personne non authentifiée :
- peut lire la table 'resource'
- peut s'enregistrer
- ne peut pas modifier une table
Tester qu'une personne authentifiée peut :
…
Faire un test login/logout complet selon le scénario suivant :
- une personne se logue
- vérifier qu'elle peut créer une ressource
- elle se délogue
- vérifier qu'elle ne peut plus créer une ressource
Deleted:
< <
Host : hyperion.cesr.fr (port 22)
Changed:
< <
Cliquer sur Next
> >
2) Ajouter le contrôle d'accès (ACL)
Changed:
< <
Sélectionner "Unix" et "GNOME"
> >
Créer quelques personnes avec des rôles (profils) différents :
'user1', profil 'admin' (tous les droits)
'user2' et 'user3', profil 'normal', utilisateur normal
'user4', profil 'priv', utilisateur privilégié
'user5', profil 'validator', utilisateur pouvant valider d'autres utilisateurs
Changed:
< <
<--
Cocher "Disable encryption of all traffic" (pour accélerer la connexion)
-->
> >
Une personne de profil 'admin' a un droit CRUD (créer/lire/modifier/supprimer) sur toutes les tables.
Changed:
< <
Cliquer sur Next
> >
Une personne de profil 'priv' :
a un droit CRUD seulement sur la table 'institutes'
peut modifier le profil de toutes les personnes (sauf le sien)
Changed:
< <
Cocher "Create shortcut on desktop"
> >
Ajouter les tests nécessaires :
tester que 'user1' peut tout faire (faire juste quelques tests, pas tout)
tester que 'user4' : * peut ajouter un nouvel institut * peut modifier le profil d'une personne (mais pas le sien)
tester que 'user2' : * ne peut pas modifier une ressource qui ne lui appartient pas * peut ajouter une nouvelle ressource, et la modifier ensuite * peut modifier son email (login) et/ou son mot de passe
...
Deleted:
< <
Cliquer sur Next
Changed:
< <
Une fenetre de connexion s'affiche (que vous pourrez relancer à loisir en cliquant sur votre raccourci bureau portant le nom de votre session)
> >
VI - ENREGISTREMENT DES UTILISATEURS (registration)
Changed:
< <
Cliquer sur "Configure"
> >
1) Réalisation de la procédure d'enregistrement (inscription) d'une personne :
Changed:
< <
Cocher "Remember my password"
> >
(voir s'il n'existe pas déjà un plugin cakephp pour gérer ça, car c'est assez classique au début)
Changed:
< <
Cliquer sur le bouton Key et y coller l'intégralité de la clé publique suivante à la place de la clé courante :
> >
a) une personne remplit sa fiche d'enregistrement et la soumet (SUBMIT) ==> elle est enregistrée dans la table people avec "status" à NULL
Changed:
< <
(pour info, cette clé provient du fichier /etc/nxserver/client.id_dsa.key dans l'installation du serveur freenx)
> >
b) elle reçoit un 1er mail de confirmation avec un lien de validation
Changed:
< <
Par soucis de sécurité, je ne diffuse pas la clé ici (vous l'avez reçue par mail)
> >
c) elle clique sur le lien de validation, ce qui valide son inscription ==> son champ "status" passe à "registered" ; les validateurs reçoivent un mail pour les avertir de cette inscription, avec un lien vers la page du site permettant de valider ou invalider la personne
Changed:
< <
cliquer sur "Save", puis "Ok" pour revenir à la fenêtre de connexion
> >
d) elle reçoit un 2e mail de confirmation lui disant qu'elle est inscrite, MAIS qu'elle doit attendre que son inscription soit validée par un 'validateur', et qu'elle recevra un mail pour le lui confirmer
Changed:
< <
Entrer votre login/pass pour hyperion
> >
e) si un validateur valide l'inscription, la personne reçoit un mail pour l'en informer (à partir de là, elle peut se connecter au site) ==> son "status" passe à "validated"
Changed:
< <
Cliquer sur "Login"
> >
f) si un validateur invalide l'inscription, la personne reçoit un mail pour l'en informer ==> son "status" passe à "invalidated"
Changed:
< <
Et voilà !
> >
Ajouter les actions suivantes au Contrôleur "person" :
validate (profil 'validator') : pour valider une personne (champ "status")
invalidate (profil 'validator') : pour invalider une personne
deleteInvalidated (profil 'priv') : pour supprimer les personnes ayant un statut "invalidated"
activate (profil 'priv') : pour activer une personne (champ "active")
deactivate (profil 'priv') : pour désactiver une personne
Changed:
< <
(Lorsque votre bureau hyperion s'affiche, répondre à la question posée en choisissant "GNOME")
> >
Ajouter/modifier les tests nécessaires
Changed:
< <
Si le clavier est qwerty, pour passer à un clavier azerty :
> >
2) Ajouter un captcha sur la fiche d'inscription
Changed:
< <
aller dans le menu Système / Préférences / Clavier
cliquer sur onglet "Agencements"
cliquer sur bouton "+ Ajouter"
sélectionner France puis cliquer sur Valider
sélectionner France puis cliquer sur "Vers le haut"
cliquer sur bouton "X Fermer"
> >
Ajouter/modifier les tests nécessaires :
tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
Sur le formulaire de login, ajouter (à droite du bouton LOGIN) un lien "register" (pour s'enregistrer) et un lien "forgot password" (mot de passe oublié)
Changed:
< <
4) C'est très bien tout ça, mais comment je fais depuis chez moi ???
> >
Le lien "forgot password" pointe vers un formulaire de modification du mot de passe (Person/PasswordUpdate) contenant juste 1 champ "email" et un bouton "SUBMIT"
Changed:
< <
C'est un peu plus compliqué car il faut installer un tunnel qui passe par le GATEWAY LABO.
> >
L'utilisateur saisit son email et clique sur "submit" pour qu'on lui envoie un nouveau mot de passe par mail (le mot de passe est aussi mis à jour dans la database)
Changed:
< <
a) Creuser un tunnel
> >
Test
Deleted:
< <
Sur Windows, on crée le tunnel avec le logiciel Putty
Changed:
< <
Exécuter Putty
> >
4) Procédure de désinscription (ACTION unregister)
Changed:
< <
Si vous avez déjà une session vers GATEWAY, inutile d'en recréer une autre, vous pouvez l'utiliser. Sinon, il faut créer une nouvelle session :
> >
a) une personne clique sur un lien "unregister"
Changed:
< <
Host name : GATEWAY
> >
b) une confirmation est demandée via une fenêtre javascript : "Are you sure that you want to unregister ?" OK/CANCEL
Changed:
< <
Port : 22
> >
c) l'action "unregister" est exécutée, la personne n'est pas supprimée de la base, mais juste marquée "inactive"
Changed:
< <
Saved Sessions : GATEWAY (ou ce que vous voulez, par exemple "le GATEWAY du LABO")
> >
d) la personne est automatiquement déconnectée
Changed:
< <
Dans le panneau de gauche (Category:), cliquer sur l'arbre "Connection", puis "SSH", puis "Tunnels"
> >
e) Test
Deleted:
< <
(si vous avez déjà un ou plusieurs tunnels créés, pas de problème, vous pouvez en ajouter un de plus)
Deleted:
< <
Source Port : 9022
Deleted:
< <
Destination : hyperion.cesr.fr:22
Deleted:
< <
Cliquer sur bouton "Add"
Changed:
< <
Dans le panneau de gauche (Category:), cliquer sur l'arbre "Session"
> >
VII - Améliorer le CRUD
Changed:
< <
Cliquer sur bouton "Save"
> >
1) Bien gérer complètement les relations 1-N
Changed:
< <
Ouvrir cette session (GATEWAY) que vous venez de créer, et se connecter sur GATEWAY (avec votre mot de passe mail).
> >
Actions sur Person (relation N-1 avec Institute) :
create : doit permettre d'associer la personne à un institut (via liste de noms)
update : doit permettre de modifier l'institut associé (via liste de noms)
index : doit permettre de voir toutes les personnes avec le nom (name) de l'institut associé ; un clic sur un institut doit amener à sa vue détaillée
view : doit afficher le nom (name) de l'institut associé
Added:
> >
Action sur Institute (relation 1-N avec Person) :
view : doit afficher toutes les personnes associées
Changed:
< <
b) Créer une session graphique
> >
2) Bien gérer complètement les relations M-N
Changed:
< <
Suivre toutes les étapes du point 3) mais en remplaçant "hyperion.cesr.fr (port 22)" par "localhost (port 9022)"
> >
Actions sur Person (relation M-N avec Expertise) :
create : doit permettre d'ajouter des expertises (ET une date "since")
update : doit permettre de modifier les expertises associées
view : doit permettre de voir toutes les expertises associées
Idem pour Expertise (lien vers Person)
Changed:
< <
Ya pu ka tester !
> >
Même chose pour Resource (relation M-N avec Sciencecase)
Added:
> >
Gestion des champs supplémentaires d'une table associative : exemple de la relation entre Person et Expertise :
Added:
> >
expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table) et le champ supplémentaire "since" (date à laquelle l'expertise a été acquise)
Added:
> >
3) Gérer d'autres types de relations
Added:
> >
a) Ajout de plusieurs rôles différents entre 2 mêmes tables
Une personne peut avoir plusieurs liens avec une ressource (plusieurs liens entre les tables "people" et "resources"), ce qui veut dire qu'elle peut jouer plusieurs rôles par rapport à une ressource.
Ainsi, au lieu d'avoir seulement une clé étrangère "resources_id" dans la table "people", nous en aurons plusieurs avec des noms différents :
resource_provider_id : la personne qui a donné l'information sur la ressource (et qui l'a saisit)
resource_owner_id : le propriétaire de la ressource
resource_contact_id : le contact pour la ressource
Ces 3 clés pointent toutes vers la même clé primaire resource.id, et sont donc des "alias".
Améliorer les actions CRUD en conséquence
Added:
> >
b) Relation réflexive (d'une table sur elle-même)
Added:
> >
Ajout d'une relation réflexive sur "institutes" (dans ce cas particulier, il s'agit d'une relation hiérarchique) :
un institut peut appartenir à un autre institut (de niveau hiérarchique supérieur ; par exemple, le "CNRS" regroupe plusieurs instituts, "l'OMP" regroupe plusieurs laboratoires dont l'IRAP…)
cela revient seulement à ajouter un champ "institute_id" dans la table institutes (qui pointe sur la table institute, lien réflexif)
améliorer les actions CRUD en conséquence
Added:
> >
c) Relation d'héritage ou spécialisation (1:1)
Added:
> >
Une ressource peut être de différents types (ajouter la table "resourcetype") :
Added:
> >
data
info (information, document...)
website
datacenter
Added:
> >
chaque type de ressource est une spécialisation du type général "resource".
Changed:
< <
Visualiser les fichiers Postscript
> >
On aura donc 4 nouvelles tables filles "resourcedata", "resourceinfo", "resourcewebsite", "resourcedatacenter" qui "hériteront" de la table mère (générique) "resource" pour l'étendre chacune avec sa spécificité.
Changed:
< <
Installer GhostScript (engine) puis GhostView (frontend)
> >
On peut représenter ce lien d'héritage par une relation 1-1 entre chacune de ces 4 tables filles et la table mère "resource".
Aucune des tables filles n'a d'existence propre, chacune dépend de la table mère "resource".
Changed:
< <
Convertir un fichier Postscript en JPEG (ou autre) avec GhostScript (en mode batch)
> >
Ainsi, les tables filles n'ont pas de clé primaire, mais juste une clé étrangère (resource_id) qui pointe vers la clé primaire de la table mère (cette clé étrangère peut aussi leur servir de clé primaire).
Changed:
< <
Pour info, sur Linux, c'est très simple, il suffit d'utiliser la commande "convert" (ou plus spécifique "ps2...")
> >
Cette relation d'héritage a un impact sur toutes les VUES de la table "resource", car à chaque fois qu'on veut accéder à une ressource,
il faut récupérer aussi les informations spécifiques à son type dans la table fille associée (via la clé étrangère resource_id).
Changed:
< <
Sous Windows, c'est un peu plus compliqué.
> >
Plus particulièrement, la vue "Create" (et "Update") devra contenir un sélecteur de type ("Type de ressource"),
et n'afficher que les champs spécifiques au type sélectionné (en plus des champs généraux de la table mère).
Cela amène à une nouvelle vue PersonSearch qui est équivalente au formulaire de Person/create,
sauf qu'au lieu de servir à créer une nouvelle personne, il sert à en CHERCHER.
L'ensemble des personnes trouvées sont affichées dans une vue "FOUND" semblable à Person/index (sauf que c'est une vue PARTIELLE et non pas COMPLETE).
Les recherches se font sans tenir compte des majuscules ou minuscules.
Changed:
< <
REMARQUE : pour faire la même chose en mode graphique,
il existe une interface graphique qui s'installe par-dessus GhostScript (en frontend),
c'est GhostView (gsview) :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier", par exemple "Apallieri"...
j'entre "Pallier" dans le champ "name", "Etienne" dans le champ "firstname", et "informaticien" dans le champ "job" :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier" ET le prénom EST EGAL à "Etienne" ET le job EST EGAL à "informaticien"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier" ET le prénom CONTIENT "Etienne" et le job CONTIENT "informaticien"
Added:
> >
Cette VUE "search" doit être accessible par un lien qui se trouve au début de la vue "index", sous la forme d'une icône en forme de LOUPE suivie de la mention "Search"
Added:
> >
Faire les tests d'acceptation (ACCEPTANCE TESTS)
Added:
> >
IX - Améliorer les vues
Added:
> >
1) ajouter les liens généraux suivants :
"login" (qui n'apparaît que si l'utilisateur n'est pas logué)
et les liens "logout", "update my registration" et "unregister" (qui n'apparaissent que si l'utilisateur est logué)
Changed:
< <
Migrer de Windows XP vers Windows 7
> >
2) Vue "view" : vue détaillée d'une ligne de table
Changed:
< <
Il faut acheter la licence Microsoft. La démarche dépend de la marque du PC.
> >
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
Changed:
< <
Pour un hp : aller sur le site hp et rechercher "windows upgrade"
> >
Ajouter les boutons "Edit", "Delete" et "Create a copy" (visibles uniquement avec le profil "admin")
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
Added:
> >
Masquer la clé primaire (id)
Added:
> >
La colonne du champ "name" est triable : en cliquant sur la colonne "name", on trie en ordre croissant, puis décroissant
Added:
> >
Le champ "name" est cliquable : en cliquant sur un nom, on va à la vue détaillée correspondante
Changed:
< <
Envoyer des mails avec Outlook quand on n'est pas au LABO
> >
Afficher le champ "name" des clés étrangères ; en cliquant dessus on va sur la vue détaillée
Added:
> >
Les colonnes des clés étrangères sont filtrables : dans la vue people/index, en cliquant sur la colonne "institutes_id" on doit pouvoir sélectionner un nom d'institut (name) et filtrer la vue en conséquence
Changed:
< <
1) "Creuser" un tunnel avec Putty
> >
Au-dessus de la liste d'une table, ajouter un "filtre externe" pour chaque table M-N associée :
par exemple, pour la vue people/index, ajouter au-dessus de la liste des personnes une liste d'expertises : en sélectionnant une expertise, on ne voit plus que les personnes associées à cette expertise
Changed:
< <
Créer une nouvelle session que vous appelerez par exemple "tunnel_mail_LABO",
et qui créera un tunnel entre le port local 9025 et le port SMTP (25) du serveur de mail LABO (GATEWAY).
> >
En début de page, ajouter un bouton "Add a new one"
Bien sûr, il faut tout remettre en place quand on revient au LABO (en fait, on pourrait aussi fonctionner en permanence avec le tunnel, même au LABO...)
(Le mieux est de placer cette ligne une fois pour toutes dans votre fichier de démarrage ~/.bash_profile, pour ne plus avoir à la taper)
Added:
> >
Si vous travaillez à l'intérieur du labo, pas besoin de l'étape suivante, il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Si vous êtes à l'extérieur du labo, continuez la lecture...
Ouvrir un tunnel avec mise en correspondance de 2 ports :
Line: 1592 to 1598
Il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Changed:
< <
c) Une fois la session idl terminée, ne pas oublier de...
détruire le tunnel en vous déconnectant d'hyperion (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
> >
Attention, une fois la session idl terminée, ne pas oublier de détruire le tunnel en vous déconnectant d'hyperion !!! (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
Bon, on peut encore améliorer les choses... si ça vous dit, allez voir un peu plus loin, juste après la partie IN ENGLISH.
Changed:
< <
Now, IN ENGLISH :
> >
Now, IN ENGLISH (and for Mac/Linux users only) :
(First, be sure you have removed any remaining license.dat file from your itt/license/ directory ; just drop it, you don't need it)
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
Added:
> >
(Pour les utilisateurs de Windows, faire un clic droit sur Poste de Travail, puis onglet "Variables d'environnement", puis entrer la variable nommée LM_LICENSE_FILE avec la valeur "1700@hyperion.cesr.fr:9700@localhost")
Utiliser la licence IDL hyperion depuis l'extérieur
> >
Utiliser mon IDL au labo ou bien à l'extérieur du labo (en une seule config)
Changed:
< <
Comment exécuter idl depuis mon pc/mac (mon idl à moi) depuis l'extérieur du labo, comme si j'étais au labo, et donc en profitant de la licence hyperion ???
> >
Problème : Comment exécuter mon idl (celui qui est installé localement sur mon pc/mac) au labo et même à l'extérieur du labo ???
Changed:
< <
Il suffit de 2 choses : un fichier de licence idl hyperion un peu modifié, et un tunnel
> >
Réponse : en profitant des licences du serveur hyperion
Changed:
< <
1) Fichier de licence
> >
En ce qui vous concerne, allez directement au point 2)
Changed:
< <
Récupérer le fichier de licence de hyperion license.dat et le copier dans votre installation IDL locale (de votre pc/mac), sous le dossier itt/license/
> >
1) Travail à faire pour l'administrateur système sur hyperion
Changed:
< <
Editer ce fichier pour en modifier la 2ème ligne comme suit :
> >
Modifier le fichier de licences /usr/local/itt/license/license.dat, remplacer la ligne : "DAEMON idl_lmgrd" par "DAEMON idl_lmgrd port=1701"
Changed:
< <
SERVER localhost 0021856ceeec 9700
> >
(cela force flexlm à utiliser le port 1701 pour idl_lmgrd)
Changed:
< <
(on a remplacé "hyperion" par "localhost" et "1700" par "9700")
> >
Relancer les service lmgrd et idl_lmgrd
Added:
> >
Si tout s'est bien passé, la commande "nmap hyperion.cesr.fr -p1700-1701" permet de voir que le port 1701 est bien ouvert
Changed:
< <
2) Créer un tunnel (entre mon pc et hyperion, via le GATEWAY)
Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2012-10-08 18:10 CEST
Interesting ports on hyperion.cesr.fr (195.83.102.174):
PORT STATE SERVICE
1700/tcp open unknown
1701/tcp open unknown
Changed:
< <
(
si ca ne marche pas, essayer plutôt ceci (mon exemple perso) :
ssh -t -L 9700:localhost:1700 epallier@GATEWAY ssh -L 1700:hyperion.cesr.fr:1700 pallier@hyperion.cesr.fr
)
> >
Nmap finished: 1 IP address (1 host up) scanned in 0.119 seconds
Deleted:
< <
Entrer le mot de passe pour GATEWAY (pour vous connecter de votre pc à GATEWAY)
Changed:
< <
Entrer le mot de passe pour hyperion (pour vous connecter de GATEWAY à hyperion)
> >
2) Pour vous (côté client), Il suffit de faire 2 choses sur votre pc/mac
a) Positionner une variable d'environnement
Positionner la variable d'environnement avec 2 serveurs de jetons (pour pouvoir bosser à l'INTERIEUR (port 1700 de hyperion) ET à l'EXTERIEUR (port 9700 de localhost) du labo sans jamais rien modifier) :
(remplacer MON_LOGIN_EMAIL par votre login utilisé pour le mail ou pour vous connecter à la passerelle du labo, et GATEWAY par le serveur passerelle du labo)
(Remarque pour l'admin système : attention, sur le localhost on a le choix de la correspondance du port 1700 d'hyperion (port 9700 local) mais pas pour le 1701)
Entrer le mot de passe pour GATEWAY (pour vous connecter de votre pc à GATEWAY)
Voilà, vous avez créé un tunnel entre votre pc/mac et hyperion, passant par GATEWAY (vous êtes d'ailleurs connecté à la passerelle).
Il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Changed:
< <
Une fois votre session idl terminée, n'oubliez pas de détruire le tunnel en vous déconnectant d'hyperion (il suffit de taper "exit" et vous serez déconnecté de hyperion ET de GATEWAY)
> >
c) Une fois la session idl terminée, ne pas oublier de...
détruire le tunnel en vous déconnectant d'hyperion (il suffit de taper "exit" et vous serez déconnecté de GATEWAY)
Bon, on peut encore améliorer les choses... si ça vous dit, allez voir un peu plus loin, juste après la partie IN ENGLISH.
Changed:
< <
On peut encore améliorer les choses... Voir plus loin, après la partie "ENGLISH"
> >
Now, IN ENGLISH :
Added:
> >
(First, be sure you have removed any remaining license.dat file from your itt/license/ directory ; just drop it, you don't need it)
Changed:
< <
IN ENGLISH :
> >
1) set a tunnel
Changed:
< <
1) Licence file
> >
Open a new terminal and create this tunnel :
Changed:
< <
Get the hyperion licence file license.dat and copy it into your LOCAL idl installation (on your pc/mac) under the itt/license/ directory
Utiliser la licence IDL hyperion depuis l'extérieur
Comment exécuter idl depuis mon pc/mac (mon idl à moi) depuis l'extérieur du labo, comme si j'étais au labo, et donc en profitant de la licence hyperion ???
Il suffit de 2 choses : un fichier de licence idl hyperion un peu modifié, et un tunnel
1) Fichier de licence
Récupérer le fichier de licence de hyperion license.dat et le copier dans votre installation IDL locale (de votre pc/mac), sous le dossier itt/license/
Editer ce fichier pour en modifier la 2ème ligne comme suit :
SERVER localhost 0021856ceeec 9700
(on a remplacé "hyperion" par "localhost" et "1700" par "9700")
2) Créer un tunnel (entre mon pc et hyperion, via le GATEWAY)
(
si ca ne marche pas, essayer plutôt ceci (mon exemple perso) :
ssh -t -L 9700:localhost:1700 epallier@GATEWAY ssh -L 1700:hyperion.cesr.fr:1700 pallier@hyperion.cesr.fr
)
Entrer le mot de passe pour GATEWAY (pour vous connecter de votre pc à GATEWAY)
Entrer le mot de passe pour hyperion (pour vous connecter de GATEWAY à hyperion)
Voilà, vous êtes connecté sur hyperion, via un tunnel passant par GATEWAY.
Il vous suffit maintenant de lancer votre idl LOCAL (votre logiciel idl installé sur votre pc/mac), comme d'habitude.
Une fois votre session idl terminée, n'oubliez pas de détruire le tunnel en vous déconnectant d'hyperion (il suffit de taper "exit" et vous serez déconnecté de hyperion ET de GATEWAY)
On peut encore améliorer les choses... Voir plus loin, après la partie "ENGLISH"
IN ENGLISH :
1) Licence file
Get the hyperion licence file license.dat and copy it into your LOCAL idl installation (on your pc/mac) under the itt/license/ directory
Edit this file and modify the 2nd line as below :
SERVER localhost 0021856ceeec 9700
(we just replaced "hyperion" with "localhost" and "1700" with "9700")
2) Tunnel
Type this command to create a tunnel between your mac and hyperion (via the irap gateway) :
Enter the gateway password (to connect from your mac to the gateway)
Enter the hyperion password (to connect from the gateway to hyperion)
You are now connected to hyperion (via the gateway).
Attention : Keep this connection opened as long as you are working with idl.
3) Run your local idl (from your mac)
It should not go to the limited demonstration session (7 mn) but allow you to work as long as you want...
4) Disconnect
Once you have finished with idl, do not forget to destroy the tunnel by just disconnecting from hyperion (type "exit" just once)
Comme je disais, on peut encore améliorer les choses... Comment ?
En s'arrangeant pour ne plus avoir aucun mot de passe à entrer grâce aux clés publique&privée.
Voici comment faire...
1) Créer une paire de clés privée/publique sur mon pc
$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/Users/pallier/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/pallier/.ssh/id_dsa.
Your public key has been saved in /Users/pallier/.ssh/id_dsa.pub.
2) Distribuer ensuite la clé publique de mon pc sur la passerelle du labo (que nous appelerons GATEWAY pour raison de sécurité)
La clé publique, doit être copiée sur le serveur distant dans ~/.ssh/authorized_keys. (La clé privée reste sur votre poste client)
Aller dans votre HOME
ssh-copy-id -i .ssh/id_dsa.pub GATEWAY
(
ou bien, si on ne dispose pas de la commande ssh-copy-id, l'exemple est ici donné pour moi :
$ cat .ssh/id_dsa.pub | ssh epallier@GATEWAY "cat - >>.ssh/authorized_keys"
)
Par exemple, je veux forwarder mes mails de pallier@planetoweb.cesr.fr vers ma boite cesr ou encore ma boite perso :
> >
Par exemple, je veux forwarder mes mails de pallier@planetoweb.cesr.fr vers ma boite LABO ou encore ma boite perso :
cd ~
Changed:
< <
créer un fichier ".forward" contenant mon adresse cesr ou perso
> >
créer un fichier ".forward" contenant mon adresse LABO ou perso
S'il s'agit de forwarder les mails adressés à root@planetoweb.cesr.fr, on peut utiliser la même solution, mais on peut aussi
ajouter cette ligne tout à la fin du fichier /etc/aliases
Line: 4428 to 4603
La mission ExoMars, de l’Agence Spatiale Européenne (ESA), est une mission du programme Aurora. Son objectif est de caractériser l’environnement biologique martien pour préparer l’exploration humaine de la planète rouge.
Changed:
< <
Instrument CESR
> >
Instrument LABO
Changed:
< <
EXLIBRIS serait capable d’effectuer une ablation des roches puis l’analyse de la composition de cette roche à la fois en chimie élémentaire (ultra-violet), en minéraux et composés organiques (Raman). Le CESR serait responsable de la partie LIBS (ultra-violet) et de la calibration de l’instrument. F. Rull Pérez (Centro de Astrobiologia , Espagne) serait en charge de la partie Raman.
> >
EXLIBRIS serait capable d’effectuer une ablation des roches puis l’analyse de la composition de cette roche à la fois en chimie élémentaire (ultra-violet), en minéraux et composés organiques (Raman). Le LABO serait responsable de la partie LIBS (ultra-violet) et de la calibration de l’instrument. F. Rull Pérez (Centro de Astrobiologia , Espagne) serait en charge de la partie Raman.
Contexte de réalisation
Mission ESA : Tir prévu en 2013.
Line: 4801 to 4976
4) C'est très bien tout ça, mais comment je fais depuis chez moi ???
Changed:
< <
C'est un peu plus compliqué car il faut installer un tunnel qui passe par le firewall CESR.
> >
C'est un peu plus compliqué car il faut installer un tunnel qui passe par le GATEWAY LABO.
a) Creuser un tunnel
Line: 4809 to 4984
Exécuter Putty
Changed:
< <
Si vous avez déjà une session vers FIREWALL, inutile d'en recréer une autre, vous pouvez l'utiliser. Sinon, il faut créer une nouvelle session :
> >
Si vous avez déjà une session vers GATEWAY, inutile d'en recréer une autre, vous pouvez l'utiliser. Sinon, il faut créer une nouvelle session :
Changed:
< <
Host name : FIREWALL
> >
Host name : GATEWAY
Port : 22
Changed:
< <
Saved Sessions : FIREWALL (ou ce que vous voulez, par exemple "le firewall du cesr")
> >
Saved Sessions : GATEWAY (ou ce que vous voulez, par exemple "le GATEWAY du LABO")
Dans le panneau de gauche (Category:), cliquer sur l'arbre "Connection", puis "SSH", puis "Tunnels"
Line: 4831 to 5006
Cliquer sur bouton "Save"
Changed:
< <
Ouvrir cette session (FIREWALL) que vous venez de créer, et se connecter sur FIREWALL (avec votre mot de passe mail).
> >
Ouvrir cette session (GATEWAY) que vous venez de créer, et se connecter sur GATEWAY (avec votre mot de passe mail).
b) Créer une session graphique
Line: 4916 to 5091
Changed:
< <
Envoyer des mails avec Outlook quand on n'est pas au CESR
> >
Envoyer des mails avec Outlook quand on n'est pas au LABO
1) "Creuser" un tunnel avec Putty
Changed:
< <
Créer une nouvelle session que vous appelerez par exemple "tunnel_mail_cesr",
et qui créera un tunnel entre le port local 9025 et le port SMTP (25) du serveur de mail cesr (FIREWALL).
> >
Créer une nouvelle session que vous appelerez par exemple "tunnel_mail_LABO",
et qui créera un tunnel entre le port local 9025 et le port SMTP (25) du serveur de mail LABO (GATEWAY).
Changed:
< <
La procédure est décrite sur la faq informatique du cesr :
> >
La procédure est décrite sur la faq informatique du LABO :
Clic sur bouton "Paramètres supplémentaires...", clic sur onglet "Options avancées"
Dans le champ "Serveur Sortant (SMTP)", remplacer "25" par "9025"
Changed:
< <
Bien sûr, il faut tout remettre en place quand on revient au cesr (en fait, on pourrait aussi fonctionner en permanence avec le tunnel, même au CESR...)
> >
Bien sûr, il faut tout remettre en place quand on revient au LABO (en fait, on pourrait aussi fonctionner en permanence avec le tunnel, même au LABO...)
Synchroniser Outlook 2007 Calendar et Google Calendar
Une personne peut avoir plusieurs liens avec une ressource (plusieurs liens entre les tables "people" et "resources"), ce qui veut dire qu'elle peut jouer plusieurs rôles par rapport à une ressource.
Ainsi, au lieu d'avoir seulement une clé étrangère "resources_id" dans la table "people", nous en aurons plusieurs avec des noms différents :
resource_provider_id : la personne qui a donné l'information sur la ressource (et qui l'a saisit)
Line: 356 to 362
Ces 3 clés pointent toutes vers la même clé primaire resource.id, et sont donc des "alias".
Améliorer les actions CRUD en conséquence
Changed:
< <
Ajout d'une relation réflexive sur "institutes" (dont une application est la relation hiérarchique) :
> >
b) Relation réflexive (d'une table sur elle-même)
Ajout d'une relation réflexive sur "institutes" (dans ce cas particulier, il s'agit d'une relation hiérarchique) :
un institut peut appartenir à un autre institut (de niveau hiérarchique supérieur ; par exemple, le "CNRS" regroupe plusieurs instituts, "l'OMP" regroupe plusieurs laboratoires dont l'IRAP…)
cela revient seulement à ajouter un champ "institute_id" dans la table institutes (qui pointe sur la table institute, lien réflexif)
améliorer les actions CRUD en conséquence
Added:
> >
c) Relation d'héritage ou spécialisation (1:1)
Une ressource peut être de différents types (ajouter la table "resourcetype") :
data
info (information, document...)
website
datacenter
chaque type de ressource est une spécialisation du type général "resource".
On aura donc 4 nouvelles tables filles "resourcedata", "resourceinfo", "resourcewebsite", "resourcedatacenter" qui "hériteront" de la table mère (générique) "resource" pour l'étendre chacune avec sa spécificité.
On peut représenter ce lien d'héritage par une relation 1-1 entre chacune de ces 4 tables filles et la table mère "resource".
Aucune des tables filles n'a d'existence propre, chacune dépend de la table mère "resource".
Ainsi, les tables filles n'ont pas de clé primaire, mais juste une clé étrangère (resource_id) qui pointe vers la clé primaire de la table mère (cette clé étrangère peut aussi leur servir de clé primaire).
Cette relation d'héritage a un impact sur toutes les VUES de la table "resource", car à chaque fois qu'on veut accéder à une ressource,
il faut récupérer aussi les informations spécifiques à son type dans la table fille associée (via la clé étrangère resource_id).
Plus particulièrement, la vue "Create" (et "Update") devra contenir un sélecteur de type ("Type de ressource"),
et n'afficher que les champs spécifiques au type sélectionné (en plus des champs généraux de la table mère).
Ajouter dans la table resource un champ "URL" (général à tous les types)
Voici les informations spécifiques à chaque type, et donc présent dans les tables filles respectives :
table data :
volume (en MB) :
restricted (oui/non)
table info (information, document...) :
langage (champ texte liste : English, French, Spanish...)
tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
Changed:
< <
...
> >
3) Récupération du mot de passe (lost password)
Line: 292 to 297
L'utilisateur saisit son email et clique sur "submit" pour qu'on lui envoie un nouveau mot de passe par mail (le mot de passe est aussi mis à jour dans la database)
Added:
> >
Test
4) Procédure de désinscription (ACTION unregister)
Line: 303 to 310
d) la personne est automatiquement déconnectée
Added:
> >
e) Test
VII - Améliorer le CRUD
Line: 389 to 400
2) Vue "view" : vue détaillée d'une ligne de table
Added:
> >
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
Ajouter les boutons "Edit", "Delete" et "Create a copy" (visibles uniquement avec le profil "admin")
Pour le formulaire Person, le bouton "Edit" est aussi visible si la personne connectée correspond à la fiche visualisée.
3) Action "index" : vue globale d'une table
Added:
> >
Ajouter une checkbox "Show dates" (visible uniquement avec profil "admin"), désactivée par défaut : quand on l'active, il faut afficher les dates (created, updated)
Masquer la clé primaire (id)
La colonne du champ "name" est triable : en cliquant sur la colonne "name", on trie en ordre croissant, puis décroissant
Line: 412 to 427
4) Ajouter les nouveaux tests nécessaires
Changed:
< <
> >
5) Ajouter une page contenant tous les tests, avec un bouton permettant de lancer tous les tests à la suite "LAUNCH ALL TESTS"
L'utilisateur saisit son email et clique sur "submit" pour qu'on lui envoie un nouveau mot de passe par mail (le mot de passe est aussi mis à jour dans la database)
Added:
> >
4) Procédure de désinscription (ACTION unregister)
a) une personne clique sur un lien "unregister"
b) une confirmation est demandée via une fenêtre javascript : "Are you sure that you want to unregister ?" OK/CANCEL
c) l'action "unregister" est exécutée, la personne n'est pas supprimée de la base, mais juste marquée "inactive"
d) la personne est automatiquement déconnectée
VII - Améliorer le CRUD
Line: 368 to 383
IX - Améliorer les vues
Changed:
< <
1) ajouter un lien général "logout"
> >
1) ajouter les liens généraux suivants :
"login" (qui n'apparaît que si l'utilisateur n'est pas logué)
et les liens "logout", "update my registration" et "unregister" (qui n'apparaissent que si l'utilisateur est logué)
2) Vue "view" : vue détaillée d'une ligne de table
Changed:
< <
Ajouter les boutons "Delete" et "Create a copy"
> >
Ajouter les boutons "Edit", "Delete" et "Create a copy" (visibles uniquement avec le profil "admin")
Pour le formulaire Person, le bouton "Edit" est aussi visible si la personne connectée correspond à la fiche visualisée.
Ne pas oublier de noter tout ce que tu fais. Rédige au fur et à mesure (avec OpenOffice).
Changed:
< <
NOUVELLES MODIFS FAITES :
> >
NOUVELLES MODIFS FAITES :
Changed:
< <
section VI-3
> >
3 mai :
section VI-3 (lost password)
section IX-1 (logout)
5 Avril :
section VII-3 (crud)
Plus tard :
(pas encore sûr, à réfléchir) ajouter un script qui permet de définir un tableau de champs obligatoires pour un Modèle donné ==> Ces champs devront obligatoirement être saisis dans les vues associées au Modèle (voir http://book.cakephp.org/1.3/view/1147/required)
Line: 234 to 245
* peut modifier son email (login) et/ou son mot de passe
...
Changed:
< <
3) Amélioration de la procédure d'enregistrement (inscription) d'une personne :
> >
VI - ENREGISTREMENT DES UTILISATEURS (registration)
1) Amélioration de la procédure d'enregistrement (inscription) d'une personne :
(voir s'il n'existe pas déjà un plugin cakephp pour gérer ça, car c'est assez classique au début)
Line: 259 to 273
Ajouter/modifier les tests nécessaires
Changed:
< <
4) Ajouter un captcha sur la fiche d'inscription
> >
2) Ajouter un captcha sur la fiche d'inscription
Ajouter/modifier les tests nécessaires :
tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
...
Added:
> >
3) Récupération du mot de passe (lost password)
Changed:
< <
VI - Améliorer le CRUD
> >
Sur le formulaire de login, ajouter (à droite du bouton LOGIN) un lien "register" (pour s'enregistrer) et un lien "forgot password" (mot de passe oublié)
Le lien "forgot password" pointe vers un formulaire de modification du mot de passe (Person/PasswordUpdate) contenant juste 1 champ "email" et un bouton "SUBMIT"
L'utilisateur saisit son email et clique sur "submit" pour qu'on lui envoie un nouveau mot de passe par mail (le mot de passe est aussi mis à jour dans la database)
VII - Améliorer le CRUD
1) Bien gérer complètement les relations 1-N
Line: 315 to 338
4) Ajouter les nouveaux tests nécessaires
Changed:
< <
VII - Ajout d'une nouvelle action dans TOUS les Contrôleurs : search
> >
VIII - Ajout d'une nouvelle action dans TOUS les Contrôleurs : search
ex : Person/search
Line: 343 to 366
Faire les tests d'acceptation (ACCEPTANCE TESTS)
Changed:
< <
VIII - Améliorer les vues
> >
IX - Améliorer les vues
1) ajouter un lien général "logout"
Changed:
< <
1) Vue "view" : vue détaillée d'une ligne de table
> >
2) Vue "view" : vue détaillée d'une ligne de table
Ajouter les "Delete" et "Create a copy"
Changed:
< <
2) Action "index" : vue globale d'une table
> >
3) Action "index" : vue globale d'une table
Masquer la clé primaire (id)
Line: 366 to 391
En début de page, ajouter un bouton "Add a new one"
VII - Ajout d'une nouvelle action dans TOUS les Contrôleurs : search
ex : Person/search
Cela amène à une nouvelle vue PersonSearch qui est équivalente au formulaire de Person/create,
sauf qu'au lieu de servir à créer une nouvelle personne, il sert à en CHERCHER.
L'ensemble des personnes trouvées sont affichées dans une vue "FOUND" semblable à Person/index (sauf que c'est une vue PARTIELLE et non pas COMPLETE).
Les recherches se font sans tenir compte des majuscules ou minuscules.
En bas du formulaire, 2 boutons :
SEARCH
EXACT SEARCH
Exemples de requêtes possibles :
j'entre "Pallier" dans le champ "name" :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier", par exemple "Apallieri"...
j'entre "Pallier" dans le champ "name", "Etienne" dans le champ "firstname", et "informaticien" dans le champ "job" :
un clic sur "EXACT SEARCH" me donne la liste des personnes dont le nom EST EGAL à "Pallier" ET le prénom EST EGAL à "Etienne" ET le job EST EGAL à "informaticien"
un clic sur "SEARCH" me donne la liste des personnes dont le nom CONTIENT "Pallier" ET le prénom CONTIENT "Etienne" et le job CONTIENT "informaticien"
Cette VUE "search" doit être accessible par un lien qui se trouve au début de la vue "index", sous la forme d'une icône en forme de LOUPE suivie de la mention "Search"
Faire les tests d'acceptation (ACCEPTANCE TESTS)
VIII - Améliorer les vues
1) Vue "view" : vue détaillée d'une ligne de table
- resources_sciencecases : avec les champs resources_id et sciencecases_id (les 2 clés étrangères formant la clé primaire de la table)
- expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table) et le champ supplémentaire "since" (date à laquelle l'expertise a été acquise)
> >
resources_sciencecases : avec les champs resources_id et sciencecases_id (les 2 clés étrangères formant la clé primaire de la table)
expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table)
Tous les champs sont obligatoires (NOT NULL), sauf people.job (default NULL).
Added:
> >
Toutes les clés primaires (id) sont autoincrémentées.
Added:
> >
Les champs "created" et "updated" sont gérés automatiquement par cakephp.
Added:
> >
Ajouter la contrainte "on delete CASCADE" (avec MysqlWorkbench) sur les clés étrangères des tables M-N (resources_sciencecases et expertises_people)
Added:
> >
Ajouter la contrainte "on delete NULL" sur toutes les clés étrangères des autres tables (people, resources)
Added:
> >
Générer le script sql de création de la base.
Added:
> >
Vérifier que MysqlWorkbench ajoute bien les contraintes sur les clés étrangères (FK = "Foreign Key")
Alimenter les tables avec des données quelconques
Line: 277 to 284
Même chose pour Resource (relation M-N avec Sciencecase)
Added:
> >
Gestion des champs supplémentaires d'une table associative : exemple de la relation entre Person et Expertise :
expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table) et le champ supplémentaire "since" (date à laquelle l'expertise a été acquise)
Créer quelques personnes avec des rôles (profils) différents :
Changed:
< <
- 'user1', profil 'admin' (tous les droits)
- 'user2' et 'user3', profil 'normal', utilisateur normal
- 'user4', profil 'priv', utilisateur privilégié
- 'user5', profil 'validator', utilisateur pouvant valider d'autres utilisateurs
> >
'user1', profil 'admin' (tous les droits)
'user2' et 'user3', profil 'normal', utilisateur normal
'user4', profil 'priv', utilisateur privilégié
'user5', profil 'validator', utilisateur pouvant valider d'autres utilisateurs
Une personne de profil 'admin' a un droit CRUD (créer/lire/modifier/supprimer) sur toutes les tables.
Une personne de profil 'priv' :
Changed:
< <
- a un droit CRUD seulement sur la table 'institutes'
- peut modifier le profil de toutes les personnes (sauf le sien)
> >
a un droit CRUD seulement sur la table 'institutes'
peut modifier le profil de toutes les personnes (sauf le sien)
Ajouter les tests nécessaires :
Changed:
< <
- tester que 'user1' peut tout faire (faire juste quelques tests, pas tout)
- tester que 'user4' :
- peut ajouter un nouvel institut
- peut modifier le profil d'une personne (mais pas le sien)
- tester que 'user2' :
- ne peut pas modifier une ressource qui ne lui appartient pas
- peut ajouter une nouvelle ressource, et la modifier ensuite
- peut modifier son email (login) et/ou son mot de passe
> >
tester que 'user1' peut tout faire (faire juste quelques tests, pas tout)
tester que 'user4' : * peut ajouter un nouvel institut * peut modifier le profil d'une personne (mais pas le sien)
tester que 'user2' : * ne peut pas modifier une ressource qui ne lui appartient pas * peut ajouter une nouvelle ressource, et la modifier ensuite * peut modifier son email (login) et/ou son mot de passe
...
3) Amélioration de la procédure d'enregistrement (inscription) d'une personne :
Line: 231 to 238
f) si un validateur invalide l'inscription, la personne reçoit un mail pour l'en informer ==> son "status" passe à "invalidated"
Ajouter les actions suivantes au Contrôleur "person" :
Changed:
< <
- validate (profil 'validator') : pour valider une personne (champ "status")
- invalidate (profil 'validator') : pour invalider une personne
- deleteInvalidated (profil 'priv') : pour supprimer les personnes ayant un statut "invalidated"
- activate (profil 'priv') : pour activer une personne (champ "active")
- deactivate (profil 'priv') : pour désactiver une personne
> >
validate (profil 'validator') : pour valider une personne (champ "status")
invalidate (profil 'validator') : pour invalider une personne
deleteInvalidated (profil 'priv') : pour supprimer les personnes ayant un statut "invalidated"
activate (profil 'priv') : pour activer une personne (champ "active")
deactivate (profil 'priv') : pour désactiver une personne
Ajouter/modifier les tests nécessaires
4) Ajouter un captcha sur la fiche d'inscription
Ajouter/modifier les tests nécessaires :
Changed:
< <
- tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
- tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
> >
tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
Ne pas oublier de noter tout ce que tu fais. Rédige au fur et à mesure (avec OpenOffice).
NOUVELLES MODIFS FAITES :
section VI-3
(pas encore sûr, à réfléchir) ajouter un script qui permet de définir un tableau de champs obligatoires pour un Modèle donné ==> Ces champs devront obligatoirement être saisis dans les vues associées au Modèle (voir http://book.cakephp.org/1.3/view/1147/required)
III - En s'inspirant du tutoriel "blog", commmencer à construire une architecture à partir d'un sous-ensemble de la BDD Europlanet
1) Ce projet est géré en versions avec subversion (plugin Eclipse subclipse)
2) Construire un schéma d'une petite BDD avec MysqlWorkbench
Ce schéma contient 7 tables principales :
- people (lien N-1 avec institutes, status, et profiles, et 1-N avec resources) : id, name, firstname, email, password, status, active, job, created, updated (le champ "active" est un booléen VRAI par défaut)
- status : id, name (avec les valeurs suivantes pour name : NULL, 'registered', 'invalidated', 'validated')
- profiles : id, name, level (level indique la hiérarchie ; name et level ont les valeurs suivantes : {'admin',10}, {'priv',5}, {'validator',3}, {'normal',0} ; donc on a la hiérarchie admin > priv > validator > normal)
- institutes : id, name, created, updated
- expertises : id, name (lien M-N avec people)
- resources (lien M-N avec sciencases) : id, name, created, updated
- sciencecases : id, name, created, updated
Pour gérer les relation M-N, il faudra créer les tables intermédiaires suivantes (voir la convention de nommage dans cakephp : http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#hasandbelongstomany-habtm) :
- resources_sciencecases : avec les champs resources_id et sciencecases_id (les 2 clés étrangères formant la clé primaire de la table)
- expertises_people : avec les champs expertises_id et people_id (les 2 clés étrangères formant la clé primaire de la table) et le champ supplémentaire "since" (date à laquelle l'expertise a été acquise)
Tous les champs sont obligatoires (NOT NULL), sauf people.job (default NULL).
Toutes les clés primaires (id) sont autoincrémentées.
Les champs "created" et "updated" sont gérés automatiquement par cakephp.
Ajouter la contrainte "on delete CASCADE" (avec MysqlWorkbench) sur les clés étrangères des tables M-N (resources_sciencecases et expertises_people)
Ajouter la contrainte "on delete NULL" sur toutes les clés étrangères des autres tables (people, resources)
Générer le script sql de création de la base.
Vérifier que MysqlWorkbench ajoute bien les contraintes sur les clés étrangères (FK = "Foreign Key")
Alimenter les tables avec des données quelconques
3) Configurer l'accès à la BDD
login : epn
pass : pass
Par défaut, l'action "people/index" ne doit afficher que les personnes dont le champ "active" est à TRUE et le champ "status" vaut "validated"
5) Lancer les tests générés par "bake" (avec phpUnit, inclus dans Xampp ?) pour tester les modèles et les contrôleurs
http://book.cakephp.org/2.0/en/development/testing.html
cake bake fixture all ?
cake bake test all ?
Depuis cakephp 2.1 :
Console/cake test app/Model/Post.php
Console/cake test app/Controller/PostsController.php
6) Ajouter la validation des champs de tous les formulaires
http://book.cakephp.org/2.0/en/models/data-validation.html
"bake" ajoute des validations par défaut. Les étendre si nécessaire pour que toutes les validations soient générées automatiquement, en fonction du type des champs.
Vérifier que les champs obligatoires sont bien obligatoires en saisie.
Ajouter un test pour s'assurer qu'une personne est obligée de remplir tous les champs (sauf people.job) quand elle s'enregistre.
1) Ajouter l'authentification (AUTH)
Login = email
Auth (et Acl) doivent avoir pour support la table "people" (et status et profiles).
Auth (et Acl) impliquent aussi l'usage des Sessions (http://book.cakephp.org/2.0/en/development/sessions.html)
Astuce : dans la session, stocker l'id de la personne, et non pas son email (car l'email peut changer, mais pas l'id)
Toute personne non authentifiée (accès anonyme) peut :
- lire (R ) toutes les tables, sauf la table "resources"
- s'enregistrer (droit C sur la table people)
Toute personne authentifiée peut :
- lire (R ) toutes les tables (y-compris "resources")
- modifier (U) sa fiche (sauf son profil), mais pas celle des autres
- créer (C ) une ressource
- modifier/supprimer (UD) une ressource qu'elle a créée, mais pas celles des autres
- modifier (U) un institut auquel elle appartient
Gérer le login et le logout
Ajouter les tests nécessaires :
(Utiliser des "fixtures", cf section "Fixtures" dans http://book.cakephp.org/2.0/en/development/testing.html)
(cake bake fixture all ?)
Tester qu'une personne non authentifiée :
- peut lire la table 'resource'
- peut s'enregistrer
- ne peut pas modifier une table
Tester qu'une personne authentifiée peut :
…
Faire un test login/logout complet selon le scénario suivant :
- une personne se logue
- vérifier qu'elle peut créer une ressource
- elle se délogue
- vérifier qu'elle ne peut plus créer une ressource
2) Ajouter le contrôle d'accès (ACL)
Créer quelques personnes avec des rôles (profils) différents :
- 'user1', profil 'admin' (tous les droits)
- 'user2' et 'user3', profil 'normal', utilisateur normal
- 'user4', profil 'priv', utilisateur privilégié
- 'user5', profil 'validator', utilisateur pouvant valider d'autres utilisateurs
Une personne de profil 'admin' a un droit CRUD (créer/lire/modifier/supprimer) sur toutes les tables.
Une personne de profil 'priv' :
- a un droit CRUD seulement sur la table 'institutes'
- peut modifier le profil de toutes les personnes (sauf le sien)
Ajouter les tests nécessaires :
- tester que 'user1' peut tout faire (faire juste quelques tests, pas tout)
- tester que 'user4' :
- peut ajouter un nouvel institut
- peut modifier le profil d'une personne (mais pas le sien)
- tester que 'user2' :
- ne peut pas modifier une ressource qui ne lui appartient pas
- peut ajouter une nouvelle ressource, et la modifier ensuite
- peut modifier son email (login) et/ou son mot de passe
...
3) Amélioration de la procédure d'enregistrement (inscription) d'une personne :
(voir s'il n'existe pas déjà un plugin cakephp pour gérer ça, car c'est assez classique au début)
a) une personne remplit sa fiche d'enregistrement et la soumet (SUBMIT) ==> elle est enregistrée dans la table people avec "status" à NULL
b) elle reçoit un 1er mail de confirmation avec un lien de validation
c) elle clique sur le lien de validation, ce qui valide son inscription ==> son champ "status" passe à "registered" ; les validateurs reçoivent un mail pour les avertir de cette inscription, avec un lien vers la page du site permettant de valider ou invalider la personne
d) elle reçoit un 2e mail de confirmation lui disant qu'elle est inscrite, MAIS qu'elle doit attendre que son inscription soit validée par un 'validateur', et qu'elle recevra un mail pour le lui confirmer
e) si un validateur valide l'inscription, la personne reçoit un mail pour l'en informer (à partir de là, elle peut se connecter au site) ==> son "status" passe à "validated"
f) si un validateur invalide l'inscription, la personne reçoit un mail pour l'en informer ==> son "status" passe à "invalidated"
Ajouter les actions suivantes au Contrôleur "person" :
- validate (profil 'validator') : pour valider une personne (champ "status")
- invalidate (profil 'validator') : pour invalider une personne
- deleteInvalidated (profil 'priv') : pour supprimer les personnes ayant un statut "invalidated"
- activate (profil 'priv') : pour activer une personne (champ "active")
- deactivate (profil 'priv') : pour désactiver une personne
Ajouter/modifier les tests nécessaires
4) Ajouter un captcha sur la fiche d'inscription
Ajouter/modifier les tests nécessaires :
- tester qu'une personne ne peut pas s'enregistrer si le captcha n'est pas bon
- tester qu'une personne peut s'enregistrer si le captcha est bon (et tout le reste)
...
VI - Améliorer le CRUD
1) Bien gérer complètement les relations 1-N
Actions sur Person (relation N-1 avec Institute) :
create : doit permettre d'associer la personne à un institut (via liste de noms)
update : doit permettre de modifier l'institut associé (via liste de noms)
index : doit permettre de voir toutes les personnes avec le nom (name) de l'institut associé ; un clic sur un institut doit amener à sa vue détaillée
view : doit afficher le nom (name) de l'institut associé
Action sur Institute (relation 1-N avec Person) :
view : doit afficher toutes les personnes associées
2) Bien gérer complètement les relations M-N
Actions sur Person (relation M-N avec Expertise) :
create : doit permettre d'ajouter des expertises (ET une date "since")
update : doit permettre de modifier les expertises associées
view : doit permettre de voir toutes les expertises associées
Idem pour Expertise (lien vers Person)
Même chose pour Resource (relation M-N avec Sciencecase)
3) Gérer d'autres types de relations
Ajout de plusieurs rôles différents entre 2 mêmes tables : voir http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#multiple-relations-to-the-same-model
Une personne peut avoir plusieurs liens avec une ressource (plusieurs liens entre les tables "people" et "resources"), ce qui veut dire qu'elle peut jouer plusieurs rôles par rapport à une ressource.
Ainsi, au lieu d'avoir seulement une clé étrangère "resources_id" dans la table "people", nous en aurons plusieurs avec des noms différents :
resource_provider_id : la personne qui a donné l'information sur la ressource (et qui l'a saisit)
resource_owner_id : le propriétaire de la ressource
resource_contact_id : le contact pour la ressource
Ces 3 clés pointent toutes vers la même clé primaire resource.id, et sont donc des "alias".
Améliorer les actions CRUD en conséquence
Ajout d'une relation réflexive sur "institutes" (dont une application est la relation hiérarchique) :
un institut peut appartenir à un autre institut (de niveau hiérarchique supérieur ; par exemple, le "CNRS" regroupe plusieurs instituts, "l'OMP" regroupe plusieurs laboratoires dont l'IRAP…)
cela revient seulement à ajouter un champ "institute_id" dans la table institutes (qui pointe sur la table institute, lien réflexif)
améliorer les actions CRUD en conséquence
4) Ajouter les nouveaux tests nécessaires
VII - Améliorer les vues
1) Vue "view" : vue détaillée d'une ligne de table
Ajouter les "Delete" et "Create a copy"
2) Action "index" : vue globale d'une table
Masquer la clé primaire (id)
La colonne du champ "name" est triable : en cliquant sur la colonne "name", on trie en ordre croissant, puis décroissant
Le champ "name" est cliquable : en cliquant sur un nom, on va à la vue détaillée correspondante
Afficher le champ "name" des clés étrangères ; en cliquant dessus on va sur la vue détaillée
Les colonnes des clés étrangères sont filtrables : dans la vue people/index, en cliquant sur la colonne "institutes_id" on doit pouvoir sélectionner un nom d'institut (name) et filtrer la vue en conséquence
Au-dessus de la liste d'une table, ajouter un "filtre externe" pour chaque table M-N associée :
par exemple, pour la vue people/index, ajouter au-dessus de la liste des personnes une liste d'expertises : en sélectionnant une expertise, on ne voit plus que les personnes associées à cette expertise
En début de page, ajouter un bouton "Add a new one"
$> netstat -ant|grep 8080
tcp4 0 0 195.83.102.52.54533 195.83.102.176.8080 ESTABLISHED
tcp6 0 0 ::1.8080 ::1.53481 ESTABLISHED
tcp6 0 0 ::1.53481 ::1.8080 ESTABLISHED
tcp6 0 0 ::1.8080 ::1.50287 ESTABLISHED
tcp6 0 0 ::1.50287 ::1.8080 ESTABLISHED
tcp46 0 0 *.8080 *.* LISTEN
Je vois ainsi que ma machine est connectée à 195.83.102.176 via le port 8080 en TCP
Pour savoir qui c'est, j'utilise la commande "host" ou "nslookup" :
$> host 195.83.102.176
Idem pour mysql :
$> netstat -ant | grep 3306
This tells me how many connections of different types of state I have on my machine.
I can run a similar command to see a complete picture of the state of all the connections made to my web server:
Exceptionnellement, sur un projet avec différents groupes (mais uniquement si nécessaire car ralentit les accès svn et alourdit la gestion) :
- ACL : contrôle d'accès basé sur les chemins :
(grâce au module authz_svn_module et à la directive AuthzSVNAccessFile), pour pouvoir réserver certains répertoires à certains groupes...
Exemple de config (chemcam) authentifiée mais SANS ACL :
DAV svn
ErrorDocument 404 default
# Only 1 repository :
SVNPath /home/projects/chemcam/svn
# Many repositories :
# any "/svn/foo" URL will map to a repository /home/svn/foo
#SVNParentPath /home/svn
#SVNListParentPath on
# Desactiver completement les controles sur les chemins (par defaut = on)
SVNPathAuthz off
# For any operations other than these (GET, PROFIND...), require an authenticated user
#
Require valid-user
#
# AUTH
AuthType Basic
AuthName "CHEMCAM Subversion repository"
# password file :
AuthUserFile /chemin/vers/fichier/des/mots/de/passe
# For any operations other than these, require an authenticated user (this would allow anybody to READ without authentication)
# Custom log file and format :
LogFormat "%t %u %h %{SVN-ACTION}e" svn
CustomLog logs/journal-svn.log svn env=SVN-ACTION
Exemple de config (chemcam) authentifiée et AVEC ACL :
DAV svn
ErrorDocument 404 default
# Only 1 repository :
SVNPath /home/projects/chemcam/svn
# Many repositories :
# any "/svn/foo" URL will map to a repository /home/svn/foo
#SVNParentPath /home/svn
#SVNListParentPath on
# Desactiver completement les controles sur les chemins (par defaut = on)
SVNPathAuthz on
# ACL
# politique de controle d'acces (uses apache module mod_authz_svn)
AuthzSVNAccessFile /chemin/vers/fichier/police_acces_svn
# For any operations other than these (GET, PROFIND...), require an authenticated user
#
Require valid-user
#
# AUTH
AuthType Basic
AuthName "CHEMCAM Subversion repository"
# password file :
AuthUserFile /chemin/vers/fichier/des/mots/de/passe
# For any operations other than these, require an authenticated user (this would allow anybody to READ without authentication)
# Custom log file and format :
LogFormat "%t %u %h %{SVN-ACTION}e" svn
CustomLog logs/journal-svn.log svn env=SVN-ACTION
Format du fichier de police d'accès aux répertoires du projet svn (nommé police_acces_svn ci-dessus) :
[groups]
# Virtual Machine only group :
cc-vm = user1, user20, user7
# Privileged access group :
cc-privileged = user3, user2, user6, user8, user30
[/]
# cc-privileged group has total access to the project (and no one else)
@cc-privileged = rw
# access given to ALL users !!!
#* = rw
[/trunk/vm]
# cc-vm group has read only access to the /vm dir (and no other dir)
@cc-vm = r
# cc-vm group has no access at all to the /vm dir
#@cc-vm =
(il suffit de placer /Applications/XAMPP/xamppfiles/bin dans mon $PATH pour que j'ai accès à toutes les commandes de xampp directement, telles que "mysql")
/Applications/XAMPP/xamppfiles/bin/mysql appelle par ex.MySQL.
By default, Vim runs in "compatible" mode. That is, it acts a lot like traditional vi, without the improvements. Unless you want a maximally vi-compatible version of vim, I recommend that you copy the standard startup files to your home directory, and name them .vimrc and .gvimrc.
Ce que j'ai fait simplement :
1) recherche de vimrc_example :
locate vimrc
2) Copie locale :
cp /usr/share/vim/vim73/vimrc_example.vim .vimrc
Installation AMP avec XAMPP (solution la plus simple, bien pour le développement, mais pas très blindée pour un serveur de production)
XAMPP est installé dans le répertoire/Applications/XAMPP
3) Démarrer
sudo /Applications/XAMPP/xamppfiles/xampp start
Sur l'écran devrait apparaitre les instructions suivantes:
Démarre XAMPP pour MacOS X 1.7.3...
XAMPP: Démarre Apache avec SSL...
XAMPP: Démarre MySQL...
XAMPP: Démarre ProFTPD...
XAMPP démarré.
Moi j'ai plutôt un pb avec proftpd, sans doute incompatible avec mac :
File permissions are being checked...ok.
Starting XAMPP for Mac OS X 1.7.3...
XAMPP: Starting Apache...ok.
XAMPP: Starting MySQL...ok.
XAMPP: Starting ProFTPD...XAMPP/XAMPP/xamppfiles/xampp: line 184: /Applications/XAMPP/xamppfiles//var/proftpd/start.err: No such file or directory
fail.
Contents of "/Applications/XAMPP/xamppfiles//var/proftpd/start.err":
cat: /Applications/XAMPP/xamppfiles//var/proftpd/start.err: No such file or directory
Si plus tard on remplace la page d'accueil de XAMPP par la sienne, on peut toujours joindre la page d'accueil de XAMPP avec http://localhost/xampp/
5) Aspects sécurité
Comme cela a déjà été expliqué antérieurement XAMPP n'est pas fait pour l'emploi de production, mais seulement pour développeur et l'environnement du développement. Cela a pour suite que XAMPP est volontairement préconfiguré pour ne pas être restrictif et être au contraire trés ouvert. Pour un développeur cela est idéal qu'il ne soit pas limité par les limites du systéme. Par contre pour un emploi en production cela est absolument pas recommendable.
Ici, une liste de choses donc XAMPP est volontairement(!) insécurisé:
1. L'administrateur (root)MySQL n'a pas de mot de passe.
2. Le démon MySQL est joignable par le réseau.
3. Le démon ProFTPD utilise le mot de passe "xampp".
4. PhpMyAdmin est joignable par le réseau.
5. MySQL et Apache fonctionne sous le même utilisateur (nobody)
Dans la page XAMPP-Demo (que l'on trouve sous http://localhost) il y a le point "Security check". À cet endroit on peut faire apparaître le niveau de sécurité actuel de XAMPP.
Si on veut utiliser XAMPP en réseau , pour que le serveur XAMPP soit accessible par d'autres utilisateurs, alors il faut impérativement exécuter les commandes suivantes avec lesquelles ont pourra alors limiter les failles de sécurité:
/Applications/XAMPP/xamppfiles/xampp security
6) START et STOP
To start XAMPP simply open XAMPP Control and start Apache, MySQL and ProFTPD.
Mais, on peut aussi utiliser la commande /Applications/XAMPP/xamppfiles/xampp :
on peut non seulement démarrer Xampp mais aussi exécuter d'autres commandes :
Pour arrêter XAMPP simplement entrer cette commande:
/Applications/XAMPP/xamppfiles/xampp stop
Pour démarrer Apache avec support SSL suivre les commandes suivantes:
/Applications/XAMPP/xamppfiles/xampp startssl
Et Apache avec support SSL fonctionne déjà. Joignable sous https://localhost.
Étape optionnelle : Activer l’extension UserDir pour Apache. Cette extension permet d’avoir des urls dédiées pour chaque utilisateur de l’ordinateur du type http://localhost/~utilisateur/
Éditez le fichier /opt/local/apache2/conf/httpd.conf
Recherchez et décommentez la ligne ci-dessous :
#Include conf/extra/httpd-userdir.conf
Étape optionnelle : Autoriser l’ajout/suppression d’options via un .htaccess (exemple Options +FollowSymLinks)
Éditez le fichier /opt/local/apache2/conf/extra/httpd-userdir.conf
Recherchez la ligne ci-dessous :
Configurer MySQL pour PHP
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez les paramètres pdo_mysql.default_socket, mysql.default_socket, mysqli.default_socketet mettez comme valeur ceci :
/opt/local/var/run/mysql5/mysqld.sock
Configurer le fuseau horaire par défaut
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez la ligne suivante :
;date.timezone =
Remplacez par :
date.timezone = "Europe/Paris"
Étape optionnelle : Activer les archives Phar
Éditez le fichier /opt/local/etc/php5/php.ini
Recherchez et décommentez la ligne ci-dessous
;phar.readonly = On
Une fois les modifications terminées, redémarrez votre serveur Apache 2.
Installation AMP (Apache Mysql Php) en utilisant les packages Mac OS pré-existant
Pour activer le serveur, allez dans Préférences système -> Partage et cochez la case Partage Web. Si elle est déjà cochée, décochez-la pour arrêter le serveur et recochez-là pour que la modification du fichier httpd.conf soit prise en compte.
v2.2.20
/usr/sbin/
PHP
v5.3.6
Php : /usr/lib/
Pour activer PHP il faut décommenter la ligne #LoadModule php5_module libexec/apache2/libphp5.so du fichier httpd.conf situé dans le dossier apache2 du dossier etc.
Ensuite réactiver le serveur apache (voir ci-dessus)
Pour montrer les éléments cachés il faut taper la commande "defaults write com.apple.finder AppleShowAllFiles 1".
Pour cacher à nouveau les fichiers et dossiers spéciaux il faut taper la commande "defaults write com.apple.finder AppleShowAllFiles 0".
L'utilitaire TinkerTool de Marcel Bresink permet de régler ces préférences d'une manière plus conviviale.
Déplacement clavier :
home : cmd left
end : cmd right
mot : alt left/right
Effacer le mot suivant Ctrl+Suppr
Navigation :
entre applis : Cmd Tab
entre onglets d'une mm appli : ctrl tab
entre fenêtres d'une mm appui : (alt tab ???)
cmd * (sur clavier mac, c'est cmd `, sous le £), à droite de la lettre "m"
Transition depuis le monde Linux
packages = .dmg
Gestion des Services
Pas de /etc/init.d/
A la place :
/System/Library/StartupItems et /Library/StartupItems
Apple provides a program called SystemStarter which is used to start and stop scripts in the /System -> Library -> StartupItems and /Library -> StartupItems folders. You can use it to restart services like so:
% sudo SystemStarter restart NetInfo
Or if you've just installed GimpPrint and need to restart CUPS for it to find your printer:
% sudo SystemStarter restart PrintingServices
The one caveat is that all the start, stop, and restart options do is pass this argument to the various scripts. If the script doesn't respond to that argument, nothing happens. An example is AppServices, which controls coreservicesd. Sending stop or restart to this script has no effect.
Type man SystemStarter and browse through the various scripts to learn more about the program and the scripts.
Astuces, raccourcis clavier
RACCOURCIS
caractère DIESE : maj alt * (touche à droite du "m")
Refaire (Ctrl+Maj+Z) Cmd+Maj+Z
Ouvrir un menu contextuel (Maj+F10) Ctrl+Espace
(Windows-E) Cmd-Maj-C Ouvre la fenêtre Computer sous Windows. / Va sur la vue Computer dans le Finder sous Mac OS X
(Ctrl-Maj-Echap) Cmd-Option-Esc Ouvre une fenêtre permettant de forcer l'arrêt d'une application
Quitter un programme +
Afficher les propriétés +
Forcer à quitter : Command + Option + Escape
Capture d'écran : Command + Shift + 3
Bureau : F11
Voir l'ensemble des appris en réduction : F9 et F10
Masquer finder : cmd H
Masquer les autres : cmd alt H
Créer un alias : Pom-alt + déplacer une icone sur bureau
ps command displays every process (-e) with a user-defined format (-o pcpu). First field is pcpu (cpu utilization). It is sorted in reverse order to display top 10 CPU eating process.
iostat :
It can be use to find out your system's average CPU utilization since the last reboot.
$ iostat
This gives you three outputs every 5 seconds (as previous command gives information since the last reboot):
$ iostat -xtc 5 3
gnome-system-monitor : allows you to view and control the processes
2) mapping identité entre les partitions physiques (PP) et virtuelles (PV) : 1 PV = 1 PP
Added:
> >
Make sure the partition type for the physical volumes is correct. The partition type should be “8e”.
# fdisk -l /dev/sdb
Disk /dev/sdb: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sdb1 1 30400 244187968+ 8e Linux LVM
/dev/sdb2 30401 60801 244196032+ 8e Linux LVM
# pvcreate /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Physical volume "/dev/sdb1" successfully created
Physical volume "/dev/sdb2" successfully created
Physical volume "/dev/sdc1" successfully created
Physical volume "/dev/sdc2" successfully created
# pvdisplay
"/dev/sdb1" is a new physical volume of "232.88 GB"
--- NEW Physical volume ---
PV Name /dev/sdb1
VG Name
PV Size 232.88 GB
Allocatable NO
PE Size (KByte) 0
Total PE 0
Free PE 0
Allocated PE 0
PV UUID j4XKT6-OI2y-cPMK-YpNR-gmgc-es67-ey4CV2
"/dev/sdb2" is a new physical volume of "232.88 GB"
--- NEW Physical volume ---
...
Notice that each PV is given a PV UUID
3) Les PV sont regroupés en 1 à n volume group (VG) (a VG can be seen as a "virtual hd")
ex : le VG primary_vg regroupera /dev/sda1, /dev/sda2 , /dev/sdb1, et /dev/sdb3
Changed:
< <
4) Chaque VG est redécoupé en m logical group (LG) : 1 VG = m LG (a LG can be seen as a "virtual partition")
> >
# vgcreate primary_vg /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Volume group "primary_vg" successfully created
# vgdisplay
--- Volume group ---
VG Name primary_vg
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 4
Act PV 4
VG Size 931.52 GB
PE Size 4.00 MB
Total PE 238468
Alloc PE / Size 0 / 0
Free PE / Size 238468 / 931.52 GB
VG UUID oNH6jk-PBE0-mR0c-aaDi-3Fys-y5SQ-0tVaxX
If you don't happen to remember the name of a VG or you happen upon a new system to administer, then you can use a command called "vgscan" that will tell what VG's are on the system.
# vgscan
Reading all physical volumes. This may take a while...
Found volume group "primary_vg" using metadata type lvm2
4) Chaque VG est redécoupé en m logical volume (LV) : 1 VG = m LV (a LV can be seen as a "virtual partition")
ex : le VG primary_vg est redécoupé en 2 LV : /dev/primary_vg/home_lv et /dev/primary_vg/data_lv
For example, if the file system says it has 29G used (29 GB), then you should snapshot a little larger – perhaps 30-32 GB (always good to have a cushion). This cushion isn’t strictly necessary, but a little safety never hurts...
LVM can be used to effectively manage storage to make expansion, snapshots, and other aspects of storage fairly easy.
LVM allows you to abstract various pieces of physical storage into groups that can be carved into chunks that form the basis of file systems (virtual partitions if you like). It also allows you to combine physical partitions into groups, resize these groups (grow or shrink), and effectively manage these groups.
1) h physical hd découpés chacun en p physical partitions (PP) (pas forcément le même nb de partitions pour chaque hd)
ex : sda découpé en /dev/sda1, /dev/sda2 et sdb découpé en /dev/sdb1, /dev/sdb2, /dev/sdb3
2) mapping identité entre les partitions physiques (PP) et virtuelles (PV) : 1 PV = 1 PP
3) Les PV sont regroupés en 1 à n volume group (VG) (a VG can be seen as a "virtual hd")
ex : le VG primary_vg regroupera /dev/sda1, /dev/sda2 , /dev/sdb1, et /dev/sdb3
4) Chaque VG est redécoupé en m logical group (LG) : 1 VG = m LG (a LG can be seen as a "virtual partition")
ex : le VG primary_vg est redécoupé en 2 LV : /dev/primary_vg/home_lv et /dev/primary_vg/data_lv
5) Sur chaque LG, on monte un système de fichier (FS) :
ex : /home monté en ext3 sur le LV home_lv et /data monté en xfs sur le LV data_lv
When you need to test something, here is what you do:
Annotate a method with @org.junit.Test
When you want to check a value, import org.junit.Assert.* statically, call assertTrue() and pass a boolean that is true if the test succeeds
(Use a method provides by JUnit to check the expected result of the code execution versus the actual result)
For example, to test that the sum of two Moneys with the same currency contains a value which is the sum of the values of the two Moneys, write:
@Test
public void simpleAdd() {
Money m12CHF= new Money(12, "CHF");
Money m14CHF= new Money(14, "CHF");
Money expected= new Money(26, "CHF");
Money result= m12CHF.add(m14CHF);
assertTrue(expected.equals(result));
}
Fixture :
What if you have two or more tests that operate on the same or similar sets of objects?
Tests need to run against the background of a known set of objects. This set of objects is called a test fixture. When you are writing tests you will often find that you spend more time writing the code to set up the fixture than you do in actually testing values.
To some extent, you can make writing the fixture code easier by paying careful attention to the constructors you write. However, a much bigger savings comes from sharing fixture code. Often, you will be able to use the same fixture for several different tests. Each case will send slightly different messages or parameters to the fixture and will check for different results.
When you have a common fixture, here is what you do:
Add a field for each part of the fixture
Annotate a method with @org.junit.Before and initialize the variables in that method
Annotate a method with @org.junit.After to release any permanent resources you allocated in setUp
For example, to write several test cases that want to work with different combinations of 12 Swiss Francs, 14 Swiss Francs, and 28 US Dollars, first create a fixture:
public class MoneyTest {
private Money f12CHF;
private Money f14CHF;
private Money f28USD;
@Before public void setUp() {
f12CHF= new Money(12, "CHF");
f14CHF= new Money(14, "CHF");
f28USD= new Money(28, "USD");
}
}
Once you have the Fixture in place, you can write as many Test Cases as you'd like. Add as many test methods (annotated with @Test) as you'd like.
Deleted:
< <
Use a method provides by JUnit to check the expected result of the code execution versus the actual result
You use a tool like Eclipse or the class "org.junit.runner.JUnitCore" to run the test.
Line: 198 to 244
Annotation Description
@Test public void method() Annotation @Test identifies that this method is a test method.
Changed:
< <
@Before public void method() Will perform the method() before each test. This method can prepare the test environment, e.g. read input data, initialize the class)
> >
@Before public void method() Will perform the method() before each test. This method can prepare the test environment (called a "fixture"), e.g. read input data, initialize the class)
@After public void method() Test method must start with test
@BeforeClass public void method() Will perform the method before the start of all tests. This can be used to perform time intensive activities for example be used to connect to a database
@AfterClass public void method() Will perform the method after all tests have finished. This can be used to perform clean-up activities for example be used to disconnect to a database
You can use the classpath to run the program from another place in your directory.
Switch to the command line, e.g. under Windows Start-> Run -> cmd. Switch to any directory you want. Type:
java HelloWorld
If you are not in the directory in which the compiled class is stored then the system should result an error message Exception in thread "main" java.lang.NoClassDefFoundError: test/TestClass
To use the class type the following command. Replace "mydirectory" with the directory which contains the test directory. You should again see the "HelloWorld" output.
java -classpath "mydirectory" HelloWorld
Create an executable JAR
A JAR file is a Java Archive based on the pkzip file format. A jar files can contain java classes and other resources (icons, property files) and can be executable.
JAR files are the deployment format for Java. You can distribute your program in a jar file or you can use exiting java code via jars by putting them into your classpath.
An executable JAR means the end-user doesn't have to pull the class files out before running the program. This is done via a manifest.txt file which tells the JVM which class has the main() method. The content of the manifest.txt file:
An empty line is required otherwise the jar won't be executable. Space after a new line is also required
To create one executable JAR file run on the command line
jar -cvmf mainfest.txt app1.jar *.class
ECLIPSE
JUnit
Line: 131 to 189
Added:
> >
7) Annotations and Assert statements
a) Annotations
The following give an overview of the available annotations in JUnit 4.x
Annotation Description
@Test public void method() Annotation @Test identifies that this method is a test method.
@Before public void method() Will perform the method() before each test. This method can prepare the test environment, e.g. read input data, initialize the class)
@After public void method() Test method must start with test
@BeforeClass public void method() Will perform the method before the start of all tests. This can be used to perform time intensive activities for example be used to connect to a database
@AfterClass public void method() Will perform the method after all tests have finished. This can be used to perform clean-up activities for example be used to disconnect to a database
@Ignore Will ignore the test method, e.g. useful if the underlying code has been changed and the test has not yet been adapted or if the runtime of this test is just to long to be included.
@Test(expected=IllegalArgumentException.class) Tests if the method throws the named exception
@Test(timeout=100) Fails if the method takes longer then 100 milliseconds
b) Assert statements
The following gives an overview of the available test methods:
Statement Description
fail(String) Let the method fail, might be usable to check that a certain part of the code is not reached.
assertTrue(true); True
assertsEquals([String message], expected, actual) Test if the values are the same. Note: for arrays the reference is checked not the content of the arrays
assertsEquals([String message], expected, actual, tolerance) Usage for float and double; the tolerance are the number of decimals which must be the same
assertNull([message], object) Checks if the object is null
assertNotNull([message], object) Check if the object is not null
assertSame([String], expected, actual) Check if both variables refer to the same object
assertNotSame([String], expected, actual) Check that both variables refer not to the same object
assertTrue([message], boolean condition) Check if the boolean condition is true.
We want to create the unit tests in a separate folder. Create therefore a new source folder "test" via right mouse click on your project, select properties and choose the "Java Build Path". Select the tab source code.
Press "Add folder" then then press "Create new folder". Create the folder "test".
The creation of an separate folder for the test is not mandatory. But it is good advice to keep the test coding separate from the normal coding.
Create a Java class
Create a package "de.vogella.junit.first" and the following class.
package de.vogella.junit.first;
public class MyClass {
public int multiply(int x, int y) { return x / y; }
}
4) Create a JUnit test
Select your new class, right mouse click and select New ->JUnit Test case, change the source folder to JUnit. Select "New JUnit 4 test". Make sure you change the source folder to test.
Press next and select the methods which you want to test.
If you have not yet JUnit in your classpath, Eclipse will asked you if it should be added to the classpath.
Create a test with the following code.
package de.vogella.junit.first;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MyClassTest {
@Test public void testMultiply() {
MyClass tester = new MyClass();
assertEquals("Result", 50, tester.multiply(10, 5));
}
}
5) Run your test via Eclipse
Right click on your new test class and select Run-As-> Junit Test.
The test should be failing (indicated via a red bar). This is due to the fact that our multiplier class is currently not working correctly (it does a division instead of multiplication). Fix the bug and re-run test to get a green light.
If you have several tests you can combine them into a test suite. All test in this test suite will then be executed if you run the test suite. To create a new test suite, select your test classes, right mouse click-> New-> Other -> JUnit -Test Suite
Select next and select the methods you would like to have test created for.
package de.vogella.junit.first;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({ MyClassTest.class, OtherClassTest.class })
public class AllTests {
}
If you later develop another test you can add it to @Suite.SuiteClasses
6) Run your test via code
You can also run your test via your own coding. The class "org.junit.runner.JUnitCore" provides the method runClasses() which allows you to run one or several tests classes. As a return parameter you receive an object of type "org.junit.runner.Result". This object can be used to retrieve information about the tests and provides information about the failed tests.
Create in your "test" folder a new class "MyTestRunner" with the following coding. This class will execute your test class and write potential failures to the console.
package de.vogella.junit.first;
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
public class MyTestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(MyClassTest.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
}
}
dd if= of= bs=(usually some power of 2, not less than 512 bytes(ie, 512, 1024, 2048, 4096, 8192, 16384, but can be any number.) skip= seek= conv=.
Line: 2107 to 2113
(http://www.efense.com/helix is a good boot cd : The helix boot environment contains the DoD version of dd called dcfldd. It works the same way, but is has a progress bar)
Added:
> >
Using dd you can create backups of an entire harddisk or just a parts of it. This is also usefull to quickly copy installations to similar machines. It will only work on disks that are exactly the same in disk geometry, meaning they have to the same model from the same brand.
this will copy the first 446 bytes of the hard drive to a file. If you haven't already guessed, reversing the objects of if and of, in the dd command line reverses the direction of the write.
Added:
> >
Back up your MBR
dd if=/dev/sda of=mbr.bin count=1
Put this on a floppy you make with
dd if=boot.img of=/dev/fd0
Along with dd. Boot from the floppy and
dd if=mbr.bin of=/dev/sda count=1
Will restore the MBR
Copy a disk partition to a file on a different partition (Do not copy a partition to the same partition)
Vous pouvez faire vos tests sur des fichiers ou des clefs USB pour commencer...
Remplacez simplement le "device" par un fichier existant. Ex : /dev/sdX par /home/moi/raid-test/disque-1.img.
Pour créer un fichier quelque part avec la bonne taille : dd if=/dev/zero of=/home/moi/raid-test/disque-1.img count=10000 bs=65535.
Pour en savoir plus : man dd.
Apres on fait un : mdadm --create /dev/md0 --level=1 --raid-devices=/home/moi/raid-test/disque-1.img,/home/moi/raid-test/disque-2.img
Et voila un RAID 1 créé avec deux fichiers stockés sur le disque dur.
J'ai testé le Raid0 sur 2DD externes de 2,5" en USB, et j'arrive à 45Mo sec avec mon portable...
Avant de mettre un raid sur une machine en production VERIFIEZ les noms des disques et des partitions !!! Préférez les /dev/disk/by-id, vous ferez moins facilement des erreurs qu'en mettant seulement /dev/sde, surtout si vous ajoutez des disques par la suite...
L'outil magique de management du RAID sous Linux : mdadm
Quelques exemples : (vous noterez que l'on utilise la syntaxe /dev/sdX alors que c'est mal.. mais c'est plus lisible que /dev/disk/by-id/ata-ST3250310AS_6RY7R988-part1)
crée un device /dev/mdX (X étant un chiffre) de niveau (--level) 0 (stripping), 1 (mirroring), 4 (comme le 5 mais la parité est toujours sur le même disque), 5 ou 6 (2 disques de parité) à partir des devices /dev/sdYZ (Y est une lettre indiquant un disque physique , Z un chiffre indicant un numéro de partition).
On peut également mettre missing dans la liste des devices. C'est très utile lorsque l'on passe son système sur un raid 1
Mise en échec d'un disque (pour test par ex.) :
mdadm --manage /dev/mdX --failed /dev/sdYZ
"Ejection" d'un disque d'une pile :
mdadm --manage /dev/mdX --remove /dev/sdYZ
Ajout d'un disque à une pile :
mdadm --manage /dev/mdX --add /dev/sdYZ
Liste des périphériques d'une pile :
mdadm --misc --detail /dev/mdX
On peux aussi faire :
cat /proc/mdstat
Agrandir une partition
La première étape consiste à repérer quel device correspond aux partitions que tu veux redimensionner. Pour cela tu peux utiliser la commande :
sudo fdisk -l
# fdisk -l
Disque /dev/sda: 250.0 Go, 250059350016 octets
255 heads, 63 sectors/track, 30401 cylinders
Unités = cylindres de 16065 * 512 = 8225280 octets
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
Disque /dev/sdb: 250.0 Go, 250059350016 octets
255 heads, 63 sectors/track, 30401 cylinders
Unités = cylindres de 16065 * 512 = 8225280 octets
Périphérique Amorce Début Fin Blocs Id Système
/dev/sdb1 * 1 30401 244196001 fd Linux raid autodetect
Disque /dev/sdc: 250.0 Go, 250059350016 octets
255 heads, 63 sectors/track, 30401 cylinders
Unités = cylindres de 16065 * 512 = 8225280 octets
Périphérique Amorce Début Fin Blocs Id Système
/dev/sdc1 * 1 30401 244196001 fd Linux raid autodetect
Disque /dev/sdd: 250.0 Go, 250059350016 octets
255 heads, 63 sectors/track, 30401 cylinders
Unités = cylindres de 16065 * 512 = 8225280 octets
Périphérique Amorce Début Fin Blocs Id Système
/dev/sdd1 * 1 30401 244196001 fd Linux raid autodetect
Disque /dev/md0: 500.1 Go, 500113080320 octets
2 heads, 4 sectors/track, 122097920 cylinders
Unités = cylindres de 8 * 512 = 4096 octets
Disque /dev/md0 ne contient pas une table de partition valide
Pour avoir un résultat plus parlant (tailles en octets + système de fichiers) tu peux utiliser cfdisk : sudo cfdisk /dev/sda
L'ext3 c'est en fait de l'ext2 mais avec un "journal" et c'est pour ça qu'il est facile de passer d'ext2 à ext3 et réciproquement.
Les outils de redimensionnement s'appliquent à de l'ext2 ce qui nécessitera de passer d'ext3 à ext2, redimensionner, puis repasser en ext3
dd if= of= bs=(usually some power of 2, not less than 512 bytes(ie, 512, 1024, 2048, 4096, 8192, 16384, but can be any number.) skip= seek= conv=.
Source is the data being read. Target is where the data gets written. If you mess up, and accidentally reverse the source and target, you can wipe out a lot of data.
(http://www.efense.com/helix is a good boot cd : The helix boot environment contains the DoD version of dd called dcfldd. It works the same way, but is has a progress bar)
Examples:
Copy one hard disk partition to another hard disk:
sda2, sdb2 are partitions. You want to copy sda2 to sdb2. If sdb2 doesn't exist, dd will start at the beginning of the disk, and create it. Be careful with order of if and of. You can write a blank disk to a good disk if you get confused.
CD sectors are 2048 bytes, so this copies sector for sector. The result will be a hard disk image file of the CD. You can use "chmod a+rwx mycd.iso" to make the image writable. You can mount the image with "mkdir /mnt/mycd", this line in fstab: "/home/sam/mycd.iso /mnt/mycd iso9660 rw,user,noauto 0 0", save fstab, "mount -o loop /mnt/mycd". Then the file system will be viewable as files and directories in the directory /mnt/mycd. You can edit the image as you wish, and the new file will be "/home/sam/mycd.iso" dd does not write to CD's. You need to use a burning utility, or the cdrdao command
Cloning an entire hard disk:
dd if=/dev/sda of=/dev/sdb conv=notrunc,noerror
In this example, sda is the source. sdb is the target. Do not reverse the intended source and target. Surprisingly many people do. notrunc means to not truncate. noerror means to keep going if there is an error. Normally dd stops at any error. if you have a question about a hard drive on whether or not it works, you can try to use it as the source drive for the dd command. You should get an error if it is not working. target drives need to be really messed up to give an error in dd.
this will copy the first 446 bytes of the hard drive to a file. If you haven't already guessed, reversing the objects of if and of, in the dd command line reverses the direction of the write.
Copy a disk partition to a file on a different partition (Do not copy a partition to the same partition)
This way you can get a bazonga hard drive and partition it so you can back up your root partition. If you mess up your root partition, you just boot from the helix cd and restore the image.
Copie de disque ou partition (image "ghost") avec partimage (SystemRescueCd)
Périphérique Amorce Début Fin Blocs Id Système
/dev/sda1 * 1 25 200781 83 Linux
/dev/sda2 26 535 4096575 82 Linux swap / Solaris
/dev/sda3 536 30401 239898645 83 Linux
Outil de visualisation graphique des logs : gnome-system-log
Added:
> >
Common Linux log files name and usage :
/var/log/message: General message and system related stuff
/var/log/auth.log: Authenication logs
/var/log/kern.log: Kernel logs
/var/log/cron.log: Crond logs (cron job)
/var/log/maillog: Mail server logs
/var/log/qmail/ : Qmail log directory (more files inside this directory)
/var/log/httpd/: Apache access and error logs directory
/var/log/lighttpd: Lighttpd access and error logs directory
/var/log/boot.log : System boot log
/var/log/mysqld.log: MySQL database server log file
/var/log/secure: Authentication log
/var/log/utmp or /var/log/wtmp : Login records file
/var/log/yum.log: Yum log files
In short /var/log is the location where you should find all Linux logs file. However some applications such as httpd have a directory within /var/log/ for their own log files. You can rotate log file using logrotate software and monitor logs files using logwatch software.
index.php : qui lance $application->bootstrap() et ->run()
3) The Bootstrap
Your Bootstrap class defines what resources and components to initialize. By default, Zend Framework's Front Controller is initialized, and it uses the application/controllers/ as the default directory in which to look for action controllers
Le contrôleur de Zend Framework réserve une action "index" comme action par défaut. C'est-à-dire que pour l'URI "http://localhost/tutoriel-zf/actualités/", l'action "index" est exécutée. Le framework réserve également un nom de contrôleur si aucun n'est fourni dans l'URI : aucune surprise qu'il soit également appelé "index". Ainsi, l'URI "http://localhost/tutoriel-zf/" appelle le contrôleur "index" avec l'action "index".
Le contrôleur de Zend Framework réserve une action "index" comme action par défaut. C'est-à-dire que pour l'URI "http://localhost/tutoriel-zf/actualités/", l'action "index" est exécutée. Le framework réserve également un nom de contrôleur si aucun n'est fourni dans l'URI : aucune surprise qu'il soit également appelé "index". Ainsi, l'URI "http://localhost/tutoriel-zf/" appelle le contrôleur "index" avec l'action "index".
Le contrôleur de Zend Framework réserve une action "index" comme action par défaut. C'est-à-dire que pour l'URI "http://localhost/tutoriel-zf/actualités/", l'action "index" est exécutée. Le framework réserve également un nom de contrôleur si aucun n'est fourni dans l'URI : aucune surprise qu'il soit également appelé "index". Ainsi, l'URI "http://localhost/tutoriel-zf/" appelle le contrôleur "index" avec l'action "index".
Next, we will add a signAction() to our GuestbookController which will process the form upon submission. To create the action and related view script, execute the following:
Note also the use of the headLink() placeholder. This is an easy way to generate the HTML for elements, as well as to keep track of them throughout your application. If you need to add additional CSS sheets to support a single action, you can do so, and be assured it will be present in the final rendered page.
Your application bootstrap will by default use the module prefix "Application". As such, our models, forms, and table classes will all begin with the class prefix "Application_".
zf configure db-adapter 'adapter=PDO_SQLITE&dbname=APPLICATION_PATH "/../data/db/guestbook.db"' production
This will create a new controller, GuestbookController, in application/controllers/GuestbookController.php, with a single action method, indexAction(). It will also create a view script directory for the controller, application/views/scripts/guestbook/, with a view script for the index action.
We'll use the "index" action as a landing page to view all guestbook entries.
Now, let's flesh out the basic application logic. On a hit to indexAction(), we'll display all guestbook entries. This would look like the following:
// application/controllers/GuestbookController.php
class GuestbookController extends Zend_Controller_Action
{
public function indexAction()
{
$guestbook = new Application_Model_GuestbookMapper();
$this->view->entries = $guestbook->fetchAll();
}
}
And, of course, we need a view script to go along with that. Edit application/views/scripts/guestbook/index.phtml to read as follows:
<!-- application/views/scripts/guestbook/index.phtml -->
<p><a href="<?php echo $this->url(
array(
'controller' => 'guestbook',
'action' => 'sign'
),
'default',
true) ?>">Sign Our Guestbook</a></p>
Guestbook Entries: <br />
<dl>
<?php foreach ($this->entries as $entry): ?>
<dt><?php echo $this->escape($entry->email) ?></dt>
<dd><?php echo $this->escape($entry->comment) ?></dd>
<?php endforeach ?>
</dl>
Utilisé pour les fonctions anonymes, le mot-clef "use" permet d’importer (en lecture seule) des variables externes, issues de l’espace de noms « global », au sein de la fonction lambda.
$var = 'World';
$f2 = function () use ($var) {
echo "<p>Hello, $var!</p>";
};
$f2(); // Hello, World!
En quelque sorte, "use" fait penser à l’instruction "global", que nous rencontrions parfois auparavant… Mais global ne répond pas aux besoins des closures
Import de variable par référence :
$var = 0;
$func2 = function () use (& $var) {
echo "<p>Début 2 : $var</p>";
$var = 2;
echo "<p>Fin 2 : $var</p>";
};
et le résultat :
echo "<p>Avant 2 : $var</p>"; // Avant 2 : 0
$func2(); // Début 2 : 0
// Fin 2 : 2
echo "<p>Après 2 : $var</p>"; // Après 2 : 2
Mais, qu'est-ce qu'une fonction anonyme pour php ?
$func = function ($param) {
echo "<p>Hello, $param!</p>";
};
var_dump($func);
Le résultat obtenu est le suivant :
object(Closure)[1]
Pour PHP, une fonction anonyme — une lambda — est un objet : une instance de classe Closure…
Une closure est une fonction qui est évaluée dans un environnement contenant une ou plusieurs variables liées, auxquelles elle peut accéder au moment de son exécution.
Dans certains langages — dont Javascript, et PHP >= 5.3 — une closure peut exister lorsqu’une fonction est définie au sein d’une autre, et que la fonction interne fait référence à des variables de la fonction externe.
A l’exécution, une closure est formée : elle est constituée du code de la fonction interne et des références aux variables externes utilisées par celle-ci.
En PHP, une closure se construit de la manière suivante :
Une variable locale est créée dans une première fonction "externe",
Une seconde fonction "interne" est définie à l’intérieur de la première fonction, sous forme d’une fonction anonyme,
Et cette fonction "interne" importe la variable locale de la fonction "externe", à l’aide du mot-clef use.
Le mécanisme de closure permet donc de créer des variables au sein de la fonction "externe", qui conserveront leur valeur aussi longtemps que l’on aura conservé un pointeur sur la fonction "interne".
Ces variables seront accessibles par la fonction interne, éventuellement en écriture si nous avons utilisé & lors de leur import, tout en n’étant pas visibles du reste de notre script.
Appel de fonction sur un objet
PHP 5.3 ajoute la possibilité d’utiliser la syntaxe d’un appel de fonction sur un objet, en lui appliquant l’opérateur ().
Pour cela, une nouvelle méthode magique a été ajoutée : __invoke :
lors d’un appel de fonction sur une instance de classe comportant une méthode __invoke, c’est cette méthode qui sera appelée.
Voici une classe d’exemple :
class MyString {
public $str;
public function __construct($a) {
$this->str = $a;
}
// Appelée quand on appelle dynamiquement un
// objet instance de cette classe
public function __invoke($a) {
var_dump(__METHOD__);
$this->str = $a;
}
}
Session
Endroit où sont stockés les fichiers (temporaires) de session : session.save_path (php.ini)
Dans Eclipse, créer un projet PHP nommé "zfquickstart"
Ajouter D:\ProgFilesNoInstall\zf\bin dans PATH windows
Changed:
< <
Ouvrir une console dos
> >
2) Créer un projet
Dans Eclipse, créer un projet PHP nommé "zfquickstart"
Ouvrir une console DOS
Aller dans xampp/htdocs
zf create project zfquickstart
Added:
> >
3) The Bootstrap
Your Bootstrap class defines what resources and components to initialize. By default, Zend Framework's Front Controller is initialized, and it uses the application/controllers/ as the default directory in which to look for action controllers
// application/Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
4) Configuration
While Zend Framework is itself configurationless, you often need to configure your application. The default configuration is placed in application/configs/application.ini, and contains some basic directives for setting your PHP environment (for instance, turning error reporting on and off), indicating the path to your bootstrap class (as well as its class name), and the path to your action controllers.
First, when using INI-style configuration, you can reference constants directly and expand them; APPLICATION_PATH is actually a constant.
Additionally note that there are several sections defined: production, staging, testing, and development. The latter three inherit settings from the "production" environment. This is a useful way to organize configuration to ensure that appropriate settings are available in each stage of application development.
5) Action Controllers
Your application's action controllers contain your application workflow, and do the work of mapping your requests to the appropriate models and views.
An action controller should have one or more methods ending in "Action"; these methods may then be requested via the web. By default, Zend Framework URLs follow the schema /controller/action, where "controller" maps to the action controller name (minus the "Controller" suffix) and "action" maps to an action method (minus the "Action" suffix).
Typically, you always need an IndexController, which is a fallback controller and which also serves the home page of the site, and an ErrorController, which is used to indicate things such as HTTP 404 errors (controller or action not found) and HTTP 500 errors (application errors).
// application/controllers/IndexController.php
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
// action body
}
}
And the default ErrorController is as follows:
// application/controllers/ErrorController.php
class ErrorController extends Zend_Controller_Action
{
public function errorAction()
{
$errors = $this->_getParam('error_handler');
switch ($errors->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
// 404 error -- controller or action not found
$this->getResponse()->setHttpResponseCode(404);
$this->view->message = 'Page not found';
break;
default:
// application error
$this->getResponse()->setHttpResponseCode(500);
$this->view->message = 'Application error';
break;
}
$this->view->exception = $errors->exception;
$this->view->request = $errors->request;
}
}
You'll note that the IndexController contains no real code, and the ErrorController makes reference to a "view" property. That leads nicely into our next subject.
6) Views
Views in Zend Framework are written in plain old PHP. View scripts are placed in application/views/scripts/, where they are further categorized using the controller names. In our case, we have an IndexController and an ErrorController, and thus we have corresponding index/ and error/ subdirectories within our view scripts directory. Within these subdirectories, you will then find and create view scripts that correspond to each controller action exposed; in the default case, we thus have the view scripts index/index.phtml and error/error.phtml.
View scripts may contain any markup you want, and use the closing tag to insert PHP directives.
Dans "D:\xampp\apache\conf\extra\myvhosts", créer un fichier "zfquickstart.conf"
Listen 8087
<VirtualHost *:8087>
ServerName zfquickstart.local
ServerAlias zfquickstart.local zfquickstart
#ServerName .local
DocumentRoot "D:/xampp/htdocs/zfquickstart/public"
# This should be omitted in the production environment
SetEnv APPLICATION_ENV "development"
<Directory "D:/xampp/htdocs/zfquickstart/public">
DirectoryIndex index.php
#Options Indexes MultiViews FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
There are several things to note. First, note that the DocumentRoot setting specifies the public subdirectory of our project; this means that only files under that directory can ever be served directly by the server. Second, note the AllowOverride, Order, and Allow directives; these are to allow us to use htacess files within our project. During development, this is a good practice, as it prevents the need to constantly restart the web server as you make changes to your site directives; however, in production, you should likely push the content of your htaccess file into your server configuration and disable this. Third, note the SetEnv directive. What we are doing here is setting an environment variable for your virtual host; this variable will be picked up in the index.php and used to set the APPLICATION_ENV constant for our Zend Framework application. In production, you can omit this directive (in which case it will default to the value "production") or set it explicitly to "production".
Avec un , il faudrait aussi faire ceci :
Finally, you will need to add an entry in your hosts file corresponding to the value you place in your ServerName directive. On *nix-like systems, this is usually /etc/hosts; on Windows, you'll typically find it in C:\WINDOWS\system32\drivers\etc. Regardless of the system, the entry will look like the following:
127.0.0.1 zfquickstart.local
Start your webserver (or restart it), and you should be ready to go.
NB: il faut ajouter le chemin vers ZF ("D:\ProgFilesNoInstall\zf\library") :
soit dans php.ini,
soit, mieux, dans le fichier index.php du dossier "public/" du projet : chercher la ligne "set_include_path" et insérer en tête de liste, ce qui donne :
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
//EP added :
"D:\ProgFilesNoInstall\zf\library",
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
To get started using Zend_Layout, first we need to inform our bootstrap to use the Layout resource. This can be done using the zf enable layout command:
% zf enable layout
Layouts have been enabled, and a default layout created at
application/layouts/scripts/layout.phtml
A layout entry has been added to the application config file.
As noted by the command, application/configs/application.ini is updated, and now contains the following within the production section:
We also want to ensure we have an XHTML DocType declaration for our application. To enable this, we need to add a resource to our bootstrap.
The simplest way to add a bootstrap resource is to simply create a protected method beginning with the phrase _init. In this case, we want to initialize the doctype, so we'll create an _initDoctype() method within our bootstrap class.
Within that method, we need to hint to the view to use the appropriate doctype. But where will the view object come from? The easy solution is to initialize the View resource; once we have, we can pull the view object from the bootstrap and use it.
To initialize the view resource, add the following line to your application/configs/application.ini file, in the section marked production:
resources.view[] =
This tells us to initialize the view with no options (the '[]' indicates that the "view" key is an array, and we pass nothing to it).
Now that we have a view, let's flesh out our _initDoctype() method. In it, we will first ensure the View resource has run, fetch the view object, and then configure it:
// application/Bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
}
}
Now that we've initialized Zend_Layout and set the Doctype, let's create our site-wide layout:
We grab our application content using the layout() view helper, and accessing the "content" key. You may render to other response segments if you wish to, but in most cases, this is all that's necessary.
Note also the use of the headLink() placeholder. This is an easy way to generate the HTML for elements, as well as to keep track of them throughout your application. If you need to add additional CSS sheets to support a single action, you can do so, and be assured it will be present in the final rendered page.
Exact number of available cores, virtual or not (8 pour hyperion, soit 2 proc x 4 cores) : grep -c processor /proc/cpuinfo
Nb de processeurs "physiques" (2 pour hyperion) : grep core\ id /proc/cpuinfo | grep -c \ 0$
The following (clumsy) group of commands will return the number of physical CPUs regardless of if there is only a single core per CPU (2 pour planetoweb et surfasafe) :
Processeur(s) virtualisable(s) ? (cpuinfo doit contenir le flag vmx pour un processeur intel, et svm pour AMD) : egrep '(vmx|svm)' /proc/cpuinfo
Information détaillée : dmidecode
dmidecode --type 4 | grep -c Socket
SSH
Exécuter une commande sur un serveur distant:
Line: 1296 to 1325
Administration
Added:
> >
Virtualisation
La virtualisation consiste à faire cohabiter plusieurs (VM) machines "virtuelles" (OS) sur une même machine physique
Prérequis :
Les processeurs doivent être virtualisables (cpuinfo doit contenir le flag vmx pour un processeur intel, et svm pour AMD) : egrep '(vmx|svm)' /proc/cpuinfo
RAM : au moins 8Go (pour 2 VM)
Disques :
au moins 2x500Go (en raid1 par exemple)
bonne config type :
2 disques raid1 pour le système de base
3 disques raid5 avec un LVM dessus pour stocker les images disques des VM
Serveur de gestion de versions (de code source) SUBVERSION
Sur linux : session.save_path = "/var/lib/php/session" (/etc/php.ini)
Added:
> >
La façon la plus sécurisée est d'utiliser les cookies
1) Le client (navigateur) demande un identifiant de session (jeton)
2) Le serveur crée l'identifiant et le retourne au client
3) Le client stocke sur son disque dur cet identifiant sous la forme d'un cookie qu'il enverra désormais à chaque requête
Nom du jeton par défaut = PHPSESSID (cf php.ini session.name et fonction session_name())
Sur le serveur, ce jeton aura le nom "sess_" suivi de sa valeur
Valeur du jeton = string générée aléatoirement par php (fonction session_id() retourne cette valeur et permet éventuellement de la fixer, mais déconseilllé)
Paramètres php.ini à positionner (on peut utiliser session_set_cookie_params() pour cela, il y a aussi ini_get() et ini_set()) :
session.use_cookies = 1
session.use_only_cookies = 1
session.use_trans_sid = 0 (si cookies pas acceptés, ne pas pour autant transmettre l'id de session dans l'url)
session.cookie_lifetime = 0 (jusqu'au moment de quitter le navigateur)
session.auto_start = 0
session.save_handler = files
session.save_path = ...
La fonction session_start() crée ou restaure une session (à mettre en première ligne du bootstrap)
session_regenerate_id() regénère l'id de session afin d'éviter une fixation de la session
appeler session_destroy() à la déconnexion du user
Le fichier standard php.ini a été réorganisé, et renommé :
php.ini-development contient les options qui sont recommandées pour un environnement de développement.
php.ini-production contient les configurations recommandées pour la production.
On les trouve dans /usr/share/doc/php-common-5.3.3
Voici la différence entre les 2 :
[root@planetoweb etc]# diff /usr/share/doc/php-common-5.3.3/php.ini-development /usr/share/doc/php-common-5.3.3/php.ini-production
514c514
< error_reporting = E_ALL | E_STRICT
---
> error_reporting = E_ALL & ~E_DEPRECATED
531c531
< display_errors = On
---
> display_errors = Off
542c542
< display_startup_errors = On
---
> display_startup_errors = Off
586c586
< track_errors = On
---
> track_errors = Off
604c604
< html_errors = On
---
> html_errors = Off
1248a1249,1256
> ; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
> ; http://php.net/mysqli.allow_local_infile
> ;mysqli.allow_local_infile = On
>
> ; Allow or prevent persistent links.
> ; http://php.net/mysqli.allow-persistent
> mysqli.allow_persistent = On
>
1297c1305
< mysqlnd.collect_memory_statistics = On
---
> mysqlnd.collect_memory_statistics = Off
1566c1574
< session.bug_compat_42 = On
---
> session.bug_compat_42 = Off
1575c1583
< session.bug_compat_warn = On
---
> session.bug_compat_warn = Off
1593d1600
< session.entropy_file =
HereDoc
La syntaxe Heredoc se comporte exactement comme une chaîne à guillemets doubles, sans les guillemets doubles. Cela signifie que vous n'avez pas à échapper les guillemets (simples ou doubles) dans cette syntaxe. Les variables sont remplacées par leur valeur et le même soin doit leur être apporté que dans les chaînes à guillemets doubles.
Le serveur X tourne localement sur mon pc (win ou lin), c'est à dire le pc avec un écran (output), un clavier et une souris (inputs).
Il se connecte à un display manager (xdm ou gdm ou kdm...) qui peut être local ou distant (sur un autre pc) :
Si le DM est local, il démarre un ou plusieurs serveurs X, affiche l'écran de connexion (login) au démarrage et chaque fois qu'un user se délogge.
Si le DM est distant, il est utilisé via le protocole XDMCP : un user lance des programmes depuis le pc distant (qui exécute le DM) alors que ses input/output se passent sur son pc local.
Ainsi, le serveur X (local) communique avec différents clients graphiques (qui peuvent être distants) à qui il envoit les inputs et de qui il reçoit les outputs.
Pour CentOS, le DM par défaut est sélectionné dans /etc/X11/prefdm (qui regarde si un DM par défaut est donné dans /etc/sysconfig/desktop)
C'est le fichier /etc/X11/xinit/Xsession qui exécute notre environnement.
xdm : voir /etc/X11/
kdm : voir /etc/kdm/
gdm : voir /etc/gdm/ Il devrait s'y trouver un gdm.conf
gdm appelle /etc/X11/xinit/Xsession avec les bonnes options
As it currently does not work on hyperion, we have to deactivate it and activate "software rendering" instead (slower).
How to set IDL to use "software rendering" (IDL 8 issue) ?
From IDLDE
Fenêtre/Préférences/IDL/Graphiques :
Méthode de rendu pour les objets graphiques : sélectionner "Logiciel" au lieu de "Matériel"
From the idl console
There are a couple of ways to set IDL to use software rendering, besides from the IDLDE.
If you want to set the entire IDL session to use software rendering, then when you start up IDL, you could use this command:
idl -IDL_GR_WIN_RENDERER 1 (for Windows)
or
idl -IDL_GR_X_RENDERER 1 (for X Windows)
If you want to switch from the default hardware rendering to software rendering in the middle of an IDL session, you could use this command:
PREF_SET, 'IDL_GR_WIN_RENDERER', '1', /COMMIT (for Windows)
or
PREF_SET, 'IDL_GR_X_RENDERER', '1', /COMMIT (for X Windows)
Conseils pour bien documenter son code
Voir conseils généraux (Michael Galloy) "A style guide" : styleguide.pdf
Line: 1115 to 1148
Administration
Added:
> >
BOOT LINUX
I - Le boot : tryptique noyau, arguments, et ramdisk
Synthèse du workflow :
bootloader ==> noyau + initramfs + arguments ==> montage de la racine
1) Chargeur de boot (bootloader)
C'est le 1er prog à s'exécuter. Différent selon les architectures (pc x86, station Sun, Mac PPC...)
Rôle: mettre en RAM le noyau (kernel), lui passer des arguments, copier un ramdisk en RAM, et passer la main au noyau
Ex: lilo, grup, outils syslinux (bien adapté à partifion FAT, clé usb, cd)
Etapes :
- allumage électrique
- POST (Power On Self Test)
- BIOS (dans lequel le periph d'amorçage est défini)
- lancement bootloader installé sur periph amorcé
Ex: noyau grub, /boot/bzImage-2.6
Ex: ramdisk grub, /boot/initrd.img
2) Le noyau
Rôle : monter la racine et lancer /sbin/init situé dessus
Au boot, le noyau décourvre son environnement (ram, cpu, disque...). Ces périph sont gérés par des pilotes (drivers), des "modules" qui sont compilés dans le noyau ou dans des fichiers externes (souvent dans /lib/modules/). Les fichiers modules sont situés sur une partition qui n'est pas encore montée, et donc les périph correspondants ne peuvent pas être utilisés.
Le noyau monte sa racine avec /bin/mount
ex: montage de /dev/sda1 en lecture seule avec sys de fichier ext4
$ mount -t ext4 -o ro /dev/sda1 /
Les arguments passés au noyau peuvent être relus après boot :
$ cat /proc/cmdline
On peut aussi passer l'argument "init=/bin/bash" pour accéder au système au démarrage avec un shell bash.
3) Le ramdisk initial : initramfs
Rôle : permettre une détection plus intelligente de la racine ainsi qu'une facilité de configuration.
S'appelait initrd, mais est de plus en plus remplacé par initramfs
L'initramsf est un ensemble de fichiers qui vont être directement copiés dans le cache de système de fichiers sous la racine (tous les sys 2.6 utilisent un rootfs, cf "cat /proc/mounts"). Il doit au moins contenir un programme /init exécutable que le noyau va lancer pour qu'il trouve la racine et la monte. C'est un microsystème linux à part entière. Le prog /init est souvent un script shell, simple à lire.
Avec un initramfs, il devient possible de conserver un noyau minimal et de mettre les modules essentiels au boot dans l'initramfs (évite de devoir recompiler le noyau). Il contient aussi l'image qui permet un affichage graphique pendant le boot.
/init parse donc la ligne /proc/cmdline, cherche la racine, et la monte pour ensuite basculer le noyau dessus, et enfin s'autoremplace par le vrai binaire /sbin/init.
II - init et inittab
Arrivé à ce point, la noyau tourne, la racine de la distrib est montée (souvent en "ro") et le binaire /sbin/init est lancé, premier processus.
Si ce processus meurt (pid=1), le noyau fait un kernel panic. Il est aussi responsable de l'extinction de la machine.
Si on passe au noyau l'argument "init=/bin/bash", seul "bash" est lancé (à la place de /sbin/init) et on a ainsi un accès root sur la racine (utile pour réparer une distrib, ou modifier mot passe root dans /etc/shadow)
/sbin/init a pour fichier de conf, /etc/inittab : décrit les processus lancés au démarrage et à surveiller durant le fonctionnement normal du système.
Init à 7 runlevels (0=stop, ..., 6=reboot). Runlevel 1 est pour la maintenance (nb minimum de processus et user root only).
Chaque ligne est composée de 4 paramètres :
référence:runlevel:manière de lancer la commande:commande
Runlevel par défaut (ici, le 3):
id:3:initdefault:
On peut modifier ça avec un argument au noyau, par ex:
root=/dev/hda2 ro 1
Runlevel courant ?
$ runlevel
Changer de runlevel ?
$ init n
sysinit est lancé au boot, mais avant les cdes boot:
si::sysinit:/etc/rc.d/rc.sysinit
reset:
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
wait, lance un process et attend sa fin pour continuer:
l5:5:wait:/etc/rc.d/rc 5
respawn, relance le process quand il se termine (ex: les gettys texte, alt-F1... relancés dès qu'on se délogue)
5:2345:respawn:/sbin/mingetty tty5
Relecture de inittab après modif ?
kill -HUP 1
inittab lance des script rc (run command) de 2 façons selon les familles de systèmes linux :
Voyons ici la façon SystemV (plus élaborée que BSD)
en fait, inittab lance le script rc général et lui passe le runlevel en argument:
l5:5:wait:/etc/rc.d/rc 5
rc va lancer les scripts du runlevel associé, dans l'ordre alpha.
/etc/rc.d/ contient un dossier rcN.d/ par runlevel (N)
ex: /etc/rc.d/rc5.d/
Ce dossier contient simplement des liens vers les scripts de /etc/init.d/ (qui doivent accepter au moins les arguments "start" et "stop")
Ces liens sont préfixés par S (Start) ou K (Kill).
Quand on entre dans un runlevel, tous les liens S* de ce runlevel sont exécutés (dans l'ordre alpha)
Quand on sort d'un runlevel, tous les liens K* de ce runlevel sont exécutés
Ex:
S85httpd lancera "/etc/init.d/httpd start"
Un lien /etc/rc.d/rc5.d/S42foobar sera exécuté à l'entrée du runlevel 5, et appellera /etc/init.d/foobar start
Il sera exécuté avant l'appel de S95barqux
Sur RedHat, seul le runlevel 5 lance X :
x:5:respawn:/etc/X11/prefdm -nodaemon
Le dernier script à être lancé est /etc/rc.d/rc.local
(on peut y mettre tout ce qu'on veut voir exécuter au boot)
Le prog update-rc.d peut être utilisé pour activer/désactiver des scripts au démarrage.
Ubuntu propose Upstart en remplacement du couple init/inittab
MacOS propose un "super-daemon" launchd qui regroupe les fonctionnalités de init (lance démon lors du démarrage), crond (lance démon lors de top horaires), et (x)inetd (lance démon lors de requêtes réseaux)
FTP
ex: installation ftp pour l'expérience RAMAN (sur ExoMars)
REMARQUE : pour faire la même chose en mode graphique,
il existe une interface graphique qui s'installe par-dessus GhostScript (en frontend),
c'est GhostView (gsview) :
La syntaxe Heredoc se comporte exactement comme une chaîne à guillemets doubles, sans les guillemets doubles. Cela signifie que vous n'avez pas à échapper les guillemets (simples ou doubles) dans cette syntaxe. Les variables sont remplacées par leur valeur et le même soin doit leur être apporté que dans les chaînes à guillemets doubles.
Exemple de chaîne HereDoc
Added:
> >
<?php
$str = <<<EOD
Line: 834 to 835
}
?>
Changed:
< <
> >
Fonctions anonymes (exemples d'algo de tri et de somme)
La syntaxe Heredoc se comporte exactement comme une chaîne à guillemets doubles, sans les guillemets doubles. Cela signifie que vous n'avez pas à échapper les guillemets (simples ou doubles) dans cette syntaxe. Les variables sont remplacées par leur valeur et le même soin doit leur être apporté que dans les chaînes à guillemets doubles.
Exemple de chaîne HereDoc
foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'MonNom';
echo <<foo.
Maintenant, j'affiche un {$foo->bar[1]}.
Ceci se traduit par un 'A' majuscule : \x41
EOT;
?>
Fonctions anonymes (exemples d'algo de tri et de somme)
La mission ExoMars, de l’Agence Spatiale Européenne (ESA), est une mission du programme Aurora. Son objectif est de caractériser l’environnement biologique martien pour préparer l’exploration humaine de la planète rouge.
Instrument CESR
EXLIBRIS serait capable d’effectuer une ablation des roches puis l’analyse de la composition de cette roche à la fois en chimie élémentaire (ultra-violet), en minéraux et composés organiques (Raman). Le CESR serait responsable de la partie LIBS (ultra-violet) et de la calibration de l’instrument. F. Rull Pérez (Centro de Astrobiologia , Espagne) serait en charge de la partie Raman.
Contexte de réalisation
IDL> doc_library, 'DIST'
----- Documentation for C:\Program Files\ITT\IDL\IDL80\lib\dist.pro
NAME:
DIST
PURPOSE:
Create a rectangular array in which each element is proportional
to its frequency. This array may be used for a variety
of purposes, including frequency-domain filtering and
making pretty pictures.
CATEGORY:
Signal Processing.
CALLING SEQUENCE:
Result = DIST(N [, M])
INPUTS:
N = number of columns in result.
M = number of rows in result. If omitted, N is used to return
a square array.
OUTPUTS:
Returns an (N,M) floating array in which:
R(i,j) = SQRT(F(i)^2 + G(j)^2) where:
F(i) = i IF 0 <= i <= n/2
= n-i IF i > n/2
G(i) = i IF 0 <= i <= m/2
= m-i IF i > m/2
SIDE EFFECTS:
None.
RESTRICTIONS:
None.
PROCEDURE:
Straightforward. The computation is done a row at a time.
MODIFICATION HISTORY:
Very Old.
SMR, March 27, 1991 - Added the NOZERO keyword to increase efficiency.
(Recomended by Wayne Landsman)
DMS, July, 1992. - Added M parameter to make non-square arrays.
CT, RSI, March 2000: Changed i^2 to i^2. to avoid overflow.
Dans ce dernier exemple (plot), on se rend compte que depuis idl 8, les nouvelles fonctions/procédures (telles que la fonction plot) ne sont plus commentées
au format "idl" mais "rst", qui semble donc être le nouveau format à utiliser pour commenter du code idl.
Je livre ici une synthèse des conseils de Michael Galloy pour bien documenter un code IDL (Lire "A style guide" pour la version complète avec justifications) :
idldoc est un outil qui permet de générer une doc à partir du code idl
Il propose 3 formats différents :
rst : le format le plus récent, qui tend à devenir le nouveau standard, il apporte beaucoup de possibilités
idldoc : le format historique de idldoc, qui ressemble à celui utilisé par des outils plus génériques, tels que Doxygen
idl : le format utilisé par ITT (et proposé dans examples/template.pro)
Ce dernier format ("idl") a juste le "mérite" d'être un standard pour les routines IDL, mais il est peu et mal exploité par IdlDoc qui ne reconnait que très peu de balises de commentaires (seulement 6) parmis celles proposées dans template.pro, et les met mal en valeur dans la doc générée.
Les 6 balises exploitées sont :
; PURPOSE:
; SIDE EFFECTS:
; RESTRICTIONS:
; PROCEDURE:
; EXAMPLE:
; MODIFICATION HISTORY:
Cette dernière balise est affichée en tant que "Author information" dans la doc générée
Quant à la balise suivante...
; CALLING SEQUENCE:
... elle n'est pas reconnue, mais elle semble inutile puisque cette information est automatiquement générée par idldoc.
> >
Le même bloc de commentaires, mais vide :
Deleted:
< <
8. Exemple possible de commentaires (donné par O Gasnault)
;+
; NAME:
Line: 640 to 599
Changed:
< <
IdlDoc : générateur de documentation pour IDL
> >
OUTILS pour documenter le code
doc_library
doc_library affiche seulement "tel quel" le bloc de commentaires complet compris entre ";+" et ";-", et affiche le chemin du fichier.
Pour documenter une fonction ou une procédure :
doc_library, 'DIST'
doc_library, 'plot'
Dans ce dernier exemple (plot), on se rend compte que depuis idl 8, les nouvelles fonctions/procédures (telles que la fonction plot) ne sont plus commentées
au format "idl" mais "rst", qui semble donc être le nouveau format à utiliser pour commenter du code idl.
mk_html_help
Cet outil génère une doc html d'un fichier ou même d'un répertoire complet :
ex: documentation du fichier dist.pro:
MK_HTML_HELP, 'C:\Program Files\ITT\IDL\IDL80\lib\dist.pro', 'help_dist.html' ; La doc générée est help_dist.html
ex: documentation d'une arborescence complète:
MK_HTML_HELP, 'C:\Program Files\ITT\IDL\IDL80\lib', 'help.html' ; La doc générée est help.html
Installation: (NB: sur hyperion, c'est déjà installé sous /usr/local/itt/idldoc/idldoc)
> >
idldoc est un outil qui permet de générer une doc à partir du code idl
Il propose 3 formats différents :
rst : le format le plus récent, qui tend à devenir le nouveau standard, il apporte beaucoup de possibilités
idldoc : le format historique de idldoc, qui ressemble à celui utilisé par des outils plus génériques, tels que Doxygen
idl : le format utilisé par ITT (et proposé dans examples/template.pro)
Ce dernier format ("idl") a juste le "mérite" d'être un standard pour les routines IDL, mais il est peu et mal exploité par IdlDoc qui ne reconnait que très peu de balises de commentaires (seulement 6) parmis celles proposées dans template.pro, et les met mal en valeur dans la doc générée.
Les 6 balises exploitées sont :
; PURPOSE:
; SIDE EFFECTS:
; RESTRICTIONS:
; PROCEDURE:
; EXAMPLE:
; MODIFICATION HISTORY:
Cette dernière balise est affichée en tant que "Author information" dans la doc générée
Quant à la balise suivante...
; CALLING SEQUENCE:
... elle n'est pas reconnue, mais elle semble inutile puisque cette information est automatiquement générée par idldoc.
Voir mes commentaires à l'auteur du logiciel et ses réponses:
contain the secondary parent class as an instance variable.
Added:
> >
8. Exemple de commentaires proposé par ITT dans examples/template.pro
;+
; NAME:
; ROUTINE_NAME
;
; PURPOSE:
; Tell what your routine does here. I like to start with the words:
; "This function (or procedure) ..."
; Try to use the active, present tense.
;
; CATEGORY:
; Put a category (or categories) here. For example:
; Widgets.
;
; CALLING SEQUENCE:
; Write the calling sequence here. Include only positional parameters
; (i.e., NO KEYWORDS). For procedures, use the form:
;
; ROUTINE_NAME, Parameter1, Parameter2, Foobar
;
; Note that the routine name is ALL CAPS and arguments have Initial
; Caps. For functions, use the form:
;
; Result = FUNCTION_NAME(Parameter1, Parameter2, Foobar)
;
; Always use the "Result = " part to begin. This makes it super-obvious
; to the user that this routine is a function!
;
; INPUTS:
; Parm1: Describe the positional input parameters here. Note again
; that positional parameters are shown with Initial Caps.
;
; OPTIONAL INPUTS:
; Parm2: Describe optional inputs here. If you don't have any, just
; delete this section.
;
; KEYWORD PARAMETERS:
; KEY1: Document keyword parameters like this. Note that the keyword
; is shown in ALL CAPS!
;
; KEY2: Yet another keyword. Try to use the active, present tense
; when describing your keywords. For example, if this keyword
; is just a set or unset flag, say something like:
; "Set this keyword to use foobar subfloatation. The default
; is foobar superfloatation."
;
; OUTPUTS:
; Describe any outputs here. For example, "This function returns the
; foobar superflimpt version of the input array." This is where you
; should also document the return value for functions.
;
; OPTIONAL OUTPUTS:
; Describe optional outputs here. If the routine doesn't have any,
; just delete this section.
;
; COMMON BLOCKS:
; BLOCK1: Describe any common blocks here. If there are no COMMON
; blocks, just delete this entry.
;
; SIDE EFFECTS:
; Describe "side effects" here. There aren't any? Well, just delete
; this entry.
;
; RESTRICTIONS:
; Describe any "restrictions" here. Delete this section if there are
; no important restrictions.
;
; PROCEDURE:
; You can describe the foobar superfloatation method being used here.
; You might not need this section for your routine.
;
; EXAMPLE:
; Please provide a simple example here. An example from the
; DIALOG_PICKFILE documentation is shown below. Please try to
; include examples that do not rely on variables or data files
; that are not defined in the example code. Your example should
; execute properly if typed in at the IDL command line with no
; other preparation.
;
; Create a DIALOG_PICKFILE dialog that lets users select only
; files with the extension `pro'. Use the `Select File to Read'
; title and store the name of the selected file in the variable
; file. Enter:
;
; file = DIALOG_PICKFILE(/READ, FILTER = '*.pro')
;
; MODIFICATION HISTORY:
; Written by: Your name here, Date.
; July, 1994 Any additional mods get described here. Remember to
; change the stuff above if you add a new keyword or
; something!
;-
PRO TEMPLATE
PRINT, "This is an example header file for documenting IDL routines"
END
idldoc est un outil qui permet de générer une doc à partir du code idl
Il propose 3 formats différents :
rst : le format le plus récent, qui tend à devenir le nouveau standard, il apporte beaucoup de possibilités
idldoc : le format historique de idldoc, qui ressemble à celui utilisé par des outils plus génériques, tels que Doxygen
idl : le format utilisé par ITT (et proposé dans examples/template.pro)
Ce dernier format ("idl") a juste le "mérite" d'être un standard pour les routines IDL, mais il est peu et mal exploité par IdlDoc qui ne reconnait que très peu de balises de commentaires (seulement 6) parmis celles proposées dans template.pro, et les met mal en valeur dans la doc générée.
Les 6 balises exploitées sont :
; PURPOSE:
; SIDE EFFECTS:
; RESTRICTIONS:
; PROCEDURE:
; EXAMPLE:
; MODIFICATION HISTORY:
Cette dernière balise est affichée en tant que "Author information" dans la doc générée
Quant à la balise suivante...
; CALLING SEQUENCE:
... elle n'est pas reconnue, mais elle semble inutile puisque cette information est automatiquement générée par idldoc.
8. Exemple possible de commentaires (donné par O Gasnault)
1. Use lowercase for reserved words, operators, and compile_opt option names.
> >
1. Use lowercase for reserved words, operators, and compile_opt option names.
For example, use:
Added:
> >
compile_opt strictarr
if (not done) then readf, lun, line
Changed:
< <
2. Use only one statement per line.
Multiple commands can be entered on one line using the & to separate them. This can be useful on the command
line, but don't use it for code in files: routines, batch files, or main-level programs. For example, don't write:
> >
2. Use only one statement per line.
For example, don't write:
a = 1 & b = 2
Changed:
< <
3. Prefer begin/end blocks unless the entire statements fits on one line.
For example, for a single short statement in a compound statement, use:
for i = 0, 10 do print, i
For a multiple statement block, write:
for i = 0, 10 do begin
j = i^2
print, j
endfor
> >
3. Prefer begin/end blocks unless the entire statements fits on one line.
For a single, long statement, use:
Added:
> >
for i = 0, 10 do begin
print, i, format='("The index is ", I0, ".")'
end
Added:
> >
But never write:
Added:
> >
for i = 0, 10 do $
print, i, format='("The index is ", I0, ".")'
Changed:
< <
The same holds for each case of a case or switch statement:
> >
5. Define structures one field per line unless the entire definition can fit on one line.
Deleted:
< <
Statement formatting
6
case uname of
'tlb': resize_widget, event.x, event.y
'draw': begin
if (event.type ne 2) then return ; type 2 = motion events
(*pstate).x = event.x
(*pstate).y = event.y
end
else:
endcase
4. Use specific end statements for the ending a block: endif, endwhile, endrep, endcase, and endswitch.
Using the appropriate end statement lets the IDL compiler help catch structural errors in the code.
There are no specific end statements for each case of a case or switch statement or the end of a routine or mainlevel
program, so just use end.
5. Define structures one field per line unless the entire definition can fit on one line.
For example, use:
Added:
> >
point = { x: 0.0, y:0.0 }
state = { x: 0.0, $
y: 0.0, $
pdata: ptr_new(), $ ; image data
drawId: 0L $ ; window identifier
}
Changed:
< <
Defining each field on its own line allows for individual fields to be found more easily and to be documented on
the same line they are defined on.
6. Add one space around most operators.
Normal arithmetic operators should have one space before and after them, for example:
> >
6. Add one space around most operators.
ex:
slope = (y0 - y1) / (x0 - x1)
Changed:
< <
There are many exceptions to this rule. Don't put spaces around -> for method invocation or = for keyword use
(but do for = for assignment). Don't put extra spaces around ()'s or []'s in any of their uses, but do add an extra
space inside {}'s. Examples:
> >
tvscl, im, true=1
Added:
> >
bin = arr[r[r[i]:r[i + 1] - 1]]
Added:
> >
point = { x: 0.0, y: 0.0 }
Changed:
< <
Don't add extra spaces in order to align values. For example, do:
x = 1
y = 2
longer = 3
instead of
x = 1
y = 2
longer = 3
7. Use single quotes for strings.
Both single and double quoted strings are allowed in IDL. Use only single quoted strings to avoid clashing with
the strange octal value notation that uses double quotes,
Statement formatting
7
age = "22 years"
is a syntax error because
age = "22
defines age to be 22 in octal (18 in decimal). The additional years" in the previous statement is not understood
by the IDL parser.
> >
Also, don't add extra spaces in order to align values.
7. Use single quotes for strings.
Use double single quotes if you need a single quote. For example,
Added:
> >
sign = 'Eat at Joe''s'
Changed:
< <
8. Don't mix the bitwise operators and, or, and not with the logical operators &&, ||, and ~.
Always use and, or, and not for all bitwise operations. For logical operations, either use the bitwise operators
or (if using IDL 6.0 or later) use the logical operators &&, ||, and ~ along with the logical_predicate option to
compile_opt.
9. Use capital letters to indicate the type of constant, use lowercase to indicate base of integers.
> >
9. Use capital letters to indicate the type of constant, use lowercase to indicate base of integers.
Use 0L not 0l because "l" (lowercase letter el) looks like "1" (integer one). Use '5'o and '5'x, not '5'O and
'5'X.
Changed:
< <
Create constants of the correct type instead of creating a variable of the incorrect type and having IDL convert
it. Though IDL will automatically convert it, that adds some overhead and, more importantly, obscures the type
of the variable for readers of the code.
10. Use square brackets for array indices.
> >
10. Use square brackets for array indices.
Use
Added:
> >
compile_opt strictarr
Added:
> >
in each routine to prevent issues with IDL confusing arrays and functions calls.
Changed:
< <
11. Indent continuation lines of routine declarations and calls with the first argument.
For example, do:
pro mgitopadapthistequal::getProperty, clip=clip, $
nregions=nregions, $
top=top, $
_ref_extra=e
12. Indent continuation lines of assignment statements to the right of the =.
For example,
self.eyeEccentricity = n_elements(eye_eccentricity) eq 0 $
? 0.5 $
: eye_eccentricity
13. Indent continuation lines of looping and conditional statements with the condition.
For example,
if (arg_present(sdev) $
|| arg_present(variance) $
|| arg_present(skewness) $
Variables
8
|| arg_present(kurtosis)) then begin
This can often be rewritten more clearly with the use of some variables that hold sections of the full expression.
14. Use labels sparingly for goto and ON_IOERROR statements.
Use lowercase short names for labels. Indent labels with surrounding code. Place the label on its own line.
For example,
on_ioerror, io_problem
openr, lun, filename, /get_lun
arr = fltarr(100)
readu, lun, arr
free_lun, lun
return, arr
io_problem:
print, err_string
5. Variables
> >
5. Variables
1. Use good variable names.
Changed:
< <
Think for a while. A thesaurus can be a valuable tool for finding the right name. Shorter names are acceptable
if the variable is used only in a small section of code (such as a loop variable). Do use the standard names for
common variables: state, pState, event, and tlb.
> >
2. Variable names should be in camel case.
Added:
> >
Camel case uppercases the first letter of each word in the name except for the first letter.
Changed:
< <
Uppercase each letter in an abbreviation that appears in a variable name unless it starts the name, i.e.
> >
Uppercase each letter in an abbreviation that appears in a variable name unless it starts the name:
noaaWeatherURL.
Changed:
< <
Prefix a local variable with "my" when it mirrors a parameter, but has possibly been modified with a default
value. Prefix the name with "n" for variables that hold counts, "o" for object references, "p" for pointers, "id" for
> >
Prefix the name with "n" for variables that hold counts, "o" for object references, "p" for pointers, "id" for
iTools identifiers.
Added:
> >
Examples that follow this convention,
Changed:
< <
myParam
> >
nFiles
oModel
pState
idPlot
Added:
> >
3. Prefer pointers, objects, and passing local variables over common blocks or system variables.
Added:
> >
Occasionally there is a reason to use common blocks or system variables, but you should have a good argument
for it.
Added:
> >
When using direct graphics, prefer using graphics keywords of the plotting routines over setting system
variables directly.
Line: 375 to 331
When using direct graphics, prefer using graphics keywords of the plotting routines over setting system
variables directly.
Deleted:
< <
Routines
9
4. Define common blocks and named structures in only one location.
Added:
> >
Define the variables in a common block only once in a batch file. Include that file where needed.
Added:
> >
map_proj_init_commonblock.pro is an example of this.
Added:
> >
Define a named structure using automatic structure definition. For example, define MG_Point in a routine
named MG_POINT__DEFINE in a file named mg_point__define.pro.
Changed:
< <
6. Routines
> >
6. Routines
1. For any file containing IDL code, filenames should always be in lower case and use the ".pro" extension.
Changed:
< <
Lowercase filenames reduce cross-platform issues. IDL will automatically find code that is in files using the
".pro" extension (provided it follows the other conventions listed in below).
> >
2. Each file should include only one routine called from outside the file.
Added:
> >
Each file should contain only one routine called from outside that file. Add the ".pro" extension to the routine
name of the externally called routine to get the filename. For example, the routine MG_LINEAR_FUNCTION
should be in a file named mg_linear_function.pro. If there are multiple routines in the file, make sure the
Line: 390 to 350
Each file should contain only one routine called from outside that file. Add the ".pro" extension to the routine
name of the externally called routine to get the filename. For example, the routine MG_LINEAR_FUNCTION
should be in a file named mg_linear_function.pro. If there are multiple routines in the file, make sure the
Changed:
< <
externally called routine is last in the file. Following this rule will insure that IDL automatically finds and
compiles all code necessary (provided the files are in the IDL path or current directory). The names of the
helper routines in the same file should be prefixed with the entire name of the external routine, such as
MG_LINEAR_FUNCTION_HELPER.
A prominent exception to this rule is the case of class definition files which should include all the methods of
the class, many of which could be called from outside the file. IDL will still find the methods automatically if
done following the style rules in the section on object-oriented programming.
> >
externally called routine is last in the file.
3. Routine names should be lower case, begin with a short organization prefix, and separate words with
underscores.
Added:
> >
The prefix indicates the individual or group responsible for the code. It is usually the initials of the individual or
orgranization. Limit to two or three letters. Don't use the "IDL", "RSI", "ITT", "cw", "it", or empty prefixes.
Changed:
< <
For example, here are some names following this style:
mg_linear_function
mg_itbrowser
mg_sample
> >
4. Routines should fit on one screen.
Changed:
< <
It is much easier to understand a routine when it can viewed in its entirety. An exception are routines with case
statements where there are many short cases.
> >
5. Keywords should always be optional for the caller; positional parameters should generally be required.
Added:
> >
Keywords should either be an optional input with a reasonable default value or an extra output (i.e. not the
Changed:
< <
main purpose of the routine). This allows new users of the routine to focus on the few positional parameters and
examine the more numerous keywords as needed when the default values are not appropriate for them.
> >
main purpose of the routine).
6. Keyword names should be lowercase and separate words with underscores.
Deleted:
< <
Object-oriented programming
10
For example,
Added:
> >
filename
ntests
eye_separation
left_image
Added:
> >
7. Always use the full keyword name when calling the routine.
Changed:
< <
The same abbreviations which are so handy when typing at the commandline become quite cryptic when written
in a file and examined years later. They may even be ambiguous if new versions of the code they call have
been released (with more keywords) in the meantime. Using the full name prevents ambiguity and increases the
readability.
> >
8. If the purpose of a routine is to return a value, use a function, otherwise use a procedure.
Changed:
< <
If the main purpose of the routine is to perform some action (besides a query), but incidentally needs to return
a value use a procedure with an output keyword. In general, use a function when it would be useful to chain
together multiple calls in one expression.
Avoid the C-style status as the function return value.
> >
9. Status and error codes should be returned via keyword.
Changed:
< <
Often this means that a function needs to return a null or impossible value if an error occurs during execution.
For example, WHERE returns -1 when there are no matching elements of the given array.
10. Setup firewalls for error handling as appropriate to the application.
Data that crosses a firewall should be checked carefully for correctness. There should always be a firewall
around the entire program for data coming in (from files, network, or user). Other firewalls should be added as
appropriate to the application: some may require a firewall around each routine, others between "packages", and
others may require no other firewalls besides the outside wall.
Use
on_error, 2
in simple, short routines when you become confident that the only errors occurring in the routine are from bad
inputs.
7. Object-oriented programming
In addition to the other rules, there are a few extra guidelines for writing object-oriented code.
> >
7. Object-oriented programming
1. Class names should begin with a prefix indicating organization and a code indicating the class' area of use.
Each word should be capitalized
Added:
> >
Use the same prefix as given to normal routine names; avoid "IDL", "ITT", "RSI", and the empty prefix.
Added:
> >
Codes already in use by IDL: an (analysis), com (COM), db (database), ex (example), ff (file format), gr
(graphics), it (iTools), sys (system), net (network), and _ (general use). Make use of the existing codes and
make up new ones as necessary.
Line: 452 to 393
(graphics), it (iTools), sys (system), net (network), and _ (general use). Make use of the existing codes and
make up new ones as necessary.
Deleted:
< <
Object-oriented programming
11
The examples,
MGgrWindow3DMGffTemplateMGutTestCase
use the codes gr and ff already in use by IDL, but creates a new code ut (for unit testing) because none is
provided.
Use all caps for abbreviations in class names, as in IDLnetURL.
Added:
> >
2. Put all the methods and the routine defining the instance variables for a class into a single file.
Added:
> >
For the definition of MGexClass, the file should be named mgexclass__define.pro. The last routine in this file
should be MGEXCLASS__DEFINE and should define the instance variables for the class (i.e. create a named
structure with name MGexClass).
Line: 465 to 400
For the definition of MGexClass, the file should be named mgexclass__define.pro. The last routine in this file
should be MGEXCLASS__DEFINE and should define the instance variables for the class (i.e. create a named
structure with name MGexClass).
Added:
> >
Define only one structure/class name in the __DEFINE routine.
Added:
> >
3. Method names should be a verb phrase in camel case.
Added:
> >
For example, here are some method names following these conventions:
Use the conventions that are used by the IDL library classes. For example, use the GETPROPERTY and
SETPROPERTY scheme of procedures to handle getting and setting properties of a class.
Added:
> >
4. Begin "protected" methods' names with a underscore.
is a helper method called by other methods in MGexSomeClass, but should not be called from outside of
MGexSomeClass.
Changed:
< <
Because IDL has no mechanism for limiting who can call a method, the underscore merely indicates that only
that class and its subclasses should call that method. This gives a visual cue to the caller without enforcing the
protection. Outside callers can still call this method, but at least they have been warned.
> >
5. Beware of multiple inheritance.
Added:
> >
Use multiple inheritance as a last resort. Prefer delegation for one of the parent classes i.e. make the new class
contain the secondary parent class as an instance variable.
Deleted:
< <
Reference
Listed below are some references that provided inspiration for the rules included in this style guide.
[Custom99] Custom Visuals. “IDL Style Guide”. www.customvisuals.com/IDL_Style.html. 1999.
Object-oriented programming
12
[Fanning03] David Fanning. Coyote's Guide to IDL Programming. www.dfanning.com. “IDL Style Guide”. 2003.
[ITTVIS07] ITT Visual Information Solutions. www.ittvis.com. “One Proposal for an IDL Coding Standard”. Tech
Tip 4120. 2007.
[KernPlauger78] Brian W. Kernighan and P. J. Plauger. The Elements of Programming Style. 2nd edition. 1978.
[McConnell04] Steve McConnell. Code Complete. 2nd edition. 2004.
[Rossum01] Python Enhancement Proposals. www.python.org/dev/peps. Guido van Rossum and Barry Warsaw.
“Python PEP-8: Style Guide for Python”. 2001.
Je livre ici une synthèse des conseils de Michael Galloy pour bien documenter un code IDL (Lire "A style guide" pour la version complète avec justifications) :
1. General principles
1. Code is for humans.
2. Do not mix styles.
3. Avoid redundancy.
4. Use an easy to maintain style.
2. Layout
1. Layout should enhance the logical structure of the code.
2. Use two spaces (not tabs) per indentation level.
3. Use a maximum line length of 79 characters.
4. Write code in paragraphs.
Example:
function mg_sample, nValues, nIndices, seed=seed
compile_opt strictarr
; get random nIndices by finding the indices of the smallest
; nIndices in an array of random values
values = randomu(seed, nValues)
; our random values are uniformly distributed, so ideally
; the nIndices smallest values are in the first bin of the
; below histogram
nBins = nValues / nIndices
h = histogram(values, nbins=nBins, reverse_indices=ri)
; the candidates for being in the first nIndices will live in
; bins 0..bin
nCandidates = 0L
for bin = 0L, nBins - 1L do begin
nCandidates += h[bin]
if (nCandidates ge nIndices) then break
endfor
; get the candidates and sort them
candidates = ri[ri[0] : ri[bin + 1L] - 1L]
sortedCandidates = sort(values[candidates])
; return the first nIndices of them
return, (candidates[sortedCandidates])[0:nIndices-1L]
end
5. Insert two blank lines between routines.
One blank line separates "paragraphs"; two blank lines separate "sections."
3. Comments
1. Document intent.
2. Keep comments up to date with the code.
3. For a short comment, use a phrase with lowercase first letter and no period. For longer comments, use all
normal grammar rules.
5. Write a complete header for each routine.
Use comments between ;+ and ;- before the routine. Document the purpose of the routine, the return value (if
a function), and side effects of the routine (which you should strive to eliminate). Each parameter should be
documented with whether it is an input and/or output, optional or required, data type expected, default value (if
any) and a description of its purpose.
For example, the below is an IDLdoc formatted header for the routine listed above:
;+
; Get nIndices random indices for an array of size nValues (do
; not repeat an index).
;
; :Returns: lonarr(nIndices)
;
; :Params:
; nValues : in, required, type=long
; size of array to choose indices from
; nIndices : in, required, type=long
; number of indices needed
;
; :Keywords:
; seed : in, out, optional, type=long or lonarr(36)
; seed to use for random number generation, a new seed
; will be output
;-
function mg_sample, nValues, nIndices, seed=seed
6. Indent a comment along with the code it's documenting.
7. Document paragraph by paragraph.
Each paragraph of code may need a comment to document its purpose, but inside a paragraph use only end-of-line
comments to comment particular lines.
It can be helpful to write the comments first, providing an outline of the code to write.
ex of end-of-line comment :
if (event.type eq 2) then begin ; type 2 = motion events
9. Don't repeat the code in the comments.
Don't document the obvious.
10. Don't add extra comments for convoluted code; improve the code.
Don't document bad code—rewrite it. (Kernighan and Plauger, The Elements of Programming Style)
4. Statement formatting
1. Use lowercase for reserved words, operators, and compile_opt option names.
For example, use:
compile_opt strictarr
if (not done) then readf, lun, line
2. Use only one statement per line.
Multiple commands can be entered on one line using the & to separate them. This can be useful on the command
line, but don't use it for code in files: routines, batch files, or main-level programs. For example, don't write:
a = 1 & b = 2
3. Prefer begin/end blocks unless the entire statements fits on one line.
For example, for a single short statement in a compound statement, use:
for i = 0, 10 do print, i
For a multiple statement block, write:
for i = 0, 10 do begin
j = i^2
print, j
endfor
For a single, long statement, use:
for i = 0, 10 do begin
print, i, format='("The index is ", I0, ".")'
end
But never write:
for i = 0, 10 do $
print, i, format='("The index is ", I0, ".")'
The same holds for each case of a case or switch statement:
Statement formatting
6
case uname of
'tlb': resize_widget, event.x, event.y
'draw': begin
if (event.type ne 2) then return ; type 2 = motion events
(*pstate).x = event.x
(*pstate).y = event.y
end
else:
endcase
4. Use specific end statements for the ending a block: endif, endwhile, endrep, endcase, and endswitch.
Using the appropriate end statement lets the IDL compiler help catch structural errors in the code.
There are no specific end statements for each case of a case or switch statement or the end of a routine or mainlevel
program, so just use end.
5. Define structures one field per line unless the entire definition can fit on one line.
For example, use:
point = { x: 0.0, y:0.0 }
state = { x: 0.0, $
y: 0.0, $
pdata: ptr_new(), $ ; image data
drawId: 0L $ ; window identifier
}
Defining each field on its own line allows for individual fields to be found more easily and to be documented on
the same line they are defined on.
6. Add one space around most operators.
Normal arithmetic operators should have one space before and after them, for example:
slope = (y0 - y1) / (x0 - x1)
There are many exceptions to this rule. Don't put spaces around -> for method invocation or = for keyword use
(but do for = for assignment). Don't put extra spaces around ()'s or []'s in any of their uses, but do add an extra
space inside {}'s. Examples:
tvscl, im, true=1
bin = arr[r[r[i]:r[i + 1] - 1]]
point = { x: 0.0, y: 0.0 }
Don't add extra spaces in order to align values. For example, do:
x = 1
y = 2
longer = 3
instead of
x = 1
y = 2
longer = 3
7. Use single quotes for strings.
Both single and double quoted strings are allowed in IDL. Use only single quoted strings to avoid clashing with
the strange octal value notation that uses double quotes,
Statement formatting
7
age = "22 years"
is a syntax error because
age = "22
defines age to be 22 in octal (18 in decimal). The additional years" in the previous statement is not understood
by the IDL parser.
Use double single quotes if you need a single quote. For example,
sign = 'Eat at Joe''s'
8. Don't mix the bitwise operators and, or, and not with the logical operators &&, ||, and ~.
Always use and, or, and not for all bitwise operations. For logical operations, either use the bitwise operators
or (if using IDL 6.0 or later) use the logical operators &&, ||, and ~ along with the logical_predicate option to
compile_opt.
9. Use capital letters to indicate the type of constant, use lowercase to indicate base of integers.
Use 0L not 0l because "l" (lowercase letter el) looks like "1" (integer one). Use '5'o and '5'x, not '5'O and
'5'X.
Create constants of the correct type instead of creating a variable of the incorrect type and having IDL convert
it. Though IDL will automatically convert it, that adds some overhead and, more importantly, obscures the type
of the variable for readers of the code.
10. Use square brackets for array indices.
Use
compile_opt strictarr
in each routine to prevent issues with IDL confusing arrays and functions calls.
11. Indent continuation lines of routine declarations and calls with the first argument.
For example, do:
pro mgitopadapthistequal::getProperty, clip=clip, $
nregions=nregions, $
top=top, $
_ref_extra=e
12. Indent continuation lines of assignment statements to the right of the =.
For example,
self.eyeEccentricity = n_elements(eye_eccentricity) eq 0 $
? 0.5 $
: eye_eccentricity
13. Indent continuation lines of looping and conditional statements with the condition.
For example,
if (arg_present(sdev) $
|| arg_present(variance) $
|| arg_present(skewness) $
Variables
8
|| arg_present(kurtosis)) then begin
This can often be rewritten more clearly with the use of some variables that hold sections of the full expression.
14. Use labels sparingly for goto and ON_IOERROR statements.
Use lowercase short names for labels. Indent labels with surrounding code. Place the label on its own line.
For example,
on_ioerror, io_problem
openr, lun, filename, /get_lun
arr = fltarr(100)
readu, lun, arr
free_lun, lun
return, arr
io_problem:
print, err_string
5. Variables
1. Use good variable names.
Think for a while. A thesaurus can be a valuable tool for finding the right name. Shorter names are acceptable
if the variable is used only in a small section of code (such as a loop variable). Do use the standard names for
common variables: state, pState, event, and tlb.
2. Variable names should be in camel case.
Camel case uppercases the first letter of each word in the name except for the first letter.
Uppercase each letter in an abbreviation that appears in a variable name unless it starts the name, i.e.
noaaWeatherURL.
Prefix a local variable with "my" when it mirrors a parameter, but has possibly been modified with a default
value. Prefix the name with "n" for variables that hold counts, "o" for object references, "p" for pointers, "id" for
iTools identifiers.
Examples that follow this convention,
myParam
nFiles
oModel
pState
idPlot
3. Prefer pointers, objects, and passing local variables over common blocks or system variables.
Occasionally there is a reason to use common blocks or system variables, but you should have a good argument
for it.
When using direct graphics, prefer using graphics keywords of the plotting routines over setting system
variables directly.
Routines
9
4. Define common blocks and named structures in only one location.
Define the variables in a common block only once in a batch file. Include that file where needed.
map_proj_init_commonblock.pro is an example of this.
Define a named structure using automatic structure definition. For example, define MG_Point in a routine
named MG_POINT__DEFINE in a file named mg_point__define.pro.
6. Routines
1. For any file containing IDL code, filenames should always be in lower case and use the ".pro" extension.
Lowercase filenames reduce cross-platform issues. IDL will automatically find code that is in files using the
".pro" extension (provided it follows the other conventions listed in below).
2. Each file should include only one routine called from outside the file.
Each file should contain only one routine called from outside that file. Add the ".pro" extension to the routine
name of the externally called routine to get the filename. For example, the routine MG_LINEAR_FUNCTION
should be in a file named mg_linear_function.pro. If there are multiple routines in the file, make sure the
externally called routine is last in the file. Following this rule will insure that IDL automatically finds and
compiles all code necessary (provided the files are in the IDL path or current directory). The names of the
helper routines in the same file should be prefixed with the entire name of the external routine, such as
MG_LINEAR_FUNCTION_HELPER.
A prominent exception to this rule is the case of class definition files which should include all the methods of
the class, many of which could be called from outside the file. IDL will still find the methods automatically if
done following the style rules in the section on object-oriented programming.
3. Routine names should be lower case, begin with a short organization prefix, and separate words with
underscores.
The prefix indicates the individual or group responsible for the code. It is usually the initials of the individual or
orgranization. Limit to two or three letters. Don't use the "IDL", "RSI", "ITT", "cw", "it", or empty prefixes.
For example, here are some names following this style:
mg_linear_function
mg_itbrowser
mg_sample
4. Routines should fit on one screen.
It is much easier to understand a routine when it can viewed in its entirety. An exception are routines with case
statements where there are many short cases.
5. Keywords should always be optional for the caller; positional parameters should generally be required.
Keywords should either be an optional input with a reasonable default value or an extra output (i.e. not the
main purpose of the routine). This allows new users of the routine to focus on the few positional parameters and
examine the more numerous keywords as needed when the default values are not appropriate for them.
6. Keyword names should be lowercase and separate words with underscores.
Object-oriented programming
10
For example,
filename
ntests
eye_separation
left_image
7. Always use the full keyword name when calling the routine.
The same abbreviations which are so handy when typing at the commandline become quite cryptic when written
in a file and examined years later. They may even be ambiguous if new versions of the code they call have
been released (with more keywords) in the meantime. Using the full name prevents ambiguity and increases the
readability.
8. If the purpose of a routine is to return a value, use a function, otherwise use a procedure.
If the main purpose of the routine is to perform some action (besides a query), but incidentally needs to return
a value use a procedure with an output keyword. In general, use a function when it would be useful to chain
together multiple calls in one expression.
Avoid the C-style status as the function return value.
9. Status and error codes should be returned via keyword.
Often this means that a function needs to return a null or impossible value if an error occurs during execution.
For example, WHERE returns -1 when there are no matching elements of the given array.
10. Setup firewalls for error handling as appropriate to the application.
Data that crosses a firewall should be checked carefully for correctness. There should always be a firewall
around the entire program for data coming in (from files, network, or user). Other firewalls should be added as
appropriate to the application: some may require a firewall around each routine, others between "packages", and
others may require no other firewalls besides the outside wall.
Use
on_error, 2
in simple, short routines when you become confident that the only errors occurring in the routine are from bad
inputs.
7. Object-oriented programming
In addition to the other rules, there are a few extra guidelines for writing object-oriented code.
1. Class names should begin with a prefix indicating organization and a code indicating the class' area of use.
Each word should be capitalized
Use the same prefix as given to normal routine names; avoid "IDL", "ITT", "RSI", and the empty prefix.
Codes already in use by IDL: an (analysis), com (COM), db (database), ex (example), ff (file format), gr
(graphics), it (iTools), sys (system), net (network), and _ (general use). Make use of the existing codes and
make up new ones as necessary.
Object-oriented programming
11
The examples,
MGgrWindow3DMGffTemplateMGutTestCase
use the codes gr and ff already in use by IDL, but creates a new code ut (for unit testing) because none is
provided.
Use all caps for abbreviations in class names, as in IDLnetURL.
2. Put all the methods and the routine defining the instance variables for a class into a single file.
For the definition of MGexClass, the file should be named mgexclass__define.pro. The last routine in this file
should be MGEXCLASS__DEFINE and should define the instance variables for the class (i.e. create a named
structure with name MGexClass).
Define only one structure/class name in the __DEFINE routine.
3. Method names should be a verb phrase in camel case.
For example, here are some method names following these conventions:
getProperty
setProperty
add
findTestNames
runTest
reportTestResult
Use the conventions that are used by the IDL library classes. For example, use the GETPROPERTY and
SETPROPERTY scheme of procedures to handle getting and setting properties of a class.
4. Begin "protected" methods' names with a underscore.
For example,
MGexSomeClass::_helperMethod
is a helper method called by other methods in MGexSomeClass, but should not be called from outside of
MGexSomeClass.
Because IDL has no mechanism for limiting who can call a method, the underscore merely indicates that only
that class and its subclasses should call that method. This gives a visual cue to the caller without enforcing the
protection. Outside callers can still call this method, but at least they have been warned.
5. Beware of multiple inheritance.
Use multiple inheritance as a last resort. Prefer delegation for one of the parent classes i.e. make the new class
contain the secondary parent class as an instance variable.
Reference
Listed below are some references that provided inspiration for the rules included in this style guide.
[Custom99] Custom Visuals. “IDL Style Guide”. www.customvisuals.com/IDL_Style.html. 1999.
Object-oriented programming
12
[Fanning03] David Fanning. Coyote's Guide to IDL Programming. www.dfanning.com. “IDL Style Guide”. 2003.
[ITTVIS07] ITT Visual Information Solutions. www.ittvis.com. “One Proposal for an IDL Coding Standard”. Tech
Tip 4120. 2007.
[KernPlauger78] Brian W. Kernighan and P. J. Plauger. The Elements of Programming Style. 2nd edition. 1978.
[McConnell04] Steve McConnell. Code Complete. 2nd edition. 2004.
[Rossum01] Python Enhancement Proposals. www.python.org/dev/peps. Guido van Rossum and Barry Warsaw.
“Python PEP-8: Style Guide for Python”. 2001.
Outil de visualisation graphique des logs : gnome-system-log
logrotate
/etc/logrotate.conf
/etc/logrotate.d/
Line: 304 to 318
==> new file "messages", "messages" devient "messages1", "messages1" devient "messages2"...
Added:
> >
logwatch
by default, runs daily on yesterday's logs (/etc/cron.daily/0logwatch qui pointe sur /usr/share/logwatch/scripts/logwatch.pl), includes all services, and sends a mail to root
vi /etc/ssh/sshd_config
Port 22 : on pourrait mettre ici un autre port, genre 2010, histoire de brouiller les pirates...
PermitRootLogin? no
LoginGraceTime? 2m
changed to :
LoginGraceTime? 30
/etc/init.d/sshd restart
Dans, Main/TWikiPreferences (ou bien dans Main/WebPreferences si on ne veut affecter qu'un seul web, et pas tout le twiki), vérifier qu'on a bien une ligne contenant :
> >
Par exemple, créer comme raccourci de l'icône TODO :
Faire une copie (de sauvegarde) d'un Web (pour consultation offline) :
Grace au plugin PublishContrib, on peut obtenir une copie du Web à tout instant (attention, cette copie est READ ONLY, ce n'est plus un wiki, mais juste des pages web).
Pour publier la version courante du Web, aller sur le topic PublishWeb, et cliquer sur le bouton "Publish" (en milieu de page). Par défaut, c'est l'option "zip" qui est sélectionnée, ce qui crée un zip du Web.
Il suffit maintenant de cliquer en bas de la page générée par la requete, sur le lien "Published To: NomduWeb.zip", pour télécharger ce zip (L'accès à cette adresse est protégé pour que seuls les personnes enregistrées puissent y acceder)
Dézipper et cliquer sur la page WebHome.html. Le résultat n'est pas très joli, mais le contenu y est...
Un historique de la dernière publication se trouve dans le topic PublishContribHistory (utile pour voir si tout s'est bien passé)
Changed:
< <
Voir ce qui change sur le site
> >
Mise à jour d'une pièce attachée (remarque) :
Changed:
< <
Pour savoir ce qui a changé (en ordre chronologique), consulter cette page :
WebChanges
> >
Il vaut mieux utiliser des noms de fichier assez génériques (par exemple FDD.pdf au lieu de FF_v1.4.pdf) ainsi on peut mettre à jour un document sans changer son nom et les liens vers ce fichier
Changed:
< <
on peut aussi s'inscrire sur cette page pour recevoir les changements par email :
WebNotify
Pour que quelqu'un puisse accéder à ce site, il faut d'abord qu'il s'inscrive (sauf s'il est déjà inscrit sur Chemcam, c'est le même login).
Ensuite, il faut ajouter son login dans le groupe autorisé à consulter et modifier ce wiki, c'est à dire TeamGroup.
Ensuite, il faut ajouter son login dans le groupe autorisé à consulter et modifier ce wiki, c'est à dire TeamGroup.
Deleted:
< <
LINUX
Niveau Utilisateur
Added:
> >
Forwarder les mails du serveur
Par exemple, je veux forwarder mes mails de pallier@planetoweb.cesr.fr vers ma boite cesr ou encore ma boite perso :
cd ~
créer un fichier ".forward" contenant mon adresse cesr ou perso
S'il s'agit de forwarder les mails adressés à root@planetoweb.cesr.fr, on peut utiliser la même solution, mais on peut aussi
ajouter cette ligne tout à la fin du fichier /etc/aliases
Dans, Main/TWikiPreferences (ou bien dans Main/WebPreferences si on ne veut affecter qu'un seul web, et pas tout le twiki), vérifier qu'on a bien une ligne contenant :
*Set SKIN = pattern
On peut alors modifier le style du PatternSkin, dans twiki/pub/TWiki/PatternSkin :
Par exemple, pour modifier l'indentation des titres (h1,h2,...), ajouter ces lignes à la fin de style.css :
Pour savoir ce qui a changé (en ordre chronologique), consulter cette page :
WebChanges
on peut aussi s'inscrire sur cette page pour recevoir les changements par email :
WebNotify
Contribuer (enrichir le site)
Vous êtes vivement encouragés à contribuer au contenu de ce site.
Pour modifier n'importe quelle page du site :
cliquez sur bouton "Edit", faites vos modifs, puis cliquez sur le bouton "Save".
si vous êtes plus à l'aise avec la souris, cliquez plutot sur le bouton "WYSIWYG"
Accéder au site
Pour que quelqu'un puisse accéder à ce site, il faut d'abord qu'il s'inscrive (sauf s'il est déjà inscrit sur Chemcam, c'est le même login).
Ensuite, il faut ajouter son login dans le groupe autorisé à consulter et modifier ce wiki, c'est à dire TeamGroup.
LINUX
Niveau Utilisateur
Line: 30 to 69
Ce fichier est automatiquement lu par /etc/profile au démarrage d'une session
Changed:
< <
Imprimer sous linux
> >
Imprimer sur linux
Pour installer l'imprimante "sprinter", voir SprinterPrinter
Line: 41 to 80
Pour imprimer du texte, on peut utiliser les utilitaires "a2ps" ou "enscript"
Added:
> >
Visualiser des images (jpeg, ps, ...) en mode console
display
Note : display permet aussi de convertir une image d'un format vers un autre (enregistrer sous...)
Voir aussi "xv" et "gthumb"
Convertir une image d'un format vers un autre
PS to PDF : ps2pdf
Voir aussi l'utilitaire convert
En mode interactif, On peut aussi utiliser display (voir ci-dessus)
Niveau Administrateur
Samba
Changed:
< <
II - Windows
> >
WINDOWS
Envoyer des mails avec Outlook quand on n'est pas au CESR
1) "Creuser" un tunnel avec Putty
Créer une nouvelle session que vous appelerez par exemple "tunnel_mail_cesr",
et qui créera un tunnel entre le port local 9025 et le port SMTP (25) du serveur de mail cesr (fw-in.cesr.fr).
Il faudra lancer cette session (et la garder ouverte en tâche de fond) avant d'envoyer un mail
2) Configurer votre client mail Outlook
Menu Outils/Paramètres du compte
Clic sur bouton "Modifier"
Dans le champ "Serveur de courrier sortant (SMTP)", remplacer "mailhost.cesr.fr" par "localhost"
Clic sur bouton "Paramètres supplémentaires...", clic sur onglet "Options avancées"
Dans le champ "Serveur Sortant (SMTP)", remplacer "25" par "9025"
Bien sûr, il faut tout remettre en place quand on revient au cesr (en fait, on pourrait aussi fonctionner en permanence avec le tunnel, même au CESR...)
Synchroniser Outlook 2007 Calendar et Google Calendar