From: Greg Burri Date: Sun, 5 Oct 2008 19:00:05 +0000 (+0000) Subject: FIX #81 (partie d'update de la BD, voir euphorik_bd_admin:patch(2)) X-Git-Tag: 1.1.3~11 X-Git-Url: https://git.euphorik.ch/?a=commitdiff_plain;h=6e20d759c95708c74084dc82dadab2167ed8ef80;p=euphorik.git FIX #81 (partie d'update de la BD, voir euphorik_bd_admin:patch(2)) MOD amélioration de la mise en pre prod : copie de la BD de prod --- diff --git a/modules/erl/euphorik_bd_admin.erl b/modules/erl/euphorik_bd_admin.erl index a5a69f1..66427d3 100644 --- a/modules/erl/euphorik_bd_admin.erl +++ b/modules/erl/euphorik_bd_admin.erl @@ -34,8 +34,9 @@ reset/0, update/0, - backup_text/1, - restore_text/1, + backup/1, + restore/1, + change_node_name/4, toggle_ek_master/1, print_users/0, @@ -110,6 +111,16 @@ create_tables() -> % mis à part car lors de la reprise de données avec load_textfile les indexes ne sont pas recréés creer_indexes() -> + % commence par supprimer les anciens indexes + lists:foreach(fun(T) -> + lists:foreach(fun(P) -> + mnesia:del_table_index(T, P) + end, + mnesia:table_info(T, index) + ) + end, + ?TABLES + ), mnesia:add_table_index(minichat, auteur_id), mnesia:add_table_index(reponse_minichat, cible), mnesia:add_table_index(user, cookie), @@ -209,11 +220,9 @@ update(Version) -> patch(1) -> % Prend un chemin vers la feuille de style de type "css/1/euphorik.css" % et renvoie "styles/1/euphorik.css" - Transforme_css = fun(F) -> - case F of - "css" ++ Reste -> "styles" ++ Reste; - _ -> F - end + Transforme_css = fun("css" ++ Reste) -> + "styles" ++ Reste; + (F) -> F end, Traiter_message = fun(M, Racine) -> F = fun(F, M2) -> % seul moyen à ma connaissance pour faire de la récursion dans une lambda fonction, voir : http://www.nabble.com/Auto-generated-functions-td15279499.html @@ -239,16 +248,14 @@ patch(1) -> fun({user, Id, Cookie, Pseudo, Login, Password, Email, Date_creation, Date_derniere_connexion, Css, Nick_format, View_times, View_tooltips, Indice_flood, _Page_principale, Conversations, Ek_master, Last_ip}) -> {user, Id, Cookie, Login, Password, {profile, Pseudo, Email, Transforme_css(Css), Nick_format, View_times, View_tooltips, light, reverse, lists:map(fun({R, _}) -> {R, false} end, Conversations)}, Date_creation, Date_derniere_connexion, Indice_flood, Ek_master, Last_ip} end, - record_info(fields, user), - user + record_info(fields, user) ), mnesia:transform_table( minichat, fun({minichat, Id, Auteur_id, Date, Pseudo, Contenu, Troll_id}) -> {minichat, Id, Auteur_id, Date, Pseudo, Contenu, Troll_id, Id} end, - record_info(fields, minichat), - minichat + record_info(fields, minichat) ), case mnesia:transaction( fun() -> @@ -262,60 +269,110 @@ patch(1) -> {atomic, _} -> ok end; % 2 -> 3 -patch(2) -> +patch(2) -> + % première étape : changer le type de la table minichat de set à ordered_set + % TODO : trouver un meilleur moyen que de passer par un backup + backup("tmp"), + create(), + restore("tmp"), + file:delete(dossier_backups() ++ "tmp"), mnesia:transform_table( troll, fun({troll, Id_troll, Id_user, Date_create, Date_post, Content}) -> % recherche le message associé s'il existe - Id_minichat = case mnesia:index_read(minichat, Id_troll, 7) of - [#minichat{id = Id}] -> Id; + Id_minichat = case e(q([M || M <- mnesia:table(minichat), element(7, M) =:= Id_troll]), [{tmpdir, ?KEY_SORT_TEMP_DIR}]) of + [M] -> element(2, M); _ -> undefined end, {troll, Id_troll, Id_user, Id_minichat, Date_create, Date_post, Content} end, - record_info(fields, troll), - user + record_info(fields, troll) ), - mnesia:del_table_index(minichat, troll_id), + %mnesia:del_table_index(minichat, troll_id), mnesia:transform_table( minichat, fun({minichat, Id, Auteur_id, Date, Pseudo, Contenu, _Troll_id, Racine_id}) -> {minichat, Id, Auteur_id, Date, Pseudo, Contenu, Racine_id} end, - record_info(fields, troll), - user - ), + record_info(fields, minichat) + ), creer_indexes(). % uniquement pour l'indice sur id_minichat de la table troll - -% crée un backup dont le nom est fournit dans le repertoire backups qui se trouve dans le repertoire de la BD. -%backup(Nom) -> -% mnesia:backup(mnesia:system_info(directory) ++ "/backups/" ++ Nom). - -% Reviens à une version précédente de la base de données -% (les données insérées durant les versions plus récentes sont perdues) -%restore(N) -> -% mnesia:restore(fichier_backup(N), [{default_op, recreate_tables}]). +% Renvoie le dossier dans lequel les backups sont effectué, ce dossier doit être en écriture. +dossier_backups() -> + mnesia:system_info(directory) ++ "/backups/". % Renvoie le fichier (avec le chemin) correspondant à la version Version, par exemple : "/var/euphorik/BD/backups/backup1" -fichier_backup(Version) -> - mnesia:system_info(directory) ++ "/backups/" ++ if is_integer(Version) -> "backup" ++ integer_to_list(Version); true -> Version end. +fichier_backup(Version) when is_integer(Version) -> + dossier_backups() ++ "backup" ++ integer_to_list(Version). + +% crée un backup dont le nom est fournit dans le repertoire backups qui se trouve dans le repertoire de la BD. +backup(Fichier) -> + mnesia:backup(dossier_backups() ++ Fichier). + + +% Restaure un backup de la BD. +restore(Fichier) when is_list(Fichier) -> + mnesia:restore(dossier_backups() ++ Fichier, []); +% Reviens à une version précédente de la base de données. +% (les données insérées durant les versions plus récentes sont perdues). +restore(Version) when is_integer(Version) -> + mnesia:restore(fichier_backup(Version), []). % [{default_op, recreate_tables}]). + -backup_text(_) -> todo. -restore_text(File) -> - mnesia:stop(), - mnesia:delete_schema([node()]), - mnesia:start(), - case mnesia:load_textfile(File) of - {atomic, ok} -> - update(), - creer_indexes(); - Erreur -> - Erreur - end. +% Change le nom du noeud d'un backup. +% provient d'ici : http://www.erlang.org/doc/apps/mnesia/Mnesia_chap7.html#6.9 +% From : l'ancien nom +% To : le nouveau nom +% Source : le nom du fichier de backup +% Target : le nom du fichier du nouveau backup +change_node_name(From, To, Source, Target) -> + Switch = + fun(Node) when Node == From -> To; + (Node) when Node == To -> throw({error, already_exists}); + (Node) -> Node + end, + Convert = + fun({schema, db_nodes, Nodes}, Acc) -> + {[{schema, db_nodes, lists:map(Switch,Nodes)}], Acc}; + ({schema, version, Version}, Acc) -> + {[{schema, version, Version}], Acc}; + ({schema, cookie, Cookie}, Acc) -> + {[{schema, cookie, Cookie}], Acc}; + ({schema, Tab, CreateList}, Acc) -> + Keys = [ram_copies, disc_copies, disc_only_copies], + OptSwitch = + fun({Key, Val}) -> + case lists:member(Key, Keys) of + true -> {Key, lists:map(Switch, Val)}; + false-> {Key, Val} + end + end, + {[{schema, Tab, lists:map(OptSwitch, CreateList)}], Acc}; + (Other, Acc) -> + {[Other], Acc} + end, + mnesia:traverse_backup(Source, Target, Convert, switched). + + +% Obsolète +%~ backup_text(File) -> + %~ mnesia:dump_to_textfile(File). +%~ restore_text(File) -> + %~ mnesia:stop(), + %~ mnesia:delete_schema([node()]), + %~ mnesia:start(), + %~ create_tables(), + %~ case mnesia:load_textfile(File) of + %~ {atomic, ok} -> + %~ update(), + %~ creer_indexes(); + %~ Erreur -> + %~ Erreur + %~ end. toggle_ek_master(User_id) -> diff --git a/modules/include/euphorik_bd.hrl b/modules/include/euphorik_bd.hrl index dbca45b..0b04c4b 100755 --- a/modules/include/euphorik_bd.hrl +++ b/modules/include/euphorik_bd.hrl @@ -83,8 +83,6 @@ }). - - -record(user, { id, diff --git a/pages/about.html b/pages/about.html index 1105acf..256159b 100644 --- a/pages/about.html +++ b/pages/about.html @@ -1,7 +1,7 @@

