searbe http://www.searbe.co.uk Most recent posts at searbe posterous.com Tue, 08 Nov 2011 16:35:00 -0800 HP DM1 4027sa and Ubuntu http://www.searbe.co.uk/hp-dm1-4027sa-and-ubuntu http://www.searbe.co.uk/hp-dm1-4027sa-and-ubuntu

I was looking for a small laptop to use on the train. I came across the HP DM1 4027sa - it looked like a surpsisingly good balance of performance and size, at a very reasonable £350.

I'll start by saying the laptop's definitely worth the money. Build quality is good (but don't expect premium at this price) and with 4GB RAM and a dual-core CPU, the whole thing is very snappy and runs like a modern PC. Considering it's netbook size and netbook price. It's great, especially in comparison to other netbooks which, to be honest, feel like a step back in time when you use them. This laptop can stream video, play HD video, run virtual machines, and so on, without any disablingly-huge performance hit.

I wanted to install Ubuntu. It's all great, but two things to save you a headache:

Remove Fourth Primary Partition

This thing comes with 4 primary partitions. You will need to delete one to get Ubuntu installed. Once you get the laptop home, boot into Windows, fire up HP Recovery Manager and use the "Create Recovery Media" option. Once you've done that, use the "Delete Recovery Partition" option to remove the partition. Then you'll be able to create a new 4th primary partition for Ubuntu.

The graphics card is not supported

If you want to use ATI's proprietary fglrx driver, you're out of luck. It doesn't work with this graphics card yet. Personally, any 3D things I want to do are in Windows, so using the open source drivers doesn't affect me here. I expect this will be resolved soon.

Broadcom 4313 Wireless is slow and buggy in Ubuntu

To fix this one, you will need to connect via the Ethernet socket. Go to Additional drivers when it's connected and make sure the Broadcom driver is enabled. Once you've done that, you're not finished: Ubuntu's lying!

Run `lspci -nn` and for this 4027sa you should find the wifi adapter has the id numbers 14e4:4727.

Run the command `lspci -k -nn -d 14e4:4727` - if it tells you the kernal driver in use is anything other than "wl", you will need to blacklist the open source Broadcom drivers. Add the following to /etc/modprobe.d/blacklist-bcm43.conf :

blacklist brcmsmac
blacklist bcma 

Save and restart. Run `lspci -k -nn -d 14e4:4727` again to confirm that "wl" is now the driver in use, then you should be good to go.

Touchpad Occasionally Stops Working

I haven't figured out /why/ this is happening. I suspect that there is an area of the touchpad that I'm pressing that turns it off (and that area isn't in the 'dip' it's supposed to be in!). However if your touchpad stops working, run this:

`synclient TouchpadOff=0`

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Tue, 02 Aug 2011 13:55:00 -0700 The Perfect Windows 7 LAMP using Ubuntu and Virtualbox http://www.searbe.co.uk/the-perfect-windows-7-ubuntu-lamp http://www.searbe.co.uk/the-perfect-windows-7-ubuntu-lamp

The purpose of this blog post is to get you running a reliable, Unix-based web development environment on top of Windows 7, using Virtuabox to create an Ubuntu virtual machine. It's an improvement on my previous setup, serves as a "note-to-self" on how to get up and running and is something I thought others would find useful.

Create a LAMP virtual machine

Create a new VM and install Ubuntu. Install aptitude, then virtualbox guest utils:

sudo apt-get install aptitude sudo aptitude install virtualbox-ose-guest-utils

Restart your VM. If you like, you can shut down then enable 3D Acceleration in your VM's settings before restarting. Depends if you care about having hardware accelleration - useful if you want to use Unity.

If you're running on a Laptop or don't have much RAM, I'd recommend Fluxbox to keep bloat to a minumum. So, optionally, install that:

sudo aptitude install fluxbox

If you do run that, you'll need to log out, click your username, choose fluxbox, then log back in.

Once you're back in, it'll all be listening to your clipboard, screen resizing, etc thanks to the guest additions. If you did the 3D hardware thing you'll have Unity too. Now install Apache, PHP, mod-php, Mysql, PHP-Mysql, Curl, so on. Here's a glorious one-liner to do just that.

sudo aptitude install apache2 php5 libapache2-mod-php5 php5-cli php5-curl mysql-server php5-mysql libapache2-mod-auth-mysql phpmyadmin

Note: To save you frustration, when it comes to the "Configuring phpmyadmin" step and it asks you which web server to reconfigure automatically, apache2 is not selected by default even if it looks like it is. I'm looking at you, Vic. Hit space to put an asterisk in the apache2 box, then press enter. 

Another note: for some stupid reason, by default, every /javascript directory is aliased. run `sudo rm -f /etc/apache2/conf.d/javascript-common.conf` to fix that.

Now restart apache2:

sudo /etc/init.d/apache2 restart

Open Firefox in your VM and visit "http://localhost/phpmyadmin". If all's well, you'll see "It works!". Visit "http://localhost/phpmyadmin" and, if all is well, you will see phpmyadmin.

Getting Windows to see it

Your virtual machine can probably already see the internet. That'll be using NAT. You have two options now if you want to have your Windows machine see your VM. Read the description of each then choose wisely.

Option one: Set up a Bridged Network with a permanent IP address

This the simplest way to get going. If your computer only ever lives on one network (i.e., it is a desktop), and you are able to set up a static IP, and your Windows machine has a static IP too, I recommend this.

Shut down your VM, open it's settings, under Network change Adapter 1 from NAT to Bridged Network. Press OK, then start up your VM. Check the internet's working.

Presuming it is all working, go to terminal and type ifconfig. Keep that info up. Now go to network settings (if you're using Unity and are confused - hit the "windows key" and start typing to find stuff). Edit Auto eth0, change IPv4 Settings -> Method to Manual. Your "inet addr" was listed by ifconfig - put that as your address, you'll see your Mask from ifconfig to put in Netmask, and your Gateway is whatever your router's IP address is (e.g. 192.168.1.1). You will probably want to put your router's IP in the "DNS servers" box and the "search domains" box, unless you know otherwise.

Hit save, and if all is good, the internet should still work. If not, double-check your router's IP and make sure you put it as the Gateway, in DNS servers and in search domains. So now you have a virtual machine with a permanent IP on your network. Visit your VM's IP address, which you just set up, in your Windows machine and you should see the "It works!" message.

Option two: Set up a Host-Only Network

This option is best if you are constantly switching between networks, routers, or you otherwise don't want to give your VM a static IP address on your local network. It is, however, problematic. You may have noticed Virtualbox install a virtual network adapter on your Windows machine. This method makes use of that to set up a network between your Windows machine and your Ubuntu VM.

Shut down your VM, open it's settings, under Network go to Adapter 2. Enable it and choose Host-only Adapter, then click OK. Now start your VM. Once you're in, check the internet's working.

In terminal, type ifconfig. You'll see "eth0", which is your NAT network adapter, and you'll see "eth1", which is your Host-only Adapter. Note the IP address. Unless you are running multiple VMs that IP is safe enough to be considered permanent, however if you want to be sure, you are more than welcome to follow option one from paragraph three to set it up a permanent IP, with the exception you will be dealing with eth1, not eth0.

Enter the eth1 IP address in your Windows VM and you should see the "It works!" page.

Troubleshooting: If you have problems with the Virtualbox Host-Only Network

If you have problems, firstly upgrade Virtualbox. If you still have problems, make sure the latest virtualbox host-only network driver is installed - use Device Manager (in Windows) to find the virtual device, right click it, and click 'upgrade driver'. Select the Oracle/Sun Virtualbox directory in Program files and let it search there for a compatible driver. Once installed, try again. 

If you still have problems, Windows might be refusing to do things on the basis the host-only network is "unidentified" and thus is forcing you to use your public firewall rules. To fix, you could go to start -> run -> secpol.msc. Click Network List Manager Policies, then double click Unidentified Networks, and check the circle to have unidentified networks always classed as private. This will make unidentified networks use your private firewall rules, which will likely be a be more relaxed ruleset.

So... now your VM is set up, sees the internet, and one way or another you have a solid IP address to reference your VM. At this point, make sure you can definitely see the "It works!" page from Windows. Now Ubuntu just needs to be serving files from your Windows machine as if it were on the VM.

Sharing the code on your Windows disk with Ubuntu using Samba and Autofs

You might be tempted to use Virtualbox's shared folders feature. Don't. It doesn't seem to support mmap properly - so the guest OS won't load changed files into it's cache, meaning you have to either specify `EnableMMAP Off` in your Apache config (and in anything else that might use it), or keep dropping the disk cache when you make tweaks to certain files (`echo 3 > /proc/sys/vm/drop_caches` as root).

So on with Samba.

Create a share on your Windows machine. I'm sharing C:\development. Right-click the development directory, go to Sharing, click "Share...", select Everyone from the drop-down, click Add, change Everyone's permission level to Read/Write, then click Share.

Note the Network Path - in my case, \\CRAIG-PC\development. Now, your IP on your host-only network adapter is probably 192.168.56.1. You can check by running ipconfig from the Windows command line. So for me, I will eventually be mounting //192.168.56.1/development.

Go to Control Panel, Network and Sharing Center, then click Change advanced sharing settings. Make sure file and printer sharing is turned on, public folder sharing is turned on and depending whether you want authentication you may want to disable Password protected sharing. For the purposes of this tutorial I will be using a username and password, for which I have a specially created "share" user on my Windows machine.

Okay, in your Ubuntu VM, open nautilus (the file browser), click on Network, find your PC (mine is called "CRAIG-PC") and browse your way to the network share you just created. You should be able to browse the network share as easily as that - although you may need to enter your username/password.

Now install smbfs:

sudo aptitude install smbfs

Let's test you can mount properly from the shell. Make sure you've unmounted the network share in Nautilus. Enter in terminal:

sudo mkdir /mnt/test sudo mount -t cifs //192.168.56.1/development -o username=your_user,password=your_password /mnt/test cd /mnt/test ls -l

And there you should get the contents of your C:\development directory. Hopefully that all worked out for you! Now, to make things a bit more permanent... 

Unmount your test mount (I'm not going to tell you to delete your /mnt/test directory as you could delete stuff from your Windows drive if you aren't careful enough. I'll leave that up to you):

sudo umount /mnt/test

Install autofs:

sudo aptitude install autofs

Make a 'win' dir, or whatever else you fancy:

sudo mkdir /win

Edit /etc/auto.master (`sudo nano /etc/auto.master`) and add the following at the end of the file:

/win /etc/auto.win --timeout=300

Create an auto.win file in /etc/auto.win by running (`sudo nano /etc/auto.win`) and paste the following contents:

development  -fstype=cifs,username=your_username,password=your_password,uid=1000,gid=1000    ://192.168.56.1/development

Restart autofs:

sudo service autofs restart

Now, autofs is quite magical. It doesn't mount something until it is actually needed. Also, note the --timeout=300? That means after five minutes of non-use, it will be unmounted automatically too. Try the following:

ls -l \win

Note there's nothing there? Now try this:

cd \win\development ls -l 

Hopefully, that worked, and it just mounted itself. Pretty cool huh. It'll unmount after the timeout period. So we've avoided putting stuff in /etc/fstab, which means boot shouldn't hang, and when apache2 tries access the directory (which, to be honest, is probably going to be during boot) only then will it be mounted.

So from here on, it's up to you how you proceed.

Recommended reading: http://www.greenfly.org/tips/autofs.html

 

 

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Fri, 03 Jun 2011 13:57:00 -0700 PHPUnit and Virtualbox / Uncaught exception 'PHPUnit_Framework_Exception' http://www.searbe.co.uk/phpunit-and-virtualbox-uncaught-exception-php http://www.searbe.co.uk/phpunit-and-virtualbox-uncaught-exception-php

Note

As per the comments for this post (I haven’t had the time to verify):

Paul Mitchell submitted a patch which solves the issue in the latest versions of Virtualbox Guest Additions – so please try upgrading.

If that doesn’t work, Theodore Smith suggests that adding this attribute and value to the phpunit tag in your xml configuration will solve the issue:

testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"

Original post

I’ve been fighting for two evenings trying to get PHPUnit working.

I have a setup where my LAMP stack runs in VirtualBox, in which I’ve mounted a folder shared with the virtual machine via Virtualboxes “shared folders” feature.

It seems that there’s a bug with DirectoryIterator; end result is it will point-blank refuse to iterate over files in your shared folder, and when you run your unit tests in the folder “Foo” with the command “phpunit Foo”:

PHP Fatal error:  Uncaught exception 'PHPUnit_Framework_Exception' with message 'Neither "FooTests.php" nor "FooTests.php" could be opened.' in /usr/share/php/PHPUnit/Util/Skeleton/Test.php:102

So. You’re going to have to do things the old fashioned way to fix this. Find PHPUnit_Runner_IncludePathTestCollecto (which uses File_Iterator and ultimately reliest on a RecursiveDirectoryIterator) and comment out the following:

/**
 * @return File_Iterator
 */
public function collectTests()
{
    $iterator = File_Iterator_Factory::getFileIterator(
      $this->paths, $this->suffixes, $this->prefixes
    );

    if ($this->filterIterator !== NULL) {
        $class    = new ReflectionClass($this->filterIterator);
        $iterator = $class->newInstance($iterator);
    }

    return $iterator;
}

In its place, insert this code – which does stuff the skanky old fashioned way:

public function collectTests()
{
    $tests = array();

    foreach ($this->paths as $path) {
        $tests = array_merge($tests, $this->_iterate($path));
    }

    return $tests;
}

protected function _iterate($path)
{
    $a = array();
    if ($h = opendir($path)) {
        while (false !== ($fname = readdir($h))) {
            $fullPath = $path . '/' . $fname;

            if ($fname == '.' || $fname == '..') {
                continue;
            }

            if (is_dir($fullPath)) {
                $a = array_merge($a, $this->_iterate($fullPath));
                continue;
            }

            foreach ((array) $this->suffixes as $sfx) {
                if (substr($fname, -strlen($sfx)) == $sfx) {
                    $a[] = $fullPath;
                    continue;
                }
            }

            foreach ((array) $this->prefixes as $pfx) {
                if (substr($fname, 0, strlen($pfx)) == $pfx) {
                    $a[] = $fullPath;
                    continue;
                }
            }
        }
        closedir($h);
    }
    return $a;
}

Now “phpunit Foo” will correctly iterate through your Foo directory and test your stuff.

This does need revisiting but for now this quick fix seems to get least get things running.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Wed, 22 Dec 2010 14:37:00 -0800 Iceland Holiday http://www.searbe.co.uk/iceland-holiday http://www.searbe.co.uk/iceland-holiday

I went to Iceland. For those of you who want to see some photos, here are a random few that won't get me in trouble with Kerry for posting pictures of her on the internet.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Wed, 22 Dec 2010 14:22:00 -0800 Java for PHP programmers http://www.searbe.co.uk/moving-from-php-to-java http://www.searbe.co.uk/moving-from-php-to-java

I wanted to learn Java so I could get on with some Android programming. I’ll try to cover everything that someone who only knows PHP would need to know to get to grips with Java. Have a quick read of this and it’ll answer a few questions you might have along the way.

Java is strongly typed

Something you might not be used to is the concept of “declaring” a variable. In Java you must declare a variable first.

DatabaseRecord foo;
foo = new DatabaseRecord();

On line 1 you declare the variable specifying its type (so the variable “foo” must contain a DatabaseRecord). On the next line, you create a new DatabaseRecord object and assign it to “foo”. You can do that all on one line:

DatabaseRecord foo = new DatabaseRecord();

So here once foo is declared, anything assigned to it must be of the type DatabaseRecord. You can only ever assign a DatabaseRecord to the variable “foo”. Whereas in PHP-land, you could put a string in a variable that was an object a second ago.

So this is valid in PHP:

$foo = new Bar();
$foo = "Blah blah";

But the equivalent is not valid in Java:

DatabaseRecord foo = new DatabaseRecord();
foo = "Blah blah";

Even a method must have a return type specified:

In PHP:

class myClass {
    public function getName() {
        return "Craig";
    }
}

In Java:

class myClass {
    public String getName() {
        return "Craig";
    }
}

Note you don’t specify “function”. For functions that don’t return a value or return with “return;”, use “void” in place of “String”

Object properties are called fields

In PHP you have “properties” in objects:

class myClass {
    public $foo = 'bar';
    protected $_bar = 'baz';
}

In Java you have “fields”. The syntax is similar, and you must specify a type for each field.

class myClass {
    public String mFoo = 'bar';
    protected String mBar = 'baz';
}

One convention I saw in an Android code sample was to prefix every property with ’m' (for ‘Member Field’). I find useful for identifying which variables are fields of the current object, especially taking the next point into account.

You don’t use “this” very often

When you’re accessing properties in Java, you don’t use “$this”.

In PHP you’d go:

class myClass {
    protected $_bar = 'baz';

    public function getBar() {
        return $this->_bar;
    }
}

In Java you wouldn’t use “this”:

class myClass {
    protected String mBar = 'baz';

    public String getBar() {
        return mBar;
    }
}

The only time you really need to use “this” is if you have a collision and it becomes unclear which variable you mean. For example:

In Java:

class myClass {
    protected String mBar = 'baz';

    public String getBar(String mBar) {
        return this.mBar; // specify "this" to access the mBar field
                          // instead of the mBar that was passed to
                          // the method
    }
}

Annotations (e.g. @override)

When you start overriding methods in parent classes, you’ll notice “@override” in front of methods that are overridden.

I suppose you can think of this as a message to the compiler (the thing that turns your code into a program). The @override annotation denotes that following method overrides a method in the parent class. It won’t compile if it doesn’t.

You can set up your own annotations for whatever reason you might like, and you can access information on what annotations are set on a specific method using Reflection (up next).

Here’s a (rather pointless) example of the @override annotation:

class MyActivity extends Activity {
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return super.onCreateOptionsMenu(menu);
    }
}

See this guide for more info on annotations: http://download.oracle.com/javase/1.5.0/docs/guide/language/annotations.html

Reflection – “What is Object.class?”

Every class you declare essentially extends the Object class. The Object class will give your class a bunch of standard methods and fields. One of them is a static member accessed via ClassName.class. This will return you a “Class” object.

This “class” object describes your object and has various methods for exploring your object – for example, you could use it to see what annotation a method has. Or you could use it to let another method know what class to create.

You might see something like this:

String someObject = "A string";
Intent i = new Intent(someObject, MyActivity.class)

This is creating a new “Intent” object, passing in the string object, then passing in the Class object from static MyActivity.class field. For instance, internally the Intent object might use the Class object to create a new MyActivity object – as the class object has a newInstance() method.

Generics – Angled / Square Brackets in Java

If you see this kind of syntax:

List<Integer> = new LinkedList<Integer>();

You might be confused by the angled brackets. These are “generics” and allow you to tell the List object what kind of object it will be storing.

Set yourself some time aside to read this excellent tutorial: http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Arrays aren’t the solution any more

In Java, you’re not going to find arrays as useful as you do in PHP. In PHP you declare an array without specifying any size, the type of the array, or anything.

In Java, you have to specify the length of the array. And you can only have an array of one type of object (for example, it must contain all integers, or all strings).

So in PHP:

$stringArray = array('One', 'Two', 'Three');

In Java:

String[3] stringArray;
stringArray[0] = "One";
stringArray[1] = "One";
stringArray[2] = "One";

Note that you declare an array by putting square brackets containing the array length. Then you can access those three, and only those three elements.

If you want a list of objects of unspecified size, you probably want to use a LinkedList object. The usage of that goes like this:

LinkedList myList = new LinkedList();
myList.add(new MyObject());
myList.add(new MyObject());
myList.add(new MyObject());

That adds three MyObject objects to the list. The nicest way to iterate through a linked list is using for-each syntax, which is similar to PHP’s. Alternatively a for loop using myList.size() would work.

To use a for-each as per below, you must iterate over something that implements the Collection interface. List and LinkedList both implement this interface, thus the following is possible:

LinkedList myList = new LinkedList();
myList.add(new MyObject());
myList.add(new MyObject());
myList.add(new MyObject());

for (MyObject myobj : myList) {
    myobj.doSomething();
}

So that’s “for each (MyObject)myObj in myList, do this:”. The equivalent in PHP would be:

$myList = array();
$myList[] = new MyObject();
$myList[] = new MyObject();
$myList[] = new MyObject();

foreach ($myList as $myObj) {
    $myObj.doSomething();
}

Personally I think Java’s way of doing it makes more sense. PHP’s way almost seems back-to-front.

Associative Arrays

For those moments where you absolutely must have an associative array, you use a hashtable.

See the following documentation: http://download.oracle.com/javase/1.4.2/docs/api/java/util/Hashtable.html

Note that you have to cast objects on the way out – the Hashtable doesn’t use the Generics mechanism I described earlier to ensure a specific data type.

Implementing interfaces with anonymous objects

Something I found really cool, and if you’ve used interfaces before I’m sure you will too, was implementing interfaces with anonymous objects. In PHP, if you have an interface, you need a solid class declaration somewhere that implements it, then you use that class declaration.

In Java you can implement an interface on-the-fly. You specify the interface you’re implementing, followed by a code block containing the implementation:

OnClickListener myClickListener = new OnClickListener() {
    public void onClick(DialogInterface dialoginterface, int i) {
        startGame(i);
    }
};

Neat huh? It’s really useful for tiny handler objects like the above. Imagine having to have a whole concrete class declaration for 50 handlers that are only used once anyway.

Inner / Nested Classes and Interfaces

In the example above I actually omitted something – the OnClickLister is actually a “static nested interface”. The correct code is this:

DialogInterface.OnClickListener myClickListener = new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialoginterface, int i) {
        startGame(i);
    }
};

