Still alive and kicking

Hello people! It’s been quite a long time since my last post, during this time I’ve been quiet some things changed, I resumed my studies, but i’m still working as a freelance web developer. The absence of new posts is also due to the fact i’m developing my personal homepage, and i intend to move my blog there, but while it’s not done, i decided to keep posting stuff in here, and keep sharing :)

With this post i also want to announce that i released on github a few super-simple CakePHP plugins i’ve been using in the last years in some projects, some of them have not been much used lately, but they should work fine on any CakePHP 2.X app.

The released plugins are:

Settings
A plugin to provide application wide persistent editable settings support.
Sortable
Sortable model records behavior for CakePHP.
Navigation
CakePHP Plugin which provides some navigation related facilities.
JS Manager
Provides automatic inclusion of javascript scripts in CakePHP projects.
Transactions
A simple behavior that provides database transactions control under CakePHP.
ValidationSet
CakePHP support for multiple sets of model validation rules.

Currently there’s no documentation available on them, but i’ll take care of that in the next few days, as well as unit tests.

Advertisements

An easy way to extend/rename CakePHP helpers transparently

There were times, while developing CakePHP apps, when i felt that a certain helper wasn’t doing the right thing for me, there was something missing (for example, i felt the lack of some features on the PaginatorHelper, i’m working on an extended version of it that i’ll publish soon), and the only way to fix it would be extending the helper and replacing all it’s occurrences on my views, this can be a very time consuming task.

Fortunately, someone found a nice workaround for doing it transparently, i found plugin called Analogue, it allows you to remap helpers transparently just by adding it to the controller.

You can check it on the author’s github page

The usage is pretty straight forward, you can see it on the plugin’s readme file.

A big thank you to the plugin’s author!

(understand that the ideal solution for the problem would be forking the plugin you think could be improved, improve it, and send your changes back in a push request, in a diff, whatever.. But this helper can still be handy sometimes)

Create a Debian Squeeze LXC template under Debian Squeeze

By default, the Debian container template script installs Debian Lenny, which is no more the current stable release, so it makes sense that your new containers run an up to date release, i tried squeeze so far, didn’t try testing or still in development yet, so i’ll tell you how to create a script to create Debian Squeeze containers.

By default, the lxc package ships with few different template scripts, and they’re located in the directory /usr/lib/lxc/templates/, the debian one is called lxc-debian.
Copy it to the same directory with another name:

user@host:/usr/lib/lxc/templates$ sudo cp lxc-debian lxc-debian-squeeze

Open it with with your favorite text editor and change the following lines:

dhcp-client,\

to

isc-dhcp-client,\
lenny $cache/partial-$arch http://ftp.debian.org/debian

to

squeeze $cache/partial-$arch http://ftp.debian.org/debian
cache="/var/cache/lxc/debian"

to

cache="/var/cache/lxc/debian-squeeze"

(this last appears two times!)

… Or just apply the following patch:

--- lxc-debian	2011-02-08 01:03:22.931566630 +0000
+++ lxc-debian-squeeze	2011-02-08 01:19:46.287573988 +0000
@@ -90,7 +90,7 @@
 locales,\
 libui-dialog-perl,\
 dialog,\
-dhcp-client,\
+isc-dhcp-client,\
 netbase,\
 net-tools,\
 iproute,\
@@ -110,7 +110,7 @@
     echo "Downloading debian minimal ..."
     debootstrap --verbose --variant=minbase --arch=$arch \
 	--include $packages \
-	lenny $cache/partial-$arch http://ftp.debian.org/debian
+	squeeze $cache/partial-$arch http://ftp.debian.org/debian
     if [ $? -ne 0 ]; then
 	echo "Failed to download the rootfs, aborting."
 	return 1
