The current situation: I have two servers at online.net. I have to transfer all the datas from one server to another.
Let's rsync all that.
Aller au contenu | Aller au menu | Aller à la recherche
{ 4 décembre 2013 }
mercredi, décembre 4 2013, 09:52 ::
The current situation: I have two servers at online.net. I have to transfer all the datas from one server to another.
Let's rsync all that.
{ 21 août 2011 }
dimanche, août 21 2011, 13:31 :: Coding
For debugging purposes, it's sometimes usefull to print the queries executed by a Symfony2 Command. Here is my tiny piece of code to do it.
protected function execute(InputInterface $input, OutputInterface $output) { // your code here // printing sql queries $logger = $this->getContainer()->get('monolog.logger.doctrine'); foreach ($logger->getLogs() as $log) { $output->writeln(sprintf('Query: %s', $log['message'])); } }
{ 20 mai 2011 }
vendredi, mai 20 2011, 22:02 :: Info
Since few kernels, vmware won't compile, or at least the vmnet driver won't compile.
CC [M] /tmp/vmware-root/modules/vmnet-only/driver.o /tmp/vmware-root/modules/vmnet-only/driver.c: In function ‘VNetFileOpUnlockedIoctl’: /tmp/vmware-root/modules/vmnet-only/driver.c:1137: error: implicit declaration of function ‘lock_kernel’ /tmp/vmware-root/modules/vmnet-only/driver.c:1139: error: implicit declaration of function ‘unlock_kernel’ make[4]: *** [/tmp/vmware-root/modules/vmnet-only/driver.o] Erreur 1 make[3]: *** [_module_/tmp/vmware-root/modules/vmnet-only] Erreur 2 make[2]: *** [sub-make] Erreur 2 make[1]: *** [all] Erreur 2 make[1]: quittant le répertoire « /usr/src/linux-headers-2.6.38-2-686-bigmem » make: *** [vmnet.ko] Erreur 2 make: quittant le répertoire « /tmp/vmware-root/modules/vmnet-only »
Fortunately, there is a patch for this !
diff -u vmnet-only//driver.c /usr/lib/vmware/modules/source/vmnet-only//driver.c --- vmnet-only//driver.c 2011-03-26 01:37:29.000000000 -0400 +++ /usr/lib/vmware/modules/source/vmnet-only//driver.c 2011-05-05 10:36:11.918545812 -0400 @@ -264,11 +264,11 @@ struct file * filp) // IN: { int ret = -ENOTTY; - lock_kernel(); + lock_flocks(); if (filp && filp->f_op && filp->f_op->ioctl == VNetFileOpIoctl) { ret = VNetFileOpIoctl(filp->f_dentry->d_inode, filp, iocmd, ioarg); } - unlock_kernel(); + unlock_flocks(); return ret; } @@ -1134,9 +1134,9 @@ if (filp && filp->f_dentry) { inode = filp->f_dentry->d_inode; } - lock_kernel(); + lock_flocks(); err = VNetFileOpIoctl(inode, filp, iocmd, ioarg); - unlock_kernel(); + unlock_flocks(); return err; } #endif
Patch found on http://communities.vmware.com/message/1749211#1749211.
Here is the archive to extract in /usr/lib/vmware/modules/source
. bunzip2
the file, it's final name must be vmnet.tar (do not extract the data from the tar file)
{ 7 mai 2011 }
samedi, mai 7 2011, 14:06 :: Coding
Recently I created a quite sensible application using symfony 1.4. As many people, I chose sfDoctrineGuardPlugin as authentication/password recovery/account managing system. But even with this piece of software, you are still vulnerable to bruteforce attacks.
I though of hacking sfDoctrineGuardPlugin's code to create some rules and attack detections. But those systems are quite tricky to create and calibrate. It must not be too aggressive nor too permissive. I wanted something that can bail out someone after $some tries in a $certain time. That implied that I would have to record every try with the current time, and calculate a ratio within which a user can login or not. I seemed simple, then it got too complicated.
{ 26 février 2011 }
samedi, février 26 2011, 11:04 :: Info
Mon exemple se compose d'une machine Dedibox Pro R210. Il s'agit d'une machine avec un octo-proc Xeon L3426 à 1.87GHz. Ne vous laissez pas avoir par « si peu » de GigaHertz, ces machines n'ont rien à voir avec des processeurs milieu de gamme type i5/i7. Elle comporte 16Go de ram DDR ECC. Cette machine est sous debian squeeze (stable actuelle).
Ma configuration réseau est ainsi :
J'ai une adresse IP failover que j'ai assigné à mon serveur :
La configuration réseau dépend de votre réseau. Par exemple, si votre ip est 88.190.23.55, la gateway doit donc être 88.190.23.1.
user@dom0$ sudo ifconfig eth0 Link encap:Ethernet HWaddr 00:26:b9:84:ff:ce inet adr:88.190.11.12 Bcast:88.190.11.255 Masque:255.255.255.0 adr inet6: fe80::226:b9ff:fe84:ffce/64 Scope:Lien UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:107463 errors:0 dropped:0 overruns:0 frame:0 TX packets:90482 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 lg file transmission:1000 RX bytes:19045383 (18.1 MiB) TX bytes:10436963 (9.9 MiB) Interruption:16 Mémoire:da000000-da012800 lo Link encap:Boucle locale inet adr:127.0.0.1 Masque:255.0.0.0 adr inet6: ::1/128 Scope:Hôte UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:70 errors:0 dropped:0 overruns:0 frame:0 TX packets:70 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 lg file transmission:0 RX bytes:6949 (6.7 KiB) TX bytes:6949 (6.7 KiB)
user@dom0$ sudo route -n Table de routage IP du noyau Destination Passerelle Genmask Indic Metric Ref Use Iface 88.190.11.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 88.190.11.1 0.0.0.0 UG 0 0 0 eth0
Vous devez installer les paquets suivant : libxenstore3.0 linux-image-2.6.32-5-xen-amd64 linux-image-xen-amd64 xen-hypervisor-4.0-amd64 xen-tools xen-utils-4.0 xen-utils-common xenstore-utils xenwatch
Avec la commande suivante :
user@dom0$ sudo aptitude installlibxenstore3.0 linux-image-2.6.32-5-xen-amd64 linux-image-xen-amd64 xen-hypervisor-4.0-amd64 xen-tools xen-utils-4.0 xen-utils-common xenstore-utils xenwatch
Par défaut, Debian ne boot pas sur le noyau xen[1]. Il faut donc modifier la configuration de grub pour booter sur ce noyau
user@dom0$ cd /etc/grub.d/ user@dom0$ sudo mv -i 20_linux_xen 09_linux_xen user@dom0$ sudo update-grub2
Vous devez ensuite redémarrer la machine pour qu'elle boot sur ce nouveau noyau. Normalement elle redémarrera sans heurt.
Une fois sur le nouveau noyau, un petit test pour voir si tout s'est bien passé :
user@dom0$ sudo xentop
Si vous voyez quelque chose du genre :
xentop - 10:52:07 Xen 4.0.1 1 domains: 1 running, 0 blocked, 0 paused, 0 crashed, 0 dying, 0 shutdown Mem: 16767188k total, 15117648k used, 1649540k free CPUs: 8 @ 1862MHz NAME STATE CPU(sec) CPU(%) MEM(k) MEM(%) MAXMEM(k) MAXMEM(%) VCPUS NETS NETTX(k) NETRX(k) VBDS VBD_OO VBD_RD VBD_WR VBD_RSECT VBD_WSECT SSID Domain-0 -----r 16821 400.7 14896180 88.8 no limit n/a 8 0 0 0 0 0 0 0 0 0 0 Delay Networks vBds Tmem VCPUs Repeat header Sort order Quit
C'est que tout s'est bien passé. Si vous avez une erreur concernant sysfs, c'est que votre noyau n'est pas le bon.
Il est très fortement conseillé d'utiliser vif-route au lieu de vif-bridge sur le réseau dedibox. Nous allons donc modifier xend en conséquence.
user@dom0$ sudo vim /etc/xen/xend-config.sxp
Vers la ligne 160 il faut commenter ces lignes :
(network-script network-bridge)
Puis un peu plus bas, décommenter
#(network-script network-route) #(vif-script vif-route)
et modifier en
(network-script 'network-route netdev=eth0') (vif-script vif-route)
Il faut aussi modifier le script de route de xen :
user@dom0$ sudo echo 'echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp' >> /etc/xen/scripts/network-route user@dom0$ sudo /etc/init.d/xend restart
Le paquet xen-tools contient plusieurs executables[2] permettant de créer facilement des images xen de plusieurs distributions.
Nous allons d'abord configurer les script pour l'utilisation de xen-create-image
user@dom0$ cd /etc/xen-tools user@dom0$ sudo vim xen-tools.conf
Vous trouverez vers la ligne 129 les tailles par défaut de vous images, ainsi que la composition matérielle (nombre de CPU, quantité de RAM, type de système de fichiers, etc.) Ma configuration est ainsi :
# ## # Disk and Sizing options. ## # size = 15Gb # Disk image size. memory = 128Mb # Memory size swap = 512Mb # Swap size # noswap = 1 # Don't use swap at all for the new system. fs = ext3 # use the EXT3 filesystem for the disk image. dist = `xt-guess-suite-and-mirror --suite` # Default distribution to install. image = sparse # Specify sparse vs. full disk images.
Vers la ligne 160 vous aurez la configuration réseau par défaut :
gateway = 88.190.11.12 netmask = 255.255.255.0
J'ai ici mis la configuration réseau de mon Dom0, mais ces valeurs seront écrasées par les options que nous passerons à xen-create-image
.
Vers la ligne 205 j'ai rajouté :
# # Uncomment the following line if you wish not to generate a new root # password for the new guest. # # genpass = 0 # genpass = 0
Par défaut, xen vous crée un mot de pass root aléatoire et vous l'affiche à l'écran quand il a fini de créer l'image. Si vous êtes un peu rapide/pressé, vous arriverez à faire en sorte que ce mot de pass disparaisse avant que vous ayez pu le noter. Avec cette directive, xen vous demandera le mot de pass que vous voudrez utiliser.
Ligne 228, toujours pour les mots de passe :
# # Uncomment the following line if you wish to interactively setup a # new root password for images. # # passwd = 1 # passwd = 1
J'ai laissé les autres directives par défaut.
user@dom0$ sudo xen-create-image --pygrub --dist=squeeze --ip=88.190.223.115 --mac=00:16:3e:00:00:40 --netmask=255.255.255.255 --hostname=debsqueeze General Information -------------------- Hostname : debsqueeze Distribution : squeeze Mirror : http://ftp.fr.debian.org/debian/ Partitions : swap 512Mb (swap) / 15Gb (ext3) Image type : sparse Memory size : 128Mb Kernel path : /boot/vmlinuz-2.6.32-5-xen-amd64 Initrd path : /boot/initrd.img-2.6.32-5-xen-amd64 Networking Information ---------------------- IP Address 1 : 88.190.223.115 [MAC: 00:16:3e:00:00:40] Netmask : 255.255.255.255 Creating partition image: /var/lib/xen//domains/debsqueeze/swap.img Done Creating swap on /var/lib/xen//domains/debsqueeze/swap.img Done Creating partition image: /var/lib/xen//domains/debsqueeze/disk.img Done Creating ext3 filesystem on /var/lib/xen//domains/debsqueeze/disk.img Done Installation method: debootstrap Done Running hooks Done No role scripts were specified. Skipping Creating Xen configuration file Done Setting up root password Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully All done Logfile produced at: /var/log/xen-tools/debsqueeze.log Installation Summary --------------------- Hostname : debsqueeze Distribution : squeeze IP-Address(es) : 88.190.223.115 RSA Fingerprint : 35:cf:00:03:54:74:60:4a:a5:ca:4f:5f:41:d1:6a:91 Root Password : N/A
user@dom0$ sudo xm create -c /etc/xen/debsqueeze.conf
L'option -c est importante. Elle permet d'avoir une console sur la machine virtuelle qui démarre. Sans cette option, la machine est détachée, vous devez y accéder via SSH. Seulement avec la configuration actuelle, votre machine virtelle n'est pour l'instant pas accessible.
pyGRUB version 0.6 ┌────────────────────────────────────────────────────────────────────────┐ │ Debian GNU/Linux 6.0 │ │ Debian GNU/Linux 6.0 (Single-User) │ │ │ │ │ │ │ │ │ │ │ │ │ └────────────────────────────────────────────────────────────────────────┘ Use the ^ and v keys to select which entry is highlighted. Press enter to boot the selected OS, 'e' to edit the commands before booting, 'a' to modify the kernel arguments before booting, or 'c' for a command line. Will boot selected entry in 1 seconds Started domain debsqueeze (id=4) [ 0.000000] Initializing cgroup subsys cpuset [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 2.6.32-5-xen-amd64 (Debian 2.6.32-30) (ben@decadent.org.uk) (gcc version 4.3.5 (Debian 4.3.5-4) ) #1 SMP Wed Jan 12 05:46:49 UTC 2011 [ 0.000000] Command line: root=/dev/xvda2 ro root=/dev/xvda2 ro [ 0.000000] KERNEL supported cpus: [ 0.000000] Intel GenuineIntel [ 0.000000] AMD AuthenticAMD [ 0.000000] Centaur CentaurHauls [ 0.000000] ACPI in unprivileged domain disabled [ 0.000000] released 0 pages of unused memory [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] Xen: 0000000000000000 - 00000000000a0000 (usable) [ 0.000000] Xen: 00000000000a0000 - 0000000000100000 (reserved) [ 0.000000] Xen: 0000000000100000 - 0000000008000000 (usable) [ 0.000000] DMI not present or invalid. [ 0.000000] last_pfn = 0x8000 max_arch_pfn = 0x400000000 [ 0.000000] init_memory_mapping: 0000000000000000-0000000008000000 [ 0.000000] RAMDISK: 016b8000 - 02fd7000 [ 0.000000] No NUMA configuration found [ 0.000000] Faking a node at 0000000000000000-0000000008000000 [ 0.000000] Bootmem setup node 0 0000000000000000-0000000008000000 [ 0.000000] NODE_DATA [000000000002a000 - 0000000000031fff] [ 0.000000] bootmap [0000000000032000 - 0000000000032fff] pages 1 [ 0.000000] (7 early reservations) ==> bootmem [0000000000 - 0008000000] [ 0.000000] #0 [0000000000 - 0000001000] BIOS data page ==> [0000000000 - 0000001000] [ 0.000000] #1 [000301a000 - 0003037000] XEN PAGETABLES ==> [000301a000 - 0003037000] [ 0.000000] #2 [0000006000 - 0000008000] TRAMPOLINE ==> [0000006000 - 0000008000] [ 0.000000] #3 [0001000000 - 0001697994] TEXT DATA BSS ==> [0001000000 - 0001697994] [ 0.000000] #4 [00016b8000 - 0002fd7000] RAMDISK ==> [00016b8000 - 0002fd7000] [ 0.000000] #5 [0002fd7000 - 000301a000] XEN START INFO ==> [0002fd7000 - 000301a000] [ 0.000000] #6 [0000008000 - 000002a000] PGTABLE ==> [0000008000 - 000002a000] [ 0.000000] Zone PFN ranges: [ 0.000000] DMA 0x00000000 -> 0x00001000 [ 0.000000] DMA32 0x00001000 -> 0x00100000 [ 0.000000] Normal 0x00100000 -> 0x00100000 [ 0.000000] Movable zone start PFN for each node [ 0.000000] early_node_map[2] active PFN ranges [ 0.000000] 0: 0x00000000 -> 0x000000a0 [ 0.000000] 0: 0x00000100 -> 0x00008000 [ 0.000000] SFI: Simple Firmware Interface v0.7 http://simplefirmware.org [ 0.000000] SMP: Allowing 1 CPUs, 0 hotplug CPUs [ 0.000000] No local APIC present [ 0.000000] APIC: disable apic facility [ 0.000000] PM: Registered nosave memory: 00000000000a0000 - 0000000000100000 [ 0.000000] Allocating PCI resources starting at 8000000 (gap: 8000000:f8000000) [ 0.000000] Booting paravirtualized kernel on Xen [ 0.000000] Xen version: 4.0.1 (preserve-AD) [ 0.000000] NR_CPUS:512 nr_cpumask_bits:512 nr_cpu_ids:1 nr_node_ids:1 [ 0.000000] PERCPU: Embedded 30 pages/cpu @ffff88000306d000 s90328 r8192 d24360 u122880 [ 0.000000] pcpu-alloc: s90328 r8192 d24360 u122880 alloc=30*4096 [ 0.000000] pcpu-alloc: [0] 0 [ 0.000000] Xen: using vcpu_info placement [ 0.000000] Built 1 zonelists in Node order, mobility grouping on. Total pages: 32187 [ 0.000000] Policy zone: DMA32 [ 0.000000] Kernel command line: root=/dev/xvda2 ro root=/dev/xvda2 ro [ 0.000000] PID hash table entries: 512 (order: 0, 4096 bytes) [ 0.000000] Initializing CPU#0 [ 0.000000] Checking aperture... [ 0.000000] No AGP bridge found [ 0.000000] Memory: 95476k/131072k available (3147k kernel code, 384k absent, 35212k reserved, 1908k data, 600k init) [ 0.000000] SLUB: Genslabs=14, HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] Hierarchical RCU implementation. [ 0.000000] NR_IRQS:4352 nr_irqs:512 [ 0.000000] Console: colour dummy device 80x25 [ 0.000000] console [tty0] enabled [ 0.000000] console [hvc0] enabled [ 0.000000] installing Xen timer for CPU 0 [ 0.000000] Detected 1862.031 MHz processor. [ 0.004000] Calibrating delay loop (skipped), value calculated using timer frequency.. 3724.06 BogoMIPS (lpj=7448124) [ 0.004000] Security Framework initialized [ 0.004000] SELinux: Disabled at boot. [ 0.004000] Dentry cache hash table entries: 16384 (order: 5, 131072 bytes) [ 0.004000] Inode-cache hash table entries: 8192 (order: 4, 65536 bytes) [ 0.004000] Mount-cache hash table entries: 256 [ 0.004000] Initializing cgroup subsys ns [ 0.004000] Initializing cgroup subsys cpuacct [ 0.004000] Initializing cgroup subsys devices [ 0.004000] Initializing cgroup subsys freezer [ 0.004000] Initializing cgroup subsys net_cls [ 0.004000] CPU: L1 I cache: 32K, L1 D cache: 32K [ 0.004000] CPU: L2 cache: 256K [ 0.004000] CPU: L3 cache: 8192K [ 0.004000] CPU 0/0x3 -> Node 0 [ 0.004000] CPU: Unsupported number of siblings 16 [ 0.004000] Performance Events: unsupported p6 CPU model 30 no PMU driver, software events only. [ 0.004000] SMP alternatives: switching to UP code [ 0.004000] Freeing SMP alternatives: 28k freed [ 0.004164] Brought up 1 CPUs [ 0.004273] devtmpfs: initialized [ 0.007968] Grant table initialized [ 0.007975] regulator: core version 0.5 [ 0.008033] NET: Registered protocol family 16 [ 0.008814] PCI: setting up Xen PCI frontend stub [ 0.009293] bio: create slab <bio-0> at 0 [ 0.009364] ACPI: Interpreter disabled. [ 0.009399] xen_balloon: Initialising balloon driver with page order 0. [ 0.009448] vgaarb: loaded [ 0.009508] PCI: System does not support PCI [ 0.009513] PCI: System does not support PCI [ 0.009592] Switching to clocksource xen [ 0.010783] pnp: PnP ACPI: disabled [ 0.010984] NET: Registered protocol family 2 [ 0.011053] IP route cache hash table entries: 1024 (order: 1, 8192 bytes) [ 0.011268] TCP established hash table entries: 4096 (order: 4, 65536 bytes) [ 0.011311] TCP bind hash table entries: 4096 (order: 4, 65536 bytes) [ 0.011338] TCP: Hash tables configured (established 4096 bind 4096) [ 0.011343] TCP reno registered [ 0.011395] NET: Registered protocol family 1 [ 0.011439] Unpacking initramfs... [ 0.029811] Freeing initrd memory: 25724k freed [ 0.036328] platform rtc_cmos: registered platform RTC device (no PNP device found) [ 0.036528] audit: initializing netlink socket (disabled) [ 0.036542] type=2000 audit(1298716438.501:1): initialized [ 0.041443] HugeTLB registered 2 MB page size, pre-allocated 0 pages [ 0.042805] VFS: Disk quotas dquot_6.5.2 [ 0.042858] Dquot-cache hash table entries: 512 (order 0, 4096 bytes) [ 0.042933] msgmni has been set to 236 [ 0.043109] alg: No test for stdrng (krng) [ 0.043164] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 253) [ 0.043171] io scheduler noop registered [ 0.043175] io scheduler anticipatory registered [ 0.043179] io scheduler deadline registered [ 0.043212] io scheduler cfq registered (default) [ 0.046544] registering netback [ 0.048173] Linux agpgart interface v0.103 [ 0.048207] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled [ 0.048412] input: Macintosh mouse button emulation as /devices/virtual/input/input0 [ 0.048463] PNP: No PS/2 controller found. Probing ports directly. [ 0.049283] i8042.c: No controller found. [ 0.049349] mice: PS/2 mouse device common for all mice [ 0.049576] rtc_cmos rtc_cmos: rtc core: registered rtc_cmos as rtc0 [ 0.174162] cpuidle: using governor ladder [ 0.174171] cpuidle: using governor menu [ 0.174188] No iBFT detected. [ 0.174612] TCP cubic registered [ 0.174791] NET: Registered protocol family 10 [ 0.175436] lo: Disabled Privacy Extensions [ 0.175812] Mobile IPv6 [ 0.175821] NET: Registered protocol family 17 [ 0.175973] registered taskstats version 1 [ 0.175995] XENBUS: Device with no driver: device/vbd/51714 [ 0.176004] XENBUS: Device with no driver: device/vbd/51713 [ 0.176011] XENBUS: Device with no driver: device/vif/0 [ 0.176018] XENBUS: Device with no driver: device/console/0 [ 0.176043] /build/buildd-linux-2.6_2.6.32-30-amd64-d4MbNM/linux-2.6-2.6.32/debian/build/source_amd64_xen/drivers/rtc/hctosys.c: unable to open rtc device (rtc0) [ 0.176072] Initalizing network drop monitor service [ 0.176219] Freeing unused kernel memory: 600k freed [ 0.176389] Write protecting the kernel read-only data: 4328k Loading, please wait... [ 0.228234] udev[46]: starting version 164 [ 0.316800] Initialising Xen virtual ethernet driver. [ 0.330826] blkfront: xvda2: barriers enabled [ 0.332243] Setting capacity to 31457280 [ 0.332257] xvda2: detected capacity change from 0 to 16106127360 [ 0.332903] blkfront: xvda1: barriers enabled [ 0.334222] Setting capacity to 1048576 [ 0.334234] xvda1: detected capacity change from 0 to 536870912 Begin: Loading essential drivers ... done. Begin: Running /scripts/init-premount ... done. Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done. Begin: Running /scripts/local-premount ... done. [ 0.597917] kjournald starting. Commit interval 5 seconds [ 0.597938] EXT3-fs: mounted filesystem with ordered data mode. Begin: Running /scripts/local-bottom ... done. done. Begin: Running /scripts/init-bottom ... done. INIT: version 2.88 booting Using makefile-style concurrent boot in runlevel S. Starting the hotplug events dispatcher: udevd[ 0.762185] udev[147]: starting version 164 . Synthesizing the initial hotplug events...done. Waiting for /dev to be fully populated...[ 0.871458] input: PC Speaker as /devices/platform/pcspkr/input/input1 [ 0.973613] Error: Driver 'pcspkr' is already registered, aborting... done. Activating swap...[ 1.095101] Adding 524280k swap on /dev/xvda1. Priority:-1 extents:1 across:524280k SS done. Checking root file system...fsck from util-linux-ng 2.17.2 /dev/xvda2: clean, 13584/983040 files, 195590/3932160 blocks done. [ 1.133306] EXT3 FS on xvda2, internal journal Loading kernel modules...done. Cleaning up ifupdown.... Setting up networking.... Activating lvm and md swap...done. Checking file systems...fsck from util-linux-ng 2.17.2 done. Mounting local filesystems...done. Activating swapfile swap...done. Cleaning up temporary files.... Setting kernel variables ...done. Configuring network interfaces...SIOCADDRT: No such process Failed to bring up eth0. done. Cleaning up temporary files.... INIT: Entering runlevel: 2 Using makefile-style concurrent boot in runlevel 2. Starting enhanced syslogd: rsyslogd. Starting OpenBSD Secure Shell server: sshd. Starting periodic command scheduler: cron. Debian GNU/Linux 6.0 debsqueeze hvc0 debsqueeze login:
Pour voir si votre machine virtuelle tourne, utilisez xentop
:
user@dom0$ sudo xentop xentop - 11:36:07 Xen 4.0.1 2 domains: 1 running, 1 blocked, 0 paused, 0 crashed, 0 dying, 0 shutdown Mem: 16767188k total, 15245088k used, 1522100k free CPUs: 8 @ 1862MHz NAME STATE CPU(sec) CPU(%) MEM(k) MEM(%) MAXMEM(k) MAXMEM(%) VCPUS NETS NETTX(k) NETRX(k) VBDS VBD_OO VBD_RD VBD_WR VBD_RSECT VBD_WSECT SSID debsqueeze --b--- 1 0.0 127232 0.8 131072 0.8 1 1 0 0 2 0 978 79 28146 1000 0 Domain-0 -----r 27539 400.7 14896180 88.8 no limit n/a 8 0 0 0 0 0 0 0 0 0 0 Delay Networks vBds Tmem VCPUs Repeat header Sort order Quit
On peut voir que la machine debsqueeze tourne
Pour l'instant la configuration de la vm ressemble à ça :
root@debsqueeze:~# ifconfig eth0 Link encap:Ethernet HWaddr 00:16:3e:00:00:40 inet addr:88.190.223.115 Bcast:88.255.255.255 Mask:255.255.255.255 inet6 addr: fe80::216:3eff:fe00:40/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:4 errors:0 dropped:0 overruns:0 frame:0 TX packets:6 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:244 (244.0 B) TX bytes:468 (468.0 B) Interrupt:246 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:8 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:536 (536.0 B) TX bytes:536 (536.0 B) root@debsqueeze:~# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface
Comme je le disais, par défaut, votre VM n'a pas encore accès au net. Pour ceci, vous allez devoir ajouter la gateway avec une certaine configuration
root@debsqueeze:~# route add 88.190.11.1/32 dev eth0 root@debsqueeze:~# route add default gw 88.190.11.1
Nous pouvons maintenant vérifier que nous avons le net à partir de la VM :
root@debsqueeze:~# ping -c 3 free.fr PING free.fr (212.27.48.10) 56(84) bytes of data. 64 bytes from www.free.fr (212.27.48.10): icmp_req=1 ttl=122 time=0.868 ms 64 bytes from www.free.fr (212.27.48.10): icmp_req=2 ttl=122 time=0.895 ms 64 bytes from www.free.fr (212.27.48.10): icmp_req=3 ttl=122 time=0.948 ms --- free.fr ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2004ms rtt min/avg/max/mdev = 0.868/0.903/0.948/0.048 ms
Et depuis l'exterieur vers la vm :
moi@autremachine$ ssh root@88.190.223.115 root@88.190.223.115's password: Linux debsqueeze 2.6.32-5-xen-amd64 #1 SMP Wed Jan 12 05:46:49 UTC 2011 x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sat Feb 26 11:44:46 2011 root@debsqueeze:~#
Pour mémoriser cette configuration, nous allons modifier le fichier /etc/network/interfaces (j'ai installé vim entre temps) :
root@debsqueeze:~# vim /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address 88.190.223.115 netmask 255.255.255.255 # les deux lignes à rajouter : post-up route add -host 88.190.11.1/32 dev eth0 post-up route add default gw 88.190.11.1 # post-up ethtool -K eth0 tx off # # The commented out line above will disable TCP checksumming which # might resolve problems for some users. It is disabled by default #
ifconfig
, redémarrer votre machine. Cette interface doit venir de l'installation de xen en bridge. Faire un ifconfig peth0 down
va tout simplement vous couper l'accès au réseau.[1] Sources: Bug 606719 chez Debian, Le wiki debian sur xen
[2] xt-customize-image, xt-create-xen-config, xen-list-images, xen-delete-image, xt-install-image, xen-create-nfs, xen-create-image, xt-guess-suite-and-mirror, xen-update-image
{ 19 juillet 2010 }
lundi, juillet 19 2010, 15:16 :: Coding
First, edit your config/databases.yml and add :
[yml] all: doctrine: class: sfDoctrineDatabase param: dsn: mysql:socket=/var/run/mysqld/mysqld.sock;dbname=mydb username: mydb password: mypassword encoding: utf8 attributes: default_table_collate: utf8_unicode_ci default_table_charset: utf8
Then open your config/doctrine/schema.yml and add at the top of your file :
|yml] --- detect_relations: true options: collation: utf8_unicode_ci charset: utf8 type: InnoDB
Of course, if you want to stick to myisam, replace InnoDB by MyIsam.
Befware, some plugins provides their own schema.yml. You may have to modify it, or to inherite it and specify that they're in utf8 (to come later)
Symfony 1.2, 1.3 and 1.4
{ 6 avril 2010 }
mardi, avril 6 2010, 18:06 :: Coding
For one of my projects I have to check if a record already exists in my database, deleted or not. The preDqlSelect looks like this :
/** * Implement preDqlSelect() hook and add the deleted flag to all queries for which this model * is being used in. * * @param Doctrine_Event $event * @return void */ public function preDqlSelect(Doctrine_Event $event) { $params = $event->getParams(); $field = $params['alias'] . '.' . $this->_options['name']; $query = $event->getQuery(); if ( ! $query->contains($field)) { $query->addWhere( $field . ' = ' . $query->getConnection()->convertBooleans(false) . ' OR ' . $field . ' IS NULL' ); } }
The method is adding the statement only if !$query->contains($field)
, and contains
is just doing an stripos on the DQL. At this time, the DQL is the part between the FROM
to the end. It doesn't include the SELECT
part. So to bypass the SoftDelete behaviour, the field deleted have to be in the DQL. A simple solution is to add a dummy statement like this :
$results = Doctrine_Query::create() ->from('Table t') ->where('t.deleted = t.deleted') ->execute() ;
Thanks to vjousse for the tip
{ 19 mars 2010 }
vendredi, mars 19 2010, 08:29 :: Coding
A new release of the Notify plugin for aMSN is now available.
You can download it on http://www.amsn-project.net/plugins....
Changelog:
{ 4 février 2010 }
jeudi, février 4 2010, 14:26 ::
I tested the rapidity of isset vs array_key_exists. I always thougt that array_key_exists would be the winner ...
Here is my script :
┌─(yoda@ev5)(14:25:29) └─(~/var/www/test)-> cat isset_array-key-exists.php #!/usr/bin/php <?php define('N', "\n"); error_reporting(E_ALL | E_NOTICE); $nbLoop = 10000; $testArray = array('foo' => 'bar', 'bar' => 'quux'); $time = array(); $desc = array( 0 => 'array_key_exists on existant key', 1 => 'array_key_exists on non existant key', 2 => 'isset on existant key', 3 => 'isset on non existant key', ); /** * begin with array_key_exists, existant key */ $time[0]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { array_key_exists('foo', $testArray); } $time[0]['stop'] = microtime(true); /** * begin with array_key_exists, non existant key */ $time[1]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { array_key_exists('foz', $testArray); } $time[1]['stop'] = microtime(true); /** * begin with isset, existant key */ $time[2]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { isset($testArray['foo']); } $time[2]['stop'] = microtime(true); /** * begin with isset, non existant key */ $time[3]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { isset($testArray['foz']); } $time[3]['stop'] = microtime(true); $differences = array(); echo 'results: '.N; foreach($time as $k => $t) { echo 'test '.$k.' "'.sprintf('%40s', $desc[$k]).'" : '.($difference[$k] = $t['stop'] - $t['start']).N; }
And here is the results :
┌─(yoda@ev5)(14:25:32) └─(~/var/www/test)-> php isset_array-key-exists.php results: test 0 " array_key_exists on existant key" : 0.00795984268188 test 1 " array_key_exists on non existant key" : 0.00665903091431 test 2 " isset on existant key" : 0.00737690925598 test 3 " isset on non existant key" : 0.00131511688232
And the winner is : isset !
{ 4 février 2010 }
jeudi, février 4 2010, 14:14 :: Coding
I tested different loops. Here is my test script :
┌─(yoda@ev5)(14:32:05) └─(~/var/www/test)-> cat for_foreach_while.php #!/usr/bin/php <?php define('N', "\n"); error_reporting(E_ALL | E_NOTICE); $nbLoop = 10000; $testArray = array_fill(0, 500, 'toto'); $time = array(); $desc = array( 'iterating an array with a count + for', 'iterating an array with a foreach', 'iterating an array with a while', ); /** * iterating with for */ echo 'Starting test 1'.N; $time[0]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { $nb = count($testArray); for($j = ($nb - 1); $j > 0; $j--) { } } $time[0]['stop'] = microtime(true); echo 'Test 1 ended'.N; /** * iterating with foreach */ echo 'Starting test 2'.N; $time[1]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { foreach($testArray as $k => $v) { } } $time[1]['stop'] = microtime(true); echo 'Test 2 stopped'.N; /** * iterating with while(list() = each()) */ echo 'Starting test 3'.N; $time[2]['start'] = microtime(true); for($i = 0; $i < $nbLoop; $i++) { while(list($k, $v) = each($testArray)) { } reset($testArray); } $time[2]['stop'] = microtime(true); echo 'Test 3 ended'.N; $differences = array(); echo 'results: '.N; foreach($time as $k => $t) { echo 'echo test '.$k.' "'.sprintf('%40s', $desc[$k]).'" : '.($difference[$k] = $t['stop'] - $t['start']).N; }
And the results are :
┌─(yoda@ev5)(14:32:47) └─(~/var/www/test)-> php for_foreach_while.php Starting test 1 Test 1 ended Starting test 2 Test 2 stopped Starting test 3 Test 3 ended results: echo test 0 " iterating an array with a count + for" : 0.489103078842 echo test 1 " iterating an array with a foreach" : 0.750061988831 echo test 2 " iterating an array with a while" : 4.91836500168
The winner is count+for, followed by foreach, and while is far behind. I suppose it's because of the reset.
PHP: 5.2.12 (debian) in CLI
Special thanks to Folliked for remembering me that while still exists
{ 3 février 2010 }
mercredi, février 3 2010, 14:03 :: Coding
It's possible, when validating a form, to check if a field is correct dependently of an other field's value.
First, in your configure method, after the declaration of your validators, add :
$this->validatorSchema->setPostValidator( new sfValidatorCallback( array('callback' => array($this, 'checkRequiredFields')) ) );
And create a new method in your form class !
public function checkRequiredFields($validator, $values) { $errors = array(); /** * checking if mandatory_field == 3, then other_field must be filled */ if(3 == $values['mandatory_field'] && null == $values['other_field']) { $error = new sfValidatorError($validator, 'if you choose the option 3 for mandatory_field, you need to fill the other_field'); $errors['other_field'] = $error; //throw new sfValidatorErrorSchema($validator, array('other_field' => $error)); } else { // nothing to check } /** * checking if foo is selected, then bar must be filled */ if(1 == $values['foo'] && null == $values['bar']) { $error = new sfValidatorError($validator, 'if you check foo, you need to fill bar'); $errors['bar'] = $error; } else { // nothing to check } /** * more depency checking here */ /** * if there is errors */ if(count($errors)) { throw new sfValidatorErrorSchema($validator, $errors); } /** * dont forget to return values ! */ return $values; }
2010-02-23 Updated: All errors are now returned once. 2010-02-23 Updated: Deleted the commented throw, added another check.
{ 20 janvier 2010 }
mercredi, janvier 20 2010, 19:24 :: Coding
Hey, yes it's possible to change the default type of your primary keys with a simple configuration
Open your config/databases.yml
. It should looks like this :
[yml] # You can find more information about this file on the symfony website: # http://www.symfony-project.org/reference/1_4/en/07-Databases all: doctrine: class: sfDoctrineDatabase param: dsn: mysql:host=localhost;dbname=. username: root password:
But Doctrine lets you customize some things. Now the file looks like :
[yml] # You can find more information about this file on the symfony website: # http://www.symfony-project.org/reference/1_4/en/07-Databases all: doctrine: class: sfDoctrineDatabase param: dsn: mysql:host=localhost;dbname=. username: root password: attributes: default_identifier_options: type: integer length: 4 unsigned: true
Nowyou can change the parameter, lets say an integer, and length: 5.
It's event possible to add any configuration that will be added automatically to your model.
Note: It's not possible to set autoincrement: false
. True is forced by doctrine.
Note: This behavior is true when no primary column is found in your schema.
Thanks to PhilG (#symfony-fr @ Freenode) for testing. Tested with symfony 1.4.1
{ 2 décembre 2009 }
mercredi, décembre 2 2009, 10:03 :: Coding
In symfony, it's possible to return a value in your execute() method.
Let's create a test task :
┌─(yoda@box)(09:46:59) └─(~/var/www/test)-> ./symfony generate:task test >> task Creating "/home/yoda/var/www/test.../testTask.class.php" task file
Adding a return value at the end of the method. :
<?php class testTask extends sfBaseTask { protected function configure() { // // add your own arguments here // $this->addArguments(array( // new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'), // )); $this->addOptions(array( new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name'), new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'), new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'), // add your own options here )); $this->namespace = ''; $this->name = 'test'; $this->briefDescription = ''; $this->detailedDescription = <<<EOF The [test|INFO] task does things. Call it with: [php symfony test|INFO]|> EOF; } protected function execute($arguments = array(), $options = array()) { // initialize the database connection $databaseManager = new sfDatabaseManager($this->configuration); $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection(); // add your code here return 42; } }
And now, execute the task :
┌─(yoda@box)(09:47:32) └─(~/var/www/test)-> ./symfony test ┌─(yoda@box)(09:47:40) └─(~/var/www/test)-> echo $? 42
The return value is correctly returned. Note that without return value, the task simply returns 0.
In the case that an exception occurs, let's see what is returned. I added a dummy exception in the execute method :
<?php class testTask extends sfBaseTask { protected function configure() { // // add your own arguments here // $this->addArguments(array( // new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'), // )); $this->addOptions(array( new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name'), new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'), new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'), // add your own options here )); $this->namespace = ''; $this->name = 'test'; $this->briefDescription = ''; $this->detailedDescription = <<<EOF The [test|INFO] task does things. Call it with: [php symfony test|INFO]|> EOF; } protected function execute($arguments = array(), $options = array()) { // initialize the database connection $databaseManager = new sfDatabaseManager($this->configuration); $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection(); // add your code here throw new Exception('foo'); return 42; } }
┌─(yoda@box)(09:51:37) └─(~/var/www/test)-> ./symfony test foo ┌─(yoda@box)(09:51:43) └─(~/var/www/test)-> echo $? 1
The task returns 1 in case of an exception.
{ 30 novembre 2009 }
lundi, novembre 30 2009, 13:41 :: Coding
It happen sometimes that you have to set/override a value within a form but without using a hidden field (that can be overridden)
Here is a short solution to set the user id in the object we are going to save.
Let's say that we have an object PersonnalData linked to the sfGuardUserProfile
In your PersonnalDataForm.class.php :
class PersonnalDataForm extends BasePersonnalDataForm { public function configure() { } //public function processValues($values = null) { // only in 1.2 public function processValues($values) { // 1.3 - 1.4 $values['user_id'] = $this->getOption('user_id'); return parent::processValues($values); } }
$this->getOption('user_id')
is a mechanism to pass variables from outside the form to it. To set it, you must use the second argument of the form's constructor.
In your action :
public function executeMyaction(sfWebRequest $request) { // setting an array containg the variable we want to use in our form $this->form = new PersonnalDataForm(null, array('user_id' => $this->getUser()->getProfile()->getId() )); if($request->isMethod('post')) { $this->form->bind($request->getParameter($this->form->getName())); if($this->form->isValid()) { $this->form->save(); } else { //echo 'not valid'; } } }
{ 30 novembre 2009 }
lundi, novembre 30 2009, 13:21 :: Coding
I recently had a problem when loading fixtures in my symfony project. I was loading cities, about 37 000 of them, and the doctrine:data-load was extremly slow (about 5 minutes). I finally found a solution to load an sql dump wihtin a task, using the doctrine/default connection.
With this solution, I reduced the time from minutes to 2 secondes.
<?php class loadALotOfDataTask extends sfBaseTask { protected function configure() { // // add your own arguments here // $this->addArguments(array( // new sfCommandArgument('my_arg', sfCommandArgument::REQUIRED, 'My argument'), // )); $this->addOptions(array( new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'), new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'), new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'), // add your own options here )); $this->namespace = ''; $this->name = 'loadALotOfData'; $this->briefDescription = ''; $this->detailedDescription = <<<EOF The [loadALotOfData|INFO] task does things. Call it with: [php symfony loadALotOfData|INFO]|> EOF; } protected function execute($arguments = array(), $options = array()) { // initialize the database connection $databaseManager = new sfDatabaseManager($this->configuration); $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection(); // add your code here $file = '../data/dump.sql'; if(!file_exists($file)) { $this->logSection('File', sprintf('File %s does not exists', $file)); return; } // loading the file in the memory. In my case, the file was $data = file_get_contents($file); // passing queries to the orm $statement = $connection->prepare($data); // executing $statement->execute(); } }
{ 4 août 2009 }
mardi, août 4 2009, 14:24 :: Coding
Il arrive souvent qu'on ai besoin de retourner plusieurs informations distinctes dans une fonction ou une méthode. La plupart du temps, il suffit de retourner un tableau indexé de manière intelligente.
class CSS { public function getDeclaration($pDeclaration) { list($key, $value) = explode(':', $pDeclaration); $key = trim($key); $value = trim($value, ' ;'); return array('key' => $key, 'value' => $value); } }; $ret = CSS::getDeclaration('background-color: #FFFFFF;'); echo 'Clé: '.$ret['key']; echo 'Valeur: '.$ret['valeur'];
Mais quand on utilise des frameworks tel que symfony où tout (ou presque) est objet, il devient difficile de chainer les éléments.
STDClass
[1] vient donc à notre secours.
class CSS { public function getDeclaration($pDeclaration) { list($key, $value) = explode(':', $pDeclaration); $key = trim($key); $value = trim($value, ' ;'); $r = new STDClass; $r->key = $key; $r->value = $value; return $r; } };
Il devient maintenant possible de faire une déclaration du genre :
echo 'Clé: '.CSS::getDeclaration('background-color: #FFFFFF;')->key; echo 'Valeur: '.CSS::getDeclaration('text-decoration: underline;')->value;
Petite mise à jour, j'avais fait une petite typo dans le premier bout de code, au niveau des echo-s. Merci Neolitec.
[1] http://php.net/stdclass
{ 29 juillet 2009 }
mercredi, juillet 29 2009, 17:10 :: Info
I recently recevied my new Asus eee1005HA-H bough on Materiel.net. Everything seemed fine as there was a Debian project supporting the eee-s. But unfortunately the current installer couldn't support networking devices.
{ 11 juillet 2009 }
samedi, juillet 11 2009, 14:13 :: Coding
Hey, I just uploaded my first plugin for symfony !
This plugin is a simple wrapper for a jQuery Carousel found at http://sorgalla.com/projects/jcarousel/
{ 4 juillet 2009 }
samedi, juillet 4 2009, 13:58 :: Info
Here is a little tip to display the latest posts of your dotclear blog in your symfony website.
If your blog database is in an other database than symfony's one, you need to create a connection in the /config/databases.yml
. Otherwise, skip this step
Mine looks like this :
[yml] dev: beta: param: classname: DebugPDO test: beta: param: classname: DebugPDO all: symfony: class: sfDoctrineDatabase param: classname: DoctrinePDO dsn: mysql:dbname=mysymfonydbanem;host=localhost username: mysymfonyusername password: mysymfonypassword encoding: utf8 persistent: true pooling: true blog: class: sfDoctrineDatabase param: classname: DoctrinePDO dsn: mysql:dbname=myblogdbname;host=localhost username: myblogusername password: myblogpassword encoding: utf8 persistent: true pooling: true
You must create models from the database to be able to retrieve the posts
$ ./symfony doctrine:build-schema --env=blog $ ./symfony doctrine:build-model
As you can see, some Dc*.class.php are now created in the /lib/model/doctrine/
folder.
In your controller (actions.class.php), use and customize this request :
public function executeIndex(sfWebRequest $request) { $this->posts = Doctrine_Query::create() ->from('DcPost p') ->where('p.post_status = 1') ->orderBy('p.post_creadt DESC') ->limit(5) ->execute(); }
<?php foreach($posts as $post) : ?> <div class="blog_box"> <h5><a href="#"><?php echo $post->getPostTitle() ?></a></h5> <?php echo __('Posted by') ?> <a href="http://url.to.your.blog/path/index.php?post/<?php echo $post->getPostUrl() ?>"><span><?php echo $post->getDcUser()->getUserDisplayname () ?></span></a> <?php echo __('in') ?> <a href="#"><span><?php echo $post->getDcCategory()->getCatTitle() ?></span></a><br /> <?php echo substr(strip_tags($post->getRawValue()->getPostContentXhtml()), 0, 40).'...' ?><br /> <div class="datetime"><?php echo $post->getPostCreadt() ?></div> </div> <?php endforeach; ?>
and that's it, you made it !
PS: This howto is maybe somehow wrong, I made those steps few times before making this working. Feel free to correct.
Update 1 : Added a where clause to select only posts where post_status = 1. Added the link to the post
{ 10 juin 2009 }
mercredi, juin 10 2009, 11:52 ::
If you are using like me svn to manage your website, you certainly notified that all the .svn files are fully readable by everyone in plain text. So here is a fix to deny the acces to those files :
<Directory ~ "\.svn"> Order allow,deny Deny from all </Directory>
Solution found at http://alexking.org/blog/2005/04/12/svn-as-a-web-site-maintenence-tool
« billets précédents - page 1 de 13