I will attempt to explain however I found the following the most useful piece of information: http://download.oracle.com/javase/tutorial/java/javaOO/nested.html

The first example is a regular inner class (not a static one like the OnClickListener). You can have a class declaration inside a class, and only the outer class may ever create an instance of the inner class. That’s a “nested class” and it looks like this:

class MyClass {
    class MyInnerClass {
    }

    public void foo() {
        MyClass.MyInnerClass innerObject = new MyClass.MyInnerClass();
    }
}

So you create an inner class declaration (MyInnerClass) that can only exist within the outer class (MyClass).

Sometimes a class should live inside another class but still be accessible to the world – so it’s only living within another class for the sake on namespacing, like the OnClickListener example above (the difference being it’s an interface rather than a class, so you’d just substitute “class” with “interface”).

In this case, you’d use the ‘static’ keyword:

class MyClass {
    static class MyInnerClass {
    }

    public void foo() {
        MyClass.MyInnerClass innerObject = new MyClass.MyInnerClass();
    }
}

class MyOtherClass {
    public void foo() {
        MyClass.MyInnerClass inner = new MyClass.MyInnerClass();
    }
}

Note that in this case, the inner class can reside within another class entirely. It doesn’t have to be inside MyClass.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Wed, 22 Dec 2010 08:39:00 -0800 Add Custom Tab Auto-Completion to your Bash Scripts http://www.searbe.co.uk/add-custom-tab-auto-completion-to-your-bash-s http://www.searbe.co.uk/add-custom-tab-auto-completion-to-your-bash-s