euphorik.ch

-

Version : 1.1.2

+

Version : 1.1.3

Auteur : GBurri

FAQ

diff --git a/tools/mise_en_prod.erl b/tools/mise_en_prod.erl index 2b9cb17..933aceb 100755 --- a/tools/mise_en_prod.erl +++ b/tools/mise_en_prod.erl @@ -5,13 +5,39 @@ % Recharge les modules de euphorik et met à jour la BD. % TODO : construire le nom du noeud en fonction du nom de l'host -main(_) -> +hote() -> + '@overnux'. + +% le premier argument est le nom du noeud est peut valoir : +% - yaws : noeud de production +% - yaws_dev : noeud de pre-production +main([Nom_node]) when Nom_node =:= "yaws"; Nom_node =:= "yaws_dev" -> + Node = list_to_atom(Nom_node ++ atom_to_list(hote())), net_kernel:start([flynux, shortnames]), io:format("rechargement des modules..~n"), - _Pid = spawn_link(yaws@overnux, euphorik_daemon, reload_euphorik, []), - receive - {'EXIT', _, _} -> - io:format("mise à jour de la BD..~n"), - spawn(yaws@overnux, euphorik_bd_admin, update, []) - end. + rpc:call(Node, euphorik_daemon, reload_euphorik, []), + if Nom_node =:= "yaws_dev" -> copier_bd(Node); + true -> true + end, + io:format("mise à jour de la BD..~n"), + rpc:call(Node, euphorik_bd_admin, update, []); +main(_) -> + io:format("Usage : mise_en_prod.erl "), + halt(1). +% Copie la bd du noeud de production +copier_bd(Node) -> + io:format("Copie de la BD de production vers le noeude pre-production~n"), + Fichier = "/tmp/backup_ek_tmp", + Fichier2 = "/tmp/backup_ek_tmp2", + rpc:call(yaws@overnux, mnesia, backup, [Fichier]), + rpc:call(Node, euphorik_bd_admin, change_node_name, [yaws@overnux, yaws_dev@overnux, Fichier, Fichier2]), + rpc:call(Node, mnesia, restore, [Fichier2, [{default_op, recreate_tables}]]), + rpc:call(yaws@overnux, file, delete, [Fichier]), + rpc:call(Node, file, delete, [Fichier2]). + + + + + + diff --git a/tools/start_yaws.sh b/tools/start_yaws.sh index 29be884..3ec2e4f 100755 --- a/tools/start_yaws.sh +++ b/tools/start_yaws.sh @@ -1,4 +1,5 @@ #!/bin/bash +# coding: utf-8 # screen est utilisé par exemple pour lancé une version de preproduction et permettre de la faire tourner après un délog #screen -S yawspreprod yaws --conf ./yaws.conf --sname yaws_dev --mnesiadir "../BD/" -I debian_yaws_dev diff --git a/tools/tools.rb b/tools/tools.rb index e2ed153..d9f6547 100644 --- a/tools/tools.rb +++ b/tools/tools.rb @@ -117,14 +117,14 @@ class MiseEnProd # Effectue la mise en production. def miseEnProd copierFichiers() - maj() + maj('yaws') end # Effectue la mise en préproduction. def miseEnPreProd copierFichiers() - copierBD() lancerYaws() + maj('yaws_dev') end def copierFichiers @@ -136,14 +136,11 @@ class MiseEnProd set_droits_fichiers() end - # TODO - def copierBD - end - def lancerYaws creer_rep("tools") system("rsync tools/yaws.conf #{@uri}:#{@rep}/tools") system("rsync tools/start_yaws.sh #{@uri}:#{@rep}/tools") + system("ssh #{@uri} \"cd #{@rep}/tools; screen -d -m -S yaws_dev ./start_yaws.sh\"") end def exec(commande) @@ -158,6 +155,7 @@ class MiseEnProd end def compiler_partie_serveuse + log "compilation des modules serveur" Dir.chdir('modules') system("make") if $?.exitstatus != 0 @@ -167,7 +165,8 @@ class MiseEnProd Dir.chdir('..') end - def creer_repertoire_bd + def creer_repertoire_bd + log "création du répertoire de la base de données" # création du repertoire BD creer_rep('BD') creer_rep('BD/backups') @@ -176,6 +175,7 @@ class MiseEnProd # css, images, html, etc.. def copier_partie_statique + log "copie de la partie statique" uri = "#{@uri}:#{@rep}" system("awk '$0 !~ /prod=\"delete\"/' index.yaws | ssh #{@uri} \" cat > #{@rep}/index.yaws\"") system("rsync favicon.ico #{uri}") @@ -186,6 +186,7 @@ class MiseEnProd # minification et package des fichiers js dans euphorik.js def pack_js + log "minification, assemblage et copie du javascript" rep_js = 'js' creer_rep(rep_js) # jquery.js et euphorik.js doivent se trouve en premier @@ -215,6 +216,7 @@ class MiseEnProd end def copie_modules_serveurs + log "copie des modules du serveur" # copie des modules erlang creer_rep('modules') system("rsync -r --exclude 'euphorik_test.beam' modules/ebin #{@uri}:#{@rep}/modules") @@ -222,14 +224,24 @@ class MiseEnProd end def set_droits_fichiers + log "attribution des droits sur les fichiers" # attribution des droits exec("chmod -R g+rx .") end - def maj + # noeud : le nom du noeud sur lequel le script de mise en prod est exécuté + # Execute le script 'mise_en_prod.erl' sur le serveur afin de : + # - Recharger les modules + # - Mettre à jour la base de données + def maj(noeud) + log "rechargement des modules serveur et mise à jour de la base de données" # execution du script de mise à jour system("cat tools/mise_en_prod.erl | ssh #{@uri} \"cat > /tmp/mise_en_prod.erl\"") - system("ssh #{@uri} \"chmod u+x /tmp/mise_en_prod.erl; /tmp/mise_en_prod.erl; rm /tmp/mise_en_prod.erl\"") + system("ssh #{@uri} \"chmod u+x /tmp/mise_en_prod.erl; /tmp/mise_en_prod.erl #{noeud}; rm /tmp/mise_en_prod.erl\"") + end + + def log(message) + puts "----- #{message} -----" end end @@ -262,18 +274,7 @@ class Commande @verifJS.verifier() when 'version' @version.maj() - end - -=begin - Net::SSH.start('euphorik.ch', 'gburri') {|ssh| - output = ssh.exec!("hostname") - stdout = "" - ssh.exec!("ls -l /tmp"){|channel, stream, data| - stdout << data if stream == :stdout - } - puts stdout - } -=end + end end def afficherUsage