mercredi 17 juin 2015

poor man's dyndns

As many, I committed a low cost dyndns ; 
hourly, I call a server's url. if the server notices a change, it updates a DNS zone : 

root@clic12:/etc/cron.hourly# cat wgk
#!/bin/sh
IP=`ifconfig -a|grep 192|head -n 1|sed -e 's/  */|/g'|cut -d\| -f3`
URL="http://www.yoursite.net/zone.php"
wget -o /dev/null -O /dev/null "$URL" 2>&1 >/dev/null
wget -o /dev/null -O /dev/null "$URL?n=guy&ip=$IP" 2>&1 >/dev/null


and the php side (can manage many dyndnses): 

//print_r($_SERVER);

$n=preg_replace("/[^a-z]/","",$_REQUEST["n"]);
if ($n)
 foreach(explode("\n",file_get_contents("zone.txt")) as $l)
   if (preg_match("/ $n /",$l)) $m=preg_replace("/^.* $n /","",$l);
if ($_REQUEST["a"]) die(file_get_contents("zone.txt"));
if ($_REQUEST["d"])
        die("ok".file_put_contents("zone.txt",strftime("%D %T reset
\n")));
if (!$n) die("list,reset");
$q=strftime("%D %T $n ".$_REQUEST["ip"]." ".$_SERVER["REMOTE_ADDR"]."
");
file_put_contents("zone.txt",$q."\n",FILE_APPEND);
$q=preg_replace("/^.* $n /","",$q);
if ($q == $m) die("ok same ip");
file_put_contents("zone.txt","***********NEWIP*******\n".$q."\n",FILE_APPEND);
if ($n=="guy")
        passthru("sudo /root/scripts/named_dyndns.sh yoursite.net adsl ".$_SERVER["REMOTE_ADDR"]);
?>.

and named_dyndns.sh + domain + subdomain + ip

#!/bin/sh
domain=$1
key=$2
ip=$3
if [ "$ip" = "" ];then echo "$0 domain key ip";exit;fi
dmx=/var/named/chroot//etc/named.xtra
sed -i $dmx -e "s/^$domain:$key IN A .*$/$domain:$key IN A $ip/"
/root/bin/named_make_domxtra2zon.pl $domain

after, this is your own domain/named/zone system, 
that recreates a zonefile and reload named





mercredi 8 avril 2015

half-em and dash in Word : why copy paste command line from MS-WORD with dashes fail

Word evolves , it replaces dash  by typographic characters the picky way. so dashes.
I was copy pasting from word and bang! :
# keytool -list –v -keystore tomcat.jks
Unrecognized command: –v
it is hidden to non hexadecimal reader
[root@h0l1ice11t conf]# echo "keytool -list –v ..."|od -cx
0000000 k e y t o o l   - l i s t   342 200 
      656b 7479 6f6f 206c 6c2d 7369 2074 80e2
0000020 223 v  
      7693 
fiiiix it …..
* in word, deactivate any automatism
menu file / option / verification / option auto-correction ….
uncheck outrageously
* and now replace – by – [sic]
there is an option to type "half-em-dash"
the option : “Plus>>” “special” “half-em-dash"
conclusion : use MD (markdown), not MS

please prefix variable

def gdflib_stinsta(param,action)
  execute "actioninstanceparamappli" do
  action :run
  command "ls"
end
Function was a bit longer. here the bug if the use of the word "action" as a parameter for the function. It confuses with the langage (it is a 'chef' keyword
The problem I dislike in Ruby, as in python C Java and others, haskell, caml, is that the langage didn't require any prefix to variables. Perl and PHP require a $ (or @ or %). Ruby a bit too but not enough.
I says it's Bad.I don't understand how in a new langage you remixed variables (data) and langage (program). At a time where view, model, controller, data, events are distinct things. Even if data and functions are as variables in FP. 
Ok, this case it is a mix in scopes of local and (bah_ )"global" variables from chef, that should have generated a warning.
Anyway

LD_LIBRARY_PATH annoyances

Hey, we don't need no ld_library_path ?
though I did  code an élégant script :
#reorder front path items matching ie(PATH,/opt:/usr:/sbin:/bin) R_PATH
reorderpath()
{
A_PATH=$1
P_BEFORES=$2
A_PATH=`echo "$A_PATH"|sed -e 's/::/:/g' -e 's/^://' -e 's/:$//'`
if [ "$A_PATH" = "" ];then return;fi
if [ "$P_BEFORES" = "" ];then return;fi
for P_BEFORE in `echo $P_BEFORES|sed -e 's/:/ /g'`;do
R_PATH=""
for I_PATH in `echo $A_PATH|sed -e 's/:/ /g'`;do
J_PATH=`echo $I_PATH|sed -e "s:^$P_BEFORE::"`
if [ "$I_PATH" = "$J_PATH" ];then
R_PATH="$R_PATH:$I_PATH"
else
R_PATH="$I_PATH:$R_PATH"
fi
done
R_PATH=`echo "$R_PATH"|sed -e 's/::/:/g' -e 's/^://' -e 's/:$//'`
A_PATH=$R_PATH
done
}

but on AIX, impossible to conciliate chef-solo and rpm
reorderpath $LD_LIBRARY_PATH /usr:/lib:/opt/freeware
puts rpm in front, rpm works, but not chef-solo who uses libs (zlib) in /lib instead of /opt/chef/embedded ;
same way round, rpm needs  libs zlib from /lib ;
and as rpm is started by chef, they should share the same LD_LIBRARY_PATH.
no solution, well indeed :
solution lies in compiled files , they have hardcoded the location of the lib
  1. Never ever set LD_LIBRARY_PATH globally.
  2. If you must ship binaries that use shared libraries and want to allow your clients to install the program outside a ‘standard’ location, do one of the following:
    • Ship your binaries as .o files, and as part of the install process relink them with the correct installation library path. (like oracle..)
    • Ship executables with a very long “dummy” run-time library path, and as part of the install process use a binary editor to substitute the correct install library path in the executable. (whaou, hacky!+1!)
  3. If you are forced to set LD_LIBRARY_PATH, do so only as part of a wrapper.

so (redhat/solaris/aix):
unset LD_LIBRARY_PATH LD_RUN_PATH LIBPATH
and everything works..
PS: my company re-opened blogger in the firewall, so I am back, 
I'll put english articles here, french here blog.kastenbaum.net

vendredi 8 novembre 2013

MaxClients, Max BusyWorkers


"Quand on arrête un noeud sur les trois, 
on a le nombre de sessions des autres noeuds qui passe de 800 à 2000, 
au lieu de 800+400=1200, pourquoi ?"




 apache reçoit R requêtes par secondes (ici : 1600)

une requête met un temps moyen T pour s'exécuter (ici: 500ms)


on a donc besoin de RT temps de process,
il y aura W=RT workers occupés pendant une seconde,

ici 1600*0.5=800 workers ,
ici, un worker peut exécuter deux requêtes pendant sa seconde de process.

coté backend on voit 800 workers, donc 800 sessions.




ça c'est quand tout va bien.




Mais quand il y a de la charge, on suppose que le temps moyen de traitement s'allonge,

soit à cause d'apache soit à cause du backend ,
quand il est supérieur à une seconde, T>1 RT=W>R, il y a plus de workers que de requêtes ;
il n'est donc pas incohérent d'autoriser un plus grand nombre de maxworkers que maxclients
pourvu que le backend arrive à suivre (et le système, mémoire, sockets etc aussi)

c'est peut être pour ça qu'on voit lors d'arrêt d'un noeud le nombre de sessions augmenter,
il ne s'agit peut être pas de sessions web (R), mais de sessions du backend (W),  (*à vérifier*)
au lieu d'avoir nos 3*800/2=2400/2=1200 sessions on en voit 2000
ce qui signifierait  une augmentation de 2000/1200=+66% du temps moyen T

  Bon, le raisonnement se tient, mais reste à voir si ça colle bien à la réalité.

lundi 14 octobre 2013

stty: standard input: Inappropriate ioctl for device


"stty: standard input: Inappropriate ioctl for device"
est un message systeme sur les redhat 6,
du (dans mon cas) à des combinaisons de su et &
j'ai réduit le test au minimum :

echo "su  root -c 'ls &' "  >  /tmp/a ; sh /tmp/a

modif : dans /etc/sudoers,
changer
Defaults    requiretty
par
Defaults    !requiretty
(ou par utilisateur..)

PGP on linux 64bits x86_64

Compilation de PGP sur linux 64bits

http://www.pgpi.org


English Reader summary : 
I tried to compile pgp for 64bits architecture,  => ok for v5 but not v6 (v6 with -m32 is ok), 
in both versions there are many fixes from the last century


PGP, le mal aimé, l'oublié, distancé par gpg opengpg gnupg etc
Du coup recompiler ce code du XXeme siècle n'a pas été joyeux,
surtout parce qu'en voyant les corrections, on voit l'esprit d'abandon et de laisser aller,
"pff, ces jeunes, ils changent tout tout le temps, ça marchait bien avant"
pgp est fait pour le 32 bits. (avec option 16bits?),

pgp658 fait trop d'erreurs ? essayons pgp50i-unix-src.tar.gz , le simplifié :
wha ! il reste des fautes de frappe dans le code !?!
comme si le code avait été abandonné du jour au lendemain.


PGP 5.0.i  : 3 fixes :

#* mauvais test sur la soixantequatrebitabilité (todo : better testing):
sed -i lib/pgp/include/pgpUsuals.h 's/ifndef HAVE64/ifndef DONTDOTHAT___HAVE64/'

#* pas de ';' dans les defines merci :
sed -i lib/pgp/keys/pgpRngRead.c 's/defined(WRAP_SUB);/defined(WRAP_SUB)/'

*relisez vous, manque un '\' dans le texte de licence :
sed -i apps/common/pgpFullLicense.c 's/Software Product\. $/Software Product.\\/'
(c'est peut être une astuce pour le relire?)

./configure --prefix=/somewhere ; make ;make install

Mais, la version 50i est très différente de la version 6, 
les options de ligne de commande ont rien à voir,
donc faut quand même faire la V6



PGP 6.5.8 , pgpsrc658unix.tar.gz : fixes

#* juste tenir compte de 64 bits
for f in `find . -name "config.sub"`;do
 sed \
  -e 's/i.3456.86 /i[3456]86 | x86_64 /' \
  -e 's/i.3456.86-\* /i[3456]86-* | x86_64-* /' \
  -i $f
done

#* correction de cast
sed -i libs/pfl/common/file/pgpStdFileIO.c -e 's/fpos_t/PGPFileOffset/g'

#* C++ est devenu plus formel, faut ajouter template <>
sed -i libs/pfl//common/classes/StPGPRefs.h \
 -e '/inline void .*::/ s/inline/template <> inline/'
sed -i ./libs/pgpcdk/priv/networklib/keyserver/CHTTPKeyServer.cpp \
 -e '/inline void .*::/ s/inline/template <> inline/'

#* correction de cast, ajout (char *) (car const char *)
sed -i ./libs/pgpcdk/priv/networklib/keyserver/CHTTPKeyServer.cpp \
 -e 's/p = strchr(kBase64Table, /p = (char *)strchr(kBase64Table, /'
sed -i ./libs/pgpcdk/priv/networklib/keyserver/CHTTPPGPKeyServer.cpp \
 -e 's/currentItem = strstr(inResult, "/currentItem = (char *)strstr(inResult, "/'

#* "writable-strings" : ça sent l'option bidouille de compil qui n'est plus admise
for f in `grep -rsl "fwritable-strings" *`;do
 sed -e 's/-fwritable-strings//' -i $f
done

#* les '?' dans un define font des trucs bizarres
sed -i ./libs/pgpcdk/pub/include/pgpUtilities.h \
    -e '/kPGPMacFileCreator_DecryptedBinary/ s/Binary.*$/Binary \"????\"/'

#* manque include malloc ?!
sed -i libs/pgpcdk/unix/ui/PGPKeyServerDialogs.cpp \
 -e 's/#include /#include \n#include /'

#* erreur dans le proto
sed -i clients/pgp/cmdline/prototypes.h \
 -e 's/^int cryptRandWriteFile/static int cryptRandWriteFile/' \
 -e 's/^int maintUpdate/static int maintUpdate/'

#* cast à l'envers
sed -i clients/pgp/cmdline/keymaint.c \
 -e 's/(PGPUInt32)traceValue = depth/traceValue = depth/'

#* no asm, on désactive l'assembleur pour la compil en 32 bits sur une archi 64 (galère)
for f in `grep -rsl "__asm__" *`;do
 sed -e 's/__GNUC__/__NOASM_EVENIFGNUC__/' -i $f
done

pour la compil, il faudra utiliser ldap.h fourni dans libs/network/ldaplib/include
et non pas celui du systeme

cd libs/pfl ;./configure ;make   #(ou configure --prefix=.... bref)
cd ../pgpcdk;./configure ; make headers ; make 
cd ../../clients/pgp/shared ; ./configure ; make ;
cd ../cmdline ; ./configure ; make 

en 64 bits ça compile mais ça affiche des erreurs à l'exécution :
je vais peut être laisser tomber moi aussi.
.... 3 jours après ... je laisse tomber le soixantequatrebitage,
compilation avec -m32 dans cppflags et ldflags
et les libs 32 bits :
glibc-2.12-1.47.el6.i686.rpm  libstdc++-4.4.6-3.el6.i686.rpm
libgcc-4.4.6-3.el6.i686.rpm   nss-softokn-freebl-3.12.9-11.el6.i686.rpm


mais toutes les modifs sont quand même conservées
pour pouvoir recompiler pgp avec les librairies récentes

cela génère un exécutable qui marche, mais qui s'autocritique par des assertions :
ASSERTION FAILED at pgpMemoryMgr.c line 423:
  PGPFreeData(): mgr being freed with outstanding allocations:
  (mgr->numAllocations == 0) not true
ou encore
ASSERTION FAILED at pflPrefs.c line 333:
  (( (err) == kPGPError_NoErr ) || err == kPGPError_UserAbort) not true



mardi 30 avril 2013

fiddler debugging

tout commence avec le genre de bug impossible :
un appel d'une page sur IE génère une alerte "mixed content" c'est à dire
"cette page contient des éléments sécurisés et des éléments non sécurisés"
uniquement sur IE (sur FF et GC c'est ok)
On analyse les requêtes avec IE developper toolbar, et on voit pas de http, tout est bien en https.
Mystère.
Et pour corser le tout ça n'arrive qu'en prod et on n'a pas la main sur les serveurs pour modifier le source pour des tests. Il y a une centaine de fichiers appelés (png css js etc).
Bon, IE toolbar n'est pas assez évolué, j'utilise enfin fiddler2 :
- ça permet de voir sur quel fichier ça bloque , mais bon là on trouve pas, c'est dans du javascript
- en utilisant le remplacement d'url + regexp on peut changer tous les chargements de *.png en blank, ou *.gif *.js *.css etc
- avec le plugin http://fiddlerurlreplace.codeplex.com/ bulk replace on peut éliminer plein de fichiers, et arriver à une erreur avec uniquement 3 fichiers.
- ensuite, on peut dans fiddler modifier les contenus, ce qui permet de modifier le javascript chargé pour affiner encore d'où vient l'erreur. menu "custom rules" , on peut éditer la fonction OnBeforeResponse :
ici par exemple je remplace url('xxx') en url('https://zzz/xxx')

static function OnBeforeResponse(oSession: Session)
{
if (oSession.oResponse.headers.ExistsAndContains("Content-Type", "javascript")) { //filtrage eventuel
  oSession.utilDecodeResponse();
  oBody = oBody.replace(/"url\(\\"\/" \+ getZZAppName/gi,
                 '"url(\\"" + window.location.protocol + "://" + '+'window.location.host + '+
                 '((window.location.port)?":"+window.location.port:"") + "/" + '+'getZZAppName');
  oSession.utilSetResponseBody('oBody');
 }

le bug IE provenait de
http://support.microsoft.com/kb/925014
http://www.pelagodesign.com/blog/2007/10/30/ie7-removechild-and-ssl/


jeudi 11 avril 2013

STRACE OPENED WRITE FILE SED ANALYZER

Même bug depuis une grosse semaine :
un jboss tourne vite sur une vm centos et un physique debian
mais est lent sur une vm redhat 6, une vm redhat 5, un physique centos ;
ça tourne sur un processeur
la partie lecture d'un xml de 100M et fabrication des données de 1M dure 5 sec. ok
ensuite le templating et renvoi de ce html dure 10 secondes dans un cas et 2 minutes dans l'autres.
la question à résoudre est
mais qu'est ce qui écrit comme un malade dans le disque ?
faut voir avec strace (ok je verrai dtrace plus tard)


strace -tt -T -f -s 80  -trace=open,close,read,write -o stf.log

cat stf.log|
sed -e '/write/!d' -e 's/^................... //' |\
sed -e "/unfinish/ N;s/\n//p"|\
sed -e 's/,.* = /,=/' -e 's/ <[0-9\.]*>//' -e'/resumed/d' \
> stfw.log
egrep "( open\(| open resum)" stf.log|\
sed -e 's/^................... //' |\
sed -e 's/^open("//' |\
sed -e '/unfinished/ N;s/\n//'|\
sed -e's/".* = / = /' \
-e '/ENOENT/d' -e 's/<[0-9\.]*>//' > stfop.log
cat stfw.log|sed -e 's/,.*$//' -e 's/^.*write(//' -e's/[^0-9]//g'|sort -u > stfu.log
echo "" > stfc.log
for i in `cat stfu.log`;do grep -c "($i," stfw.log >> stfc.log; echo " : $i" >> stfc.log;done
cat stfc.log | sed -e '/:/!N;s/\n//p' |sed -e '/:/! d' | sort -run |head -n 5 > stft.log
for f in `cat stft.log|sed -e's/^.* : //'` ;do grep " = $f" stfop.log >> stfg.log;done
more stfg.log

il faudrait le réécrire en réel scanneur, parce que les mêmes numéros sont réalloués, et plusieurs processes différents peuvent avoir les mêmes numéros.

vendredi 8 février 2013

désaccentuation


J'oubliais, ce petit script pour "désaccentuer" du texte : utiliser entity_decode,
puisque é s'écrit &+e+acute; on peut récupérer le 'e' après le & :
function f_desaccentuation($v_str)

{
        //htmlentities pour les accents !: référence devient reference
        $str=f_str2utf8($v_str);
        $str=f_str2iso(html_entity_decode($str,ENT_NOQUOTES,"UTF-8"));
        $str=preg_replace("/[\xa0-\xbf\xd7\xf7]/"," ",$str);
        $str=htmlentities(f_str2utf8($str),ENT_NOQUOTES,"UTF-8");
        $str=str_replace(" "," ",$str);
        $str=str_replace("<","<",$str);
        $str=str_replace(">",">",$str);
        $str=str_replace("&","&",$str);
        $str=str_replace(""",'"',$str);
        $str=str_replace("'","'",$str);
        return(preg_replace("/\&(.)[^\;]*\;/","$1",$str));
}
pas de table de conversion :-)

mysql replication repairing script

Ah je ne vous ai pas montré le script pour réparer ma réplication mysql  :
à lancer sur le backup qui a foiré.
* copie fichier de la base à froid
* on trouve à quel redo/pos on peut reprendre (c'est là l'astuce)
* après y a plus qu'à refaire la conf de réplication


#####my_repl_bk2rp.sh

#!/bin/sh
echo "quand la repl. foire, faire repartir de zero"
echo "copie le bk vers la replication, ok?"
read "ok"

/etc/init.d/mysqld stop

#merci à www.rsnapshot.org génial
rsync -e ssh -va --delete serveurdesauvegarde:/backup/hourly.0/mysql /home/
#replay, just to be sure...
rsync -e ssh -va --delete serveurdesauvegarde:/backup/hourly.0/mysql /home/

/etc/init.d/mysqld start

cd /repertoire/mysql

lastredo=$(tail -n 1 redo*.index|sed -e 's:^.*/::')

lastredopos=$(mysqlbinlog $lastredo|grep end_log_pos|tail -n 1|sed -e 's/^.*end_log_pos *//' -e 's/ .*$//')

mysql -pmotdepasseenclair <
CHANGE MASTER TO \
MASTER_HOST='masterserver', \
MASTER_USER='slave', \
MASTER_PASSWORD='passduuserslave', \
MASTER_LOG_FILE='$lastredo', \
MASTER_LOG_POS=$lastredopos;
START SLAVE;
EOT

tail /var/log/mysqld.log
sleep 1
echo "my_repl_check.sh"
mysql -u root -pmotdepasse <

show slave hosts \G;
show slave status \G;
show master status \G;
EOT


et ça marche !!
quand on perd la réplication, on galère pour retrouver comment on fait pour la rebrancher,
surtout avec le stress, t le risque de perdre encore plus. pff. chouette script, merci moi-même.


vendredi 1 février 2013

pass bash arguments with quotes in $@

Très énervant, c'est en grande partie due à l'habitude de lire des jurons du capitaine Haddock
'"$@"' ${a[0]} $*!=$@ [tonnerre][brest]
Je veux juste faire un petit shell sympathique pour en encapsuler un autre moins sympa mais plus utile.
genre :
guy.sh coucou

guy.sh contient :
/$JBPTH/jboss-cli.sh -c -u usr -p pw -w=80 $*

(sh bash ksh ouais bon pareil)

alors, ça marche bien jusqu'à ce qu'on essaie :
guy.sh --command="ls server"
ah purée c'est pas prévu du tout

#on peut récupérer les arguments $@ dans un tableau :

argc=0;for v;do argc=`expr $argc + 1`;argv[$argc]=$v;done
#pour l'afficher
for i in `seq $argc` ;do echo ${argv[$i]};done


joli. Mis à part que 'seq' n'existe pas sur Solaris (. et on perd quand même les guillemets ...

donc en cherchant comment fait redhat java jboss et tout ça dans leur propres wrappers (scripts sandwichs)
on se dit  '"$@"' !!!  :

eval /$JBPTH/jboss-cli.sh -c -u usr -p pw -w=80 '"$@"'