I like shoving little methods in my bash ~/.profile ... to complete the laziness I added tab auto-completion.

Create a method that generates the tab options then use "complete" to assign it to your custom method:

# a method which returns all my project dirs via COMPREPLY - note the use of # compgen and ls /clients within backticks, that's where you want to do # your own thang function _clientdirs() {         local curw         COMPREPLY=()         curw=${COMP_WORDS[COMP_CWORD]}         COMPREPLY=($(compgen -W '`ls /clients`' -- $curw))         return 0 } # my 'q' shortcut method to run a queue script in one of my projects function q() {         if [ $# -eq 1 ]         then                 php /clients/$1/core/tools/run_queue.php local         else                 php core/tools/run_queue.php local         fi } # assigning the complete method to my method complete -F _clientdirs -o dirnames q

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Thu, 09 Dec 2010 16:16:00 -0800 Windows 7 Lamp - Ubuntu / VirtualBox PHP Development Environment http://www.searbe.co.uk/windows-7-lamp-ubuntu-virtualbox-php-developm http://www.searbe.co.uk/windows-7-lamp-ubuntu-virtualbox-php-developm

NOTICE: I have made a more up-to-date tutorial. If you prefer, you can still follow this post. However I'd recommend you give my new setup a try - you'll find it at The Perfect Windows 7 LAMP using Ubuntu and Virtualbox. This post tells you to mount in a nasty way and uses virtualbox's Shared Folders feature which I find problematic.