@@ -136,7 +136,7 @@
 
 install_debian()
 {
-    cache="/var/cache/lxc/debian"
+    cache="/var/cache/lxc/debian-squeeze"
     rootfs=$1
     mkdir -p /var/lock/subsys/
     (
@@ -220,7 +220,7 @@
 
 clean()
 {
-    cache="/var/cache/lxc/debian"
+    cache="/var/cache/lxc/debian-squeeze"
 
     if [ ! -e $cache ]; then
 	exit 0

And now you’re ready to create new Debian Squeeze containers :)

user@host:~$ sudo /usr/lib/lxc/templates/lxc-debian-squeeze -p /var/lib/lxc/my-awesome-debian-squeeze-container

There’s also something else you’ll probably need to do in order to login to a tty with lxc-console, the template script does not create any of the /dev/tty’s, so you’ll need to create them by hand, or change the new template script in order to create it:

… cd to your container’s rootfs and execute the following commands:

user@host:~$ sudo mknod -m 666 /dev/tty1 c 4 1
user@host:~$ sudo mknod -m 666 /dev/tty2 c 4 2
user@host:~$ sudo mknod -m 666 /dev/tty3 c 4 3
user@host:~$ sudo mknod -m 666 /dev/tty4 c 4 4

Now you may want to edit your container’s configuration, and then start using it.
For your convenience, you can setup a first container, do your initial configuration on it, and then leave it alone, every new container you want to create could be just a copy of it, this will boost the container’s setup, just don’t forget to edit the new containers configuration accordingly.

user@host:/var/lib/lxc$ sudo cp -a squeeze-base-container new-web-container

Install fuse powered filesystems within an LXC container

I’m running a Debian Squeeze in an LXC container, and i needed to install SSHFS within the container, a FUSE based filesystem which lets you to mount remote filesystems through SSH. It shouldn’t be a problem, but fuse-utils depends on udev, and as you may know, LXC containers do not support udev, which will cause problems during the install.
While installing the udev package you’ll get some errors related with device creation like the following one:

Populating the new /dev filesystem temporarily mounted on /tmp/udev.EgkS50/...
mknod: `//tmp/udev.EgkS50/ppp': Operation not permitted

In order to solve this i had to allow those new devices to be created in your container’s configuration file by adding the following lines:

#ppp
lxc.cgroup.devices.allow = c 108:0 rwm
#fuse
lxc.cgroup.devices.allow = c 10:229 rwm
#loop0
lxc.cgroup.devices.allow = b 7:0 rwm
#tun
lxc.cgroup.devices.allow = c 10:200 rwm

Now start your container and login.
Then, because the udev install will break your created devices, you should backup them:

user@host:~$ sudo cp -a /dev /dev.old

Go and install your fuse based filesystem, i’ll be installing sshfs:

user@host:~$ sudo apt-get install sshfs

Restore your old devices:

user@host:~$ sudo cp -a /dev.old/* /dev/

Create the fuse device:

user@host:~$ sudo mknod /dev/fuse c 10 229

Avoid udev to boot by disabling its init scripts:

user@host:~$ sudo update-rc.d -f udev disable

And that’s it, you should now be able to mount your fuse powered filesystem :-)

Changing Git submodule remote repository

A Git submodule allows you to add other repositories inside your project source tree, they’re handful for application modules or plugins, so you can develop reusable plugins independently of your app. When you add submodules, it is created a file called .gitmodules, in your source tree root, where are stored all submodule information (remote repository URL and it’s path on the source tree).
During the development of a project, the source of a submodule may change for any reason (the server URL changed, the repository’s name or path changed, etc…), and you’ll have to update those changes in your apps, otherwise you won’t be able to push or pull on those submodules. This task is not that easy, because Git apart from storing submodule information in the .gitmodules file, it stores the same information in the repository configuration file (.git/config), and every submodule’s repository remote URL. But fortunately, there’s an easier way to do that using the ‘git submodule sync’ command, all you have to do is:

1) Edit the .gitmodules file, and change the URL for the submodules which changed.

2) In your source tree’s root run:

user@host:/path/to/repo$ git submodule sync

3) Then run git init to update the project’s repository configuration with the new URLs:

user@host:/path/to/repo$ git submodule init

And it’s done, now you can continue pushing and pulling your submodules with no problems :)

Tunneling network connections through SSH

Sometimes you may want to tunnel your connections through a secure SSH connection, because you want the traffic to be encrypted, because of any restrictive access rule in your firewall, or any other reason.
I assume you have a regular account in a machine running an OpenSSH server, an OpenSSH client installed in your machine, and you’re running Linux.
What you have to do is to bounce all network connections through a SOCKS4 / SOCKS5 local proxy created by the SSH connection, that can be done using the -D option on the OpenSSH client call, in conjunction with the tsocks library. tsocks is basically a library which intercepts network connections from any application, and redirects them through a SOCKS server, if you’re using Ubuntu there’s also a script with the same name which wraps it, allowing you to enable and disable the connection forwarding.

At first you’ll need to configure the SOCKS server and port in the tsocks configuration file, for that edit the file /etc/tsocks.conf and set the following options:

server = 127.0.0.1
server_port = 1080

Then, do the SSH connection:

user@host$ ssh -NfD 1080 user@remote

The “D” will create the local SOCKS proxy, binding it to the give port (1080 is the default one), the “f” tells the client to execute in the background after logging in and executing the command, and the “N” tells the client to not execute any command. So, it’ll just create the SOCKS server and go to background.

After that, just run the tsocks command (man tsocks for more information)

user@host$ tsocks

Now every connection done by every application you run in this shell session will be redirected through the SOCKS server, and will be done by the remote server.

Hope it helps someone! :)

CakePHP and in-memory query caching

CakePHP models by default cache in-memory all database queries you make in each request, this reduces the database querying overhead when redundant queries are made, assuming that nothing changed. But sometimes there’s a need to implement complex methods in your models to perform complex and crazy actions with your data, and sometimes when you do that you need to make the same query many times, for example, when you’re checking something inside any loop, and when you do that, if your model is caching queries, you’ll get always the same result, that will bring you for sure an unexpected behavior. So when you do that, you just need to disable query caching by setting the cacheQueries variable to false in your model before the database query you don’t want to cache, and enabling it after, if needed. It’ll make you model to generate a real fetch of data in the server. I believe that some of you are thinking which it can be avoided if you do any kind of data handling in your logic, avoiding the model to do repeated fetches to the database, and you’re right, but each situation is unique, and this need is not very usual. I just want you to be aware about the models query cache existence :)