A few steps on getting yourself set up with an Ubuntu LAMP running in VirtualBox, sharing your internet connection in a way which keeps it portable (so it'll work on your laptop regardless of what network you're on) but also two-way (so you can see your virtual machine on the network and your vm can see you). It involves creating a host-only network and is quite easy once you've jumped through the hoops.

Install VirtualBox

Head on over to virtualbox.org, download and install. Then create a new Virtual Machine and set up your Ubuntu LAMP.

Get an Ubuntu LAMP set up

If you're not familiar with VirtualBox, you need to create a new machine. VirtualBox will take you through a wizard which you should be able to figure out. Head over to Ubuntu and grab yourself an ISO. Once you have the an Linux desktop sitting in front of you, get your server set up. Check out my Ubuntu LAMP guide if you don't know how.

Add VirtualBox Shared Folders

Power your virtual machine off and open VirtualBox. Click the VM (your virtual machine, in my case I called it 'ubuntu'), click Settings then Shared Folders. Add a shared folder from your Windows drive. This will contain all of the stuff you want to share with your Linux box.

You can do multiple shares if you like. I prefer to have a single shared folder and treat it like a drop-box for everything.

Install VirtualBox Guest Additions

Start up your VM. You will need to install Guest Additions if you haven't already. Click 'Devices' at the top of your VM then click 'install guest additions'. This will mount a CD, in which there is a .sh shell script which you should execute (run "./scriptname.sh" in terminal).

Mount your Shared Directories in the Ubuntu Virtual Machine

In your running VM, make a directory somewhere. I use /development (mkdir /development). This is where the contents of the shared folder you created earlier will appear.

To mount the shared folder:

sudo mount -t vboxsf development /development

With "development" being name you specified when you created the shared folder in VirtualBox and "/development" being the directory you just created in the Virtual Machine.

It's a little annoying having to run this in the terminal each time the VM boots up - so what I did is stick it at the end of /etc/rc.local, just before exit 0 (rc.local is a script that's run just at the end of startup).

Before that works, you'll want to edit /etc/sudoers (sudo nano /etc/sudoers) and add a line like this:

%craig ALL = NOPASSWD: ALL

(Change 'craig' to your user's group)

Configure VirtualBox Port Forwarding

Great, nearly there. You have a LAMP setup, you have a shared folder without any SAMBA rubbish, but you can't access your LAMP from Windows!

Don't go and set up a bridged network - there's a better solution; VirtualBox's port forwarding. You want to make every request to port 80 of your PC forward to the VirtualBox guest.

Open a command prompt in Windows and change directory to wherever VirtualBox is installed - in my case, C:\Program Files\Sun\VirtualBox.

Take note of what your VM is called. Mine is called Ubuntu. If it has a space in the name, you'll need to wrap it in "double quotes" in the following commands.

My Virtual Machine uses a pcnet adapter - others talk about e1000 - you may need to tweak as necesarry, but unfortunately I don't know the abbreviated names for the other adapters. Let's just presume your Virtual Machine uses a pcnet adapter.

Run this to have every request to port 80 on your host (Windows 7) forward to port 80 on your guest (the Ubuntu VM).

VBoxManage.exe setextradata Ubuntu "VBoxInternal/Devices/pcnet/0/LUN#0/Config/Apache/HostPort" 80 VBoxManage.exe setextradata Ubuntu "VBoxInternal/Devices/pcnet/0/LUN#0/Config/Apache/GuestPort" 80 VBoxManage.exe setextradata Ubuntu "VBoxInternal/Devices/pcnet/0/LUN#0/Config/Apache/Protocol" TCP

Run the following and the extra data you just set should be spat back at you, just to confirm the settings are all in there okay:

VBoxManage.exe getextradata Ubuntu enumerate

Configure VirtualBox Host-Only Adapter

Now we need to add a second network adapter so we have a permanent IP address to your Windows host. Power your Ubuntu VM down, edit the network adapters and enable the second adapter. Choose 'Attached to: host-only adapter'.

Now you have an "internal networ" between Ubuntu and Windows. In VirtualBox, go to File->Settings->Network and click the configure icon for the host-only adapter. You'll see an IP address - default is 192.168.56.1. This is your Windows PC's "internal network" IP - so anywhere you need a permanent handle to your host, use this IP.

Now you have a Windows 7 irrtitance (bug?) to fix: go to Run, and enter secpol.msc. Click Network List Manager Policies, then double click Unidentified Networks, and check the circle to have unidentified networks always classed as private. This will make unidentified networks use your private firewall rules, which will likely be a be more relaxed ruleset. If you don't do this, you might have trouble getting Ubuntu to talk to Windows 7 on this "internal network".

Configure XDebug

Okay now for XDebug. Jump back in to your Ubuntu VM and ensure your xdebug config file (probably at /etc/php5/apache/conf.d/xdebug.ini) has this:

xdebug.remote_enable=on xdebug.remote_handler=dbgp xdebug.remote_host=[your HOST machines permanent IP on the host-only adapter, 192.168.56.1 in my case] xdebug.remote_port=9000 xdebug.idekey=netbeans-xdebug

IMPORTANT It seems that somehow this setup will now *ONLY* work if you have an xdebug session running, otherwise you get an infinite hang where it seems XDebug is trying to connect to a client (?!). So comment out the first line by putting a semi-colon in front of it:

;xdebug.remote_enable=on

And only un-comment it when you want to run a debug session. Not great but I can't find another solution :-( Please comment if you know of a better way.

Finished!

Right - now restart VirtualBox and, hopefully, you will be all set up with a Linux development machine inside a Windows development environment!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Fri, 25 Dec 2009 16:33:00 -0800 Acer 3000, 3020, 5020 Windows 7 Drivers & Windows Vista Drivers http://www.searbe.co.uk/acer-3000-3020-5020-windows-7-drivers-windows http://www.searbe.co.uk/acer-3000-3020-5020-windows-7-drivers-windows

Acer apparently "dont support" Windows 7 or Windows Vista drivers on my Acer 3020. After spending a while browsing around for drivers, I found Acer 3020 Vista drivers. They work great on Windows 7.

Or have a browse of their FTP server yourself and find whatever else you're looking for: ftp://ftp.support.acer-euro.com/notebook/

If these links break, you might be able to find your way to their FTP server by paying attention to download locations on their support site.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell
Sat, 19 Dec 2009 16:38:00 -0800 Ubuntu 10.10 LAMP Install Guide http://www.searbe.co.uk/ubuntu-1010-lamp-install-guide http://www.searbe.co.uk/ubuntu-1010-lamp-install-guide

# Install Apache2 sudo apt-get install apache2 sudo /etc/init.d/apache2 start sudo /etc/init.d/apache2 stop # Install PHP5 and the PHP5-CLI sudo apt-get install php5 libapache2-mod-php5 php5-cli sudo /etc/init.d/apache2 restart # Install MySQL sudo apt-get install mysql-server # ... and the php/apache mysql gubbins. Also phpMyAdmin. sudo apt-get install libapache2-mod-auth-mysql php5-mysql phpmyadmin sudo /etc/init.d/apache2 restart # Install rewrite module sudo a2enmod rewrite sudo /etc/init.d/apache2 restart # now configure apache2 - I use a domains directory mkdir ~/domains # shove your vhosts in a config file. I'll just edit default; sudo gedit /etc/apache2/sites-available/default # Restart apache - shouldn't get any errors sudo /etc/init.d/apache2 restart # And some useful utils sudo apt-get install subversion php5-xdebug nautilus-open-terminal

Finally if you want to nab your fonts from your windows partition:

sudo apt-get install msttcorefonts cd /media/disk/windows/Fonts sudo cp *.ttr *.TTF /usr/share/fonts/truetype/msttcorefonts/

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/921910/P1000949.JPG http://posterous.com/users/1kW9IE5JZ2Zb Craig Bendell searbe Craig Bendell