Functional programming in PHP using Map Reduce

This tutorial shows you how to leverage some of PHP’s functional programming abilities.

This is just a simple solution to Problem 22 from ProjectEuler.net, but it’s a good example of showing how to use a hybrid of OOP and Functional Programming to arrive at the correct solution.

We’ll use basic OOP for the structure and for encapsulation, and then we’ll implement the actual solution using the infamous Map Reduce pattern.

Here’s a look at the full implementation, then we’ll go over each piece individually.

ProjectEuler.net Problem 22

namespace ProjectEuler\Problems;

class Problem22
{
 private $inputData = array();

 function __construct()
 {
  $filename = "./p022_names.txt";
  $this->readInCsv($filename);

  // Would never do this. Only invoking from the
  // constructor for brevity since not a real app.
  //
  // Invoking methods on this class should
  // come from your controllers.
  // And a class with this type of logic would be classified
  // as domain logic, aka *business logic*.
  //
  // This "business logic" should be structured as
  // Domain Objects (or a service depending 
  // on reusability) in your application as
  // part of your Model *layer*.

  $result = $this->mapReduce();
  $this->displayResult($result);
 }

 private function readInCsv($filename)
 {
  $handle = fopen($filename, "r");
  $this->inputData = fgetcsv($handle, 0, ",");
  fclose($handle);

  sort($this->inputData);
 }

 private function mapReduce()
 {
  $nameTotal = array_map(function($name, $index) {

   $charsTotal = array_reduce(str_split($name),
    function($runningCharTotal, $char) {

     // calculate value by offsetting from capital 
     // ascii char values to get sequential values
     $runningCharTotal += ord(strtoupper($char)) - 64;

     return $runningCharTotal;
    });

   // return the name position
   // multiplied by the name's char total
   return ($index + 1) * $charsTotal;

  }, $this->inputData, array_keys($this->inputData));

  $total = array_reduce($nameTotal, 
   function($runningNameTotal, $item) {

    $runningNameTotal += $item;

    return $runningNameTotal;
   });

  return $total;
 }

 private function displayResult($result)
 {
  echo 'The total is: ';
  print_r($result);
 }
}




First we’ll take a look at how to read in data from our .txt file.

The readInCsv method uses fopen to open the file, bind it to a data stream, and then fgetcsv parses each line (using commas as the delimiter) into an array.

This array is then sorted alphabetically using one of the native PHP sorting algorithms (I believe it’s an implementation of QuickSort for those wondering)

 private function readInCsv($filename)
 {
  $handle = fopen($filename, "r");
  $this->inputData = fgetcsv($handle, 0, ",");
  fclose($handle);

  sort($this->inputData);
 }




Next, after we have our input file data read into an array, we do some functional programming magic using array_map, array_reduce, and anonymous functions (lambdas).



Let’s look at array_map

In functional programming a map function takes an array and a *callback function* as input (and other *optional* arguments, but we’ll leave that out for brevity) and then performs a transformation (functionality/algorithm) specified in the callback function on every element in the array. The new values calculated for each element are added to a new array.



Now, for our heavy hitter… array_reduce

In functional programming a reduce function starts with an initial value and passes this initial value to the callback function. The initial value plus the first element in the array is passed to the callback function and the callback function’s functionality is performed.

After this callback functionality completes, the data returned is now passed to the callback function again. The functionality is performed again with the data return from the previous call, and the *second* element in the array. The data accumulates with each call.

This continues through each element in the array until the last element completes. When done a single value/object/etc (meaning the array was reduced to its last element) is returned.



Confused?

Simple pseudo code example:

 array intExample = [1, 2, 3, 4]

 result = reduce(intExample, "callback")

 function callback(previous, current)
 {
  previous *= current
  return previous
 }


The output of the above looks like:
2 = (1 * 2)
6 = (2 * 3)
24 = (6 * 4)

So the array [1, 2, 3, 4] was reduced to 24.

**NOTE: If no initial value is given, NULL is passed, and the reduce starts with the array’s first element as the initial value (like above).



Using both map and reduce together:

 $nameTotal = array_map(function($name, $index) {

   $charsTotal = array_reduce(str_split($name),
    function($runningCharTotal, $char) {

     // calculate value by offsetting from capital 
     // ascii char values to get sequential values
     $runningCharTotal += ord(strtoupper($char)) - 64;

     return $runningCharTotal;
    });

  // calculate a name total, which is
  // (name position * name's char total)
  return ($index + 1) * $charsTotal;

 }, $this->inputData, array_keys($this->inputData));



**NOTE: The callback function does not have to be defined inline, nor does it have to be an anonymous function. We could have just as easily defined the function:

Callback Function

function callBackAction($name, $index)
{
  // Do stuff...
}


And then passed the callback like:

$names = array("Name", "AnotherName");

array_map("callBackAction", $names);


However, it’s much easier to read (and cleaner) using an anonymous function instead.



**NOTE: Our parameters used in our callback functions are implicitly passed as arguments from the previously returned result (previous) from the callback.


Now… Why str_split?

Since array_reduce only takes an array as the datatype, we create one on the fly using PHP’s str_split.

str_split is just a quick (and dirty?) way of taking a string and storing each character as an element in an array, which is exactly what we want to do, in order to reduce on it.



Now… I know what you’re probably thinking..

WTF does the following mean? 🙂

$runningCharTotal += ord(strtoupper($char)) - 64;


Well….
Since we want the sequential value of each character in a name, we need a quick and non super hacky way of doing this.

To do this, we just use ord() to get the ASCII value of a character. However, before passing the value to ord() we first want to convert (or make sure) our character is uppercase using strtoupper(), and then offset it by 64.

Offsetting by 64 gives us the sequential value for that character.

For example, suppose we have the lowercase character ‘a’.

First we convert ‘a’ to the capital character ‘A’ using strtoupper(), and then pass ‘A’ to ord().

ord() will return ‘A’ in ASCII (under base 10), which equals 65.

Then if we offset this by 64, the character ‘A’ will give us decimal 1, and ‘B’ will give us decimal 2, and ‘C’ decimal 3, and so on…



Now let’s look at our return.
The return is straight forward.

We need an easy way to calculate our row value in our rowValue * nameValue = totalNameValue calculation. In order to do this, we pass our array to PHP’s array_keys(), which will give us access to each indice in our array during the reduce.



**NOTE: Just a heads up if you didn’t notice. PHP has yet another annoying quirk with it’s naming consistency of the parameters for the array_map and array_reduce signatures.

With array_map the callback is the first parameter, with the second the array, where as in array_reduce the array is supplied first, and then the callback second…. grrrrr….

>> I know.. I know..
>> *insert non PHP developers mocking tone of voice here*
>> Somethin.. Somethin.. PHP is the *worst* language.. Somethin.. Somethin..

>> *now insert PHP developers mocking tone of voice here*
>> Somethin.. Somethin.. Don’t care about the language.. I just use the right tool for the job.. Somethin.. Somethin..
😀



Calculating the Overall Total

  $total = array_reduce($nameTotal, 
   function($runningNameTotal, $item) {

    $runningNameTotal += $item;

    return $runningNameTotal;
   });

  return $total;
 }


Our final reduce is straight forward as well. The accumulator and each element perform a summation and the total returned is the solution.

Output the solution and that’s it! 😀

Securing Bitcoin in Cold Storage with Armory and Linux Mint

As Bitcoin increases in price, stories of unfortunate users being hacked becomes more common. This article will show you how to protect your Bitcoin from vulnerabilities by utilizing “Cold Storage”.

Disclaimer: This article is meant only as a guide to help you setup “Cold Storage”. Do your own due diligence to determine if this setup
accurately meets the level of security you require.


Remember: Always backup your private key(s). If you lose your private key(s) you lose your Bitcoins, this cannot be stressed enough.



This article will show you how to:

  1. Install Linux on a Netbook.
  2. Install an Armory wallet on your net book as a “Cold Storage” offline wallet.
  3. Install Armory on your online computer and show you how to safely monitor your “Cold Storage” (offline wallet) from your online computer.
  4. Show you how to send BTC to your “Cold Storage” offline wallet.
  5. Show you how to send BTC from your “Cold Storage” wallet to your online “Hot Wallet” (or another address)



Before we begin let’s define what “Cold Storage” actually is. Cold Storage is a Bitcoin wallet who’s private keys have never resided on a computer that was connected to the internet (at the time the keys were created), and it assumes if it did touch the network prior, the system was virus / malware free.

Let’s be honest, there has to be some level of trust.. I mean, unless you’re going to write your own OS, or your own kernel and then audit every piece of software that came with your base OS install (which is impossible) you have to have at least some level of trust for the OS you are installing.

I typically do an initial install, update the initial OS base packages, download and install Armory, and then once Armory is downloaded (and before the wallet is created), disable WIFI and Bluetooth for good.


What should I use to hold my Cold Storage?
Many people like to use cold storage by installing Linux on a USB drive and then use their online computer to boot between Operating Systems.

To me if you want true “Cold Storage”, then that’s a mistake waiting to happen. For “Cold Storage” I recommend using a separate dedicated computer like an old laptop or netbook. Netbooks are very cheap and it doesn’t have to be powerful.

Since for this article we will be installing Linux on a computer that isn’t very powerful (netbook) we should try to use a ‘light’ version.

For my cold storage I went with an XFCE version of Linux Mint. Linux Mint is an Ubuntu derivative, so if you’re familiar with Ubuntu / Debian then you should have no trouble with Linux Mint.


So with that out of the way..  Let’s begin! 😀
 




Step One: Install Linux on a Netbook


First download the XFCE version of Linux Mint in either 32-bit or 64-bit according to the type of netbook you have.

Next, if you’re using a netbook you’ve probably realized there’s no DVD drive. Since you probably don’t have an external DVD drive to plugin via USB, we need another solution.

Get a blank USB drive and download Unetbootin. Run Unetbootin and select the .ISO and select to save it to your USB drive.
unetbootin_f

When it’s done, go to your netbook, insert the USB drive and enter your netbook’s BIOS.

Depending on the computer and version of BIOS you have, the key to press on boot can be different. Some computers you press the DEL key and others its F2. Just google for how to enter BIOS for the version of your netbook.

After you’re in BIOS, look for the menu location to change your “boot sequence”. You want to be booting off the USB drive you just inserted, so make sure your USB drive is the first option in the computer’s “boot sequence”.

Now boot off your USB drive and choose the Default for Linux Mint. It should boot you up to the desktop where you should see an icon for an install script. Click the icon to run the Linux Mint install script, and follow the directions on installing Linux Mint to your Netbook’s hard drive.

**Note: I strongly recommend encrypting your netbook, so choose that option when asked and DO NOT lose your password.

After Linux Mint is installed, you can reboot and go back into BIOS and put your Netbook’s hard drive as the first option in the boot sequence, but this isn’t really necessary as long as there are no USB drives plugged in.

I usually leave the USB drive as the first option so I don’t have to change the sequence later for something else. Do whichever you prefer, this is strictly preference.
 


Update all Base Packages
Next we want to update all packages on the base Linux Mint install.

Linux Mint has an easy to use Network Manager in your task bar, so make sure you’re connected to the internet so we can update your OS packages.

To update and upgrade your packages, click on the bottom left “LM” icon in the desktop taskbar and bring up an XFCE Terminal Window (shell).

Update Linux Mint Base Packages


  $ sudo apt-get update
  $ sudo apt-get upgrade

Now wait until the system is done updating… Then reboot.

You should now have a fresh install of Linux Mint! 😀




Step Two: Install our Cold Storage Armory Wallet


Before we install Armory, we need to download and install some dependencies Armory needs in order to run. These are the dependencies that didn’t come with our initial Linux Mint install.
 

Install Armory Dependencies


 # sudo apt-get install python-qt4 python-twisted python-psutil


Now that the dependencies are installed and everything is ready to rock, it’s time to download Armory.

Change directories to your “Downloads” directory (inside your home directory) and download either the 32-bit or 64-bit version of Armory wallet.

The Armory version to download depends on what version of Linux Mint you installed. If there’s a newer version out, download the newest version instead.

Download Armory Wallet


  $ cd /home/YourUserNameHere/Downloads
  
  // For the 32-bit version
  $ wget https://s3.amazonaws.com/bitcoinarmory-releases/armory_0.91.99.8-beta_ubuntu-32bit.deb

  // If you're running 64-bit Linux Mint here's the 64-bit version
  $ wget https://s3.amazonaws.com/bitcoinarmory-releases/armory_0.91.99.8-beta_ubuntu-64bit.deb


From your Downloads directory install the Armory wallet.


Install Armory Wallet


  $ cd /home/[YourUserNameHere]/Downloads
  $ sudo dpkg -i armory_0.91.99.8-beta_ubuntu-32bit.deb

Congratulations! You’ve just installed Armory on Linux Mint.

Now……. Listen closely.
 



**Attention: From here on out your net book is to NEVER touch the internet!

Let me repeat that again.. From here on out your net book is to NEVER touch the internet!

If it does (and your wallet was created), by definition, you no longer have “Cold Storage”.
 



So with that out of the way, let’s go ahead and disable networking. While we’re at it, just because being paranoid with Bitcoin is a good thing 😀 we’re going to also disable Bluetooth.

Now we could start blacklisting drivers (and this is something you should do), but for this article we’re just going to shutdown Linux Mint’s Network Manager and put it into manual mode so it doesn’t start on boot and accidentally connect us online automatically.
 

Stop and Disable the Network Manager


  $ sudo bash
  # stop network-manager
  # echo "manual" | tee /etc/init/network-manager.override


Now we want to edit the Network Manager configuration file.

Edit the Network Manager Configuration


  # cd /etc/NetworkManager
  # vi NetworkManager.conf

  // Add the lines or edit the lines to:
  [ifupdown]
  managed=false

Verify that Network Manager is off


  # nmcli dev status

You should see the message


Error: Network Manager is not running.


Now to disable Bluetooth.

Disable Bluetooth


  # vi /etc/rc.local
  
  // add to the bottom
  rckill block bluetooth


OK…. Finally.. Let’s play with Armory! 😀

Click on the “LM” icon on the bottom left of your task bar and then click on “All”. You should see three shortcuts to Armory.

Click on Armory (offline) and then create your first wallet! 😀


Be sure to encrypt your wallet and DO NOT lose your encryption password!


Backups:
Next, you need to backup your wallet. Plug your printer into your net book and let’s make a “Paper Backup”.

From the Main Screen of Armory choose “Wallet Properties” -> “Backup this Wallet” and choose the option to “Make a Paper Backup”.

Follow the directions and print out your backup with your “Root Key”. This is needed to restore your wallet should something happen.


Now that you’ve made your paper backup, let’s also now create a Digital Backup.

Get a NEW USB drive and go back to “Wallet Properties” -> “Backup This Wallet”
and choose the option to “Make a Digital Backup”.

Be sure to save this to your NEW USB drive and NOT your net book’s hard drive.


Next, although it’s not necessary, you can also export your keys to your USB drive just to be safe.

Go back to “Wallet Properties” -> “Backup This Wallet” and choose the option to “See Other Backup Options”. Choose to “Export Key Lists” and save them next to your wallet’s digital backup on your new removable USB drive.


Create a Watch-Only Copy of your Cold Storage
Now it’s time to create a “Watch-Only Copy” of your Cold Storage wallet. This will allow you to watch the balance of your Cold Storage wallet on your online computer without any risk of your BTC being compromised.

From the main screen of Armory wallet click “Wallet Properties” and choose the option “Create Watch-Only Copy”.

Save this to ANOTHER removable USB drive. Anything is fine, as long as it is NOT the USB drive with your digital backup on it.

Note: That USB drive should be already put away in a safe place, and it (just like your Netbook) is to NEVER touch any computer with online access. I mean it..


If it’s not put away, do it now! 😛  Put it, your paper backup, your Cold Storage wallet’s encryption password, and your Net book’s encryption password away in a safe location.


OK, so now you should have your “Create Watch-Only Copy” file saved to another USB drive. This USB drive is fine to be plugged into your online computer since there are no private keys on it to compromise. So plug it into your online computer and lets get to work. 😀




Step Three: Install Armory on your Online Computer


Now we want to download and install Armory again, except this time we’re downloading it to our online computer. However, unlike on our Net book this version of Armory won’t be running in “Offline Mode”. This version of Armory will be online and download the full blockchain.

Download Armory for your online computer’s Operating System and then install it.

When it’s done installing, run Armory, but do not create a wallet yet. Choose the option to skip.


Next, follow the directions to install Bitcoin-qt THROUGH Armory.

After that is done, it’s time to import our “Watch-Only Copy” of our “Cold Storage” wallet.


On the Armory main screen and under the “Wallets” drop-down menu, choose the option to “Import or Restore Wallet”.

Import your “Watching-Only Copy” of your Cold Storage wallet that you saved on your USB drive.


Now wait, wait, and wait some more. Depending on your internet connection speed this will take a LONG time…

Once it’s done your Armory Dashboard will go from “Armory is Offline” to “Armory is Online!”

Your balance will change from “…” to “0.00000000” and you should be able to see “Connected” with the number of blocks.
online-watching-only-blank_f


Note: If you have a Solid State Hard drive for your main drive and it’s small, and you would like to have your wallet and data directory on a different drive, you can change the directory path under “File” -> “Settings”.
online-watching-only-change-directory_f


Note: If you’re like me and already had bitcoin-qt installed, you may have realized that Armory is trying to download the blockchain again.

If you stop Armory from downloading the blockchain and instead just point Armory to the location that your old bitcoin-qt already downloaded the blockchain to, you may have a problem.

What I mean by may is, it mostly works and it may work for you as well; however, I found that when I pointed Armory to the old blockchain and didn’t let Armory download the entire blockchain itself, I ran into the infamous bug of the progress bar infinitely freezing at 98% with 1.5 minutes left.

Although, fortunately when I started over and just let Armory download the entire blockchain, I never ran into that problem again.


OK! Now it’s time…

It’s now time to test out your “Cold Storage” by actually sending some BTC to your “Cold Storage” wallet’s receiving address.

Fill out the address for your “Cold Storage” wallet, the amount, the fee and send your BTC just like you would send a normal BTC transaction. I recommend first sending a small amount of BTC just to be sure everything is working properly.

Once you receive the BTC, you will see the balance of your “Cold Storage” wallet from your “Watch-Only Copy” on your online computer’s Armory. You can only watch (hence the name “Watch-Only” :P) and monitor the BTC transactions on your “Cold Storage” wallet from your online computer’s Armory.
online-watching-only-transactions-to-cold-storage_f


Note: Your true “Cold Storage” wallet (on your offline netbook) will not show your BTC balance because it never downloaded the blockchain since it’s “Cold Storage” and never allowed online (duh.. :P).


Now we’re at the last step.. Sending BTC from your “Cold Storage” wallet to another address.




Step Four: Sending Bitcoin from Cold Storage


Sending BTC from your “Cold Storage” wallet to another address can be tedious. It’s a THREE step inconvenient (on purpose!) process.

Remember we want any BTC going out of “Cold Storage” to be difficult, time consuming, and have physical aspects involved. That’s the whole point of “Cold Storage”! 😀



The Three Steps Include:

  1. First, on your online wallet using your “Watch Only Copy” of your Cold Storage wallet you will create an “unsigned transaction” and save it to a USB drive.
  2. Second, you transfer that “unsigned transaction” to your Cold Storage (offline netbook) via your USB drive and sign the transaction with your offline Armory wallet, and save this now “signed transaction” back on your USB drive.
  3. Third, you replug your USB drive back into your online computer and with the now “signed transaction” on your online computer, you broadcast this transaction to the network.



When you’re ready to send BTC from your Cold Storage, go back to the main screen of your Armory Wallet on your ONLINE computer and click “Offline Transactions”.

Next, click “Create New Offline Transaction” and fill out the address you want to send to, the amount, the fee, optional comment, and make sure the check box for “Create Unsigned” is checked and click continue.

Save this “Unsigned Transaction” file to the same USB drive you transferred your “Watching Only Copy” of your Cold Storage Wallet to.


Next, transfer the USB drive to your offline net book.

On your net book’s offline Armory wallet, click “Offline Transactions” again and then click “Sign” and save the signed transaction back to your USB drive.

Next, unplug the USB drive from your netbook and then replug your USB drive to your online computer.

Finally, now on your online computer’s Armory, click “Offline Transactions”, but this time we want to choose “Broadcast”.


And that’s it!! 😀

Congratulations, you’ve just created a Cold Storage solution for BTC!


Have fun! 😀


Creating a Vagrant Base Box with CentOS 6.5, Puppet and Virtual Box

Vagrant is a great tool for developers to use their favorite IDE, within their favorite OS, all while using their favorite VM.
Doing so lets you work in a development environment that is identical to where your application will be deployed.

Puppet is a popular provisioning tool used to duplicate the configuration of systems quickly. Automated system administration. 😀
This article will show how to create a Vagrant Base box with CentOS 6.5 (64-bit), install Puppet Agent and configure it to sync up to your Puppet Master.

Now if you’re thinking… Why would we want to do this when there are tons of base boxes already available?
There are and that’s true, however creating your own allows you to customize what you truly need and don’t need for your team, and also be certain on what’s really installed.

Note: This article assumes you’ve already installed CentOS 6.5 as a Virtual Box VM, the correct Guest Additions for your Virtual Box version, and are already running a Puppet Master.

This article will show you:

  • How to create a Vagrant CentOS 6.5 base box from an already installed CentOS 6.5 VM Image.
  • How to add your newly created base box to Vagrant in order to use it.
  • How to initially provision Vagrant to connect to your company’s Puppet Master.

First we need to install the right version of Vagrant for your OS distro.

Next, we need to boot up your already installed CentOS Virtual Box Virtual Machine.
VBox_f

Next, we’re going to install Puppet Agent on our freshly installed CentOS VM. Our goal (when we do our initial Vagrant provision) is to have Puppet Agent already installed on our base box. This way, we can use Puppet Agent to create our Vagrant environment according to what our dev team’s configuration “node(s) profile” on the Puppet Master is. Puppet Agent will sync up with our Puppet Master to tell us which packages and configurations are needed to install for the Vagrant environment.

Note: Configuring Puppet Master is beyond the scope of this article, but there are many tutorials out there to help.

OK, with our VM in Virtual Box running, login and install Puppet Agent.
Vagrant-login_f

Install Puppet Agent


# sudo yum install puppet

Next, we want to be able to use Puppet’s “file_line” function. We’re doing this in order to modify Puppet Agent’s config file with our Puppet Master server location.
We could of manually edited it on the VM before creating our Base Box, but this way gives much more flexibility. You could have more than one team, with each using different Puppet Masters that have different development configurations.

Note: Puppet’s “file_line” function is usually only used for minor file modifications. If you have config files that need to be modified according to a much more complex use case, then the tool you want to use is Augeas.

Install Puppet’s Stdlib module on the VM


# puppet module install puppetlabs-stdlib

Now that those are installed, make sure your VM has everything installed that you initially want (puppet agent, initial packages, hostname, specific dev user/group/permissions, etc), then it’s time to create a Vagrant Base Box from our VM. Don’t worry if you’ve forgot something, you can always go back to the original VM and modify it. Meaning, this won’t modify your VM, it just creates a copy.

Now shutdown your VM. On your host OS we’re going to create the base box.

Create a Vagrant Base Box from your CentOS Virtual Box VM


// --output: the name your base box will be
// --base: your CentOS VM name
# vagrant package --output CentOS-6.5-x86_64_puppet.box --base CentOS-6.5-x86_64

This creates a Vagrant base box file in Vagrant’s box directory named CentOS-6.5-x86_64_puppet.box

Next we need to add this base box to Vagrant so we can use it.

Add the Base Box to Vagrant


# vagrant box add CentOS-6.5-x86_64_puppet CentOS-6.5-x86_64_puppet.box

We can view our base boxes by asking Vagrant.

List the current base boxes


# vagrant box list

vagrant-list-base-boxes_f

Note: I’m storing my base boxes in a custom directory I created just for them that’s off of my SSD drive (since many base boxes can potentially take up a lot of room). Initially Vagrant stores them on the main drive. This can be changed by modifying the default path in your env variables.

Now it’s time to actually *use* Vagrant. 🙂

Create a project directory called “testvagrant” on your host machine and cd to it.

Create and cd to the “testvagrant” directory


# mkdir testvagrant
# cd testvagrant

Next, we’re going to initialize a vagrant environment.

Create Vagrant Env


# vagrant init

This will create a Vagrantfile in the “testvagrant” directory. We’re going to edit this file to setup Vagrant and do our provisioning with Puppet.

Inside our “testvagrant” directory we’re going to create Puppet’s standardized directory tree structure.

Note: This isn’t necessary, it’s just good habit. 🙂

Create the directories


testvagrant
-- puppet
 -- manifests
  -- site.pp
 -- modules
  -- init
   -- manifests
    -- init.pp

Now we want to edit init.pp and add

Add to init.pp


class init {
    # config Puppet Agent (preinstalled on BaseBox)
    # Chaining Arrows (ordering) to prevent race conditions
    file { '/etc/puppet/puppet.conf':
        ensure => 'present',
    } ->
    # server is the location of the Puppet Master domain
    file_line { 'Configure Agent - puppetmaster server':
        path   => '/etc/puppet/puppet.conf',
        ensure => 'present',
        line   => '    server = puppet.ltdev',        
    } ->
    file_line { 'Configure Agent - report':
        path   => '/etc/puppet/puppet.conf',
        ensure => 'present',
        line   => '    report = true',        
    } ->
    file_line { 'Configure Agent - plugin sync':
        path   => '/etc/puppet/puppet.conf',
        ensure => 'present',
        line   => '    pluginsync = true',        
    }
}

Note: Rememeber, if you have a config use case that’s complicated, use Augeas.

Now we want to edit site.pp and add

Add to site.pp


node default {
    include init
}

Now that our Puppet Agent config files are ready to be modified we need to setup Vagrant and tell it how to provision. We do this by editing our Vagrantfile.

Edit Vagrantfile configuration


# This is the name of your base box
config.vm.box = "CentOS-6.5-x86_64_puppet"

# Our VM will be running our web server on port 80 but forwarding to our host OS on port 8080
config.vm.network "forwarded_port", guest: 80, host: 8080

# This is the directory that will be in sync on your host with your guest (VM) default is 
# /vagrant which is the root directory for that vagrant init (where your Vagrantfile is located)
# Note: I am using Samba for performance reasons with Symfony 2, however try the default 
# sync first.
config.vm.synced_folder ".", "/vagrant", type: "smb"

# Provision with Puppet
config.vm.provision "puppet" do |puppet|
    puppet.manifests_path = "puppet/manifests"
    puppet.manifest_file  = "site.pp"
    puppet.module_path = "puppet/modules"
end

Now its time to fire Vagrant up and provision! *cough* If everything went correctly.. 🙂

Start Vagrant


# cd testvagrant
# vagrant up

vagrant-up_provision_f1

And this is the modification Puppet did by using “file_line” to our /etc/puppet/puppet.conf

puppet-conf_f

Note: Vagrant only provisions on the first “vagrant up”, however you can force it to provision again if you need to by

Force Vagrant Provision


# vagrant up --provision

That’s it. If you need to you can reference how to use Vagrant here.
Have fun! 😀

Symfony 2 and AngularJS: Server-side rendering of form data

Now that Javascript frameworks are starting to mature and be used by a lot more companies than a few years prior, the question often comes up: How can we use our current server side form rendering while at the same time populate our client side framework with that initial data?

Well, let’s first talk about the pros and cons and then I’ll give a brief example on how you can easily do this with Symfony 2 / Twig and AngularJS.

There’s basically two schools of thought. The first is the camp that believes the client side framework should do all rendering / populating of form data. This means that when a user loads your page, the client does an AJAX call to populate the initial data after the UI has already loaded. This school of thought definitely has some merit, especially from a business point of view because more times than not this makes the user experience faster. However, there’s also a downside with slow data loads when users load your page with low end systems / mobile devices and are waiting around with a blank application, no content, and a confused look on their face. This could (and many times does) violate the cardinal rule of don’t annoy your customers. User annoyance is a for sure way to lose a sale. There is also the issue of not being able to take full advantage of server side optimizations.

The second is the camp (which… *cough* *cough* I happen to belong to) is letting your initial data load with the server side rendering, and then initializing the client side framework with it. When your page loads, your users aren’t sitting around with a WTF feeling, because if your page is loaded, your data is there. The reason I say this is because we’re at a point with the internet that your average user understands a page load vs a non page load, but they definitely don’t have any concept of well I know the app loaded just fine, I’ve just gotta wait around a few seconds until the JSON response returns. Even when the content shows up, your customer more often than not thinks the application is some how broken, loses trust, and moves on. And this is definitely what you don’t want.

The downside to this approach is unfortunately many popular Javascript frameworks including AngularJS (as of this post) view this as going against best practices. My view and others I work with view server side rendering of initial data and seeding the client side framework with it as the best of both worlds. In fact, Twitter has even changed their opinion when it comes to this as well.

OK, enough with the rambling… Let’s see some code! 😀


NOTE:

This article will assume you already have an understanding of Symfony 2 / Twig, how to override in Twig, and at least a basic understanding of what AngularJS directives are and how they work.

On our page load, we pass our form field data to AngularJS via assigning an AngularJS directive as an attribute and let AngularJS repopulate our fields. We add our init directive to the form by overriding our block’s field widget. We don’t add it via attribute in our Form class before rendering, why is beyond the scope of this article. Adding the directive will give control of our rendered form data to AngularJS and then we can continue to work with it in AngularJS as we normally would.

First create a twig file to override and add


{# Content\ProfileBundle\Resources\views\Form\fields_angularjs_init.html.twig #}

{# override the forms media widget #}
{% block _content_profile_userGallery_media_widget %}
{% spaceless %}
    {% set attr = {'data-ng-model': 'userGallery.media', 'data-initialize-directive': ''} %}
    {{ block('form_widget') }}
{% endspaceless %}
{% endblock _content_profile_userGallery_media_widget %}


Next create an AngularJS directive and add


// Content\ProfileBundle\Resources\public\js\directives.js

// change to the way your app loads directives
profileAppDirectives.directive('initializeDirective', function($parse) {
    return {
        restrict: 'A',
        require: '?ngModel',
        scope: false, // change for your scope (you need to be in the correct scope)
    
        // ...

        // the linking function will assign to your init directive 
        // as an attribute in fields_angularjs_init.html.twig
        link: function(scope, element, attrs) {
            // ...

            $parse(attrs.ngModel).assign(scope, attrs.value);
    
            // ...
        }

        // ...
    }
}

You can also add attrs.value, attrs.checked, etc. and checking conditions for the different form fields you’re dealing with.

That’s it, have fun! 😀

Phusion Passenger on Apache 2.4: ‘undefined symbol: unixd_config’

If you or your company has come across this error while trying to start Apache 2.4 with Passenger, don’t worry there’s an easy fix. Your Passenger module is compiled for the wrong version of Apache, usually 2.2. Apache 2.4 has many changes and unixd_config has been renamed to ap_unixd_config in version 2.4. The fix is to recompile the Passenger module against your correct Apache version.


Verify your APXS2 Environment Variable location
First you need to make sure your APXS2 Environment Variable is pointing to the correct Apache version path.

Usually located at


cd /etc/sbin
ls | less

apxs_f

Verify the apxs location with what’s set as APXS2 in your environment variables.


env

If the path is not correct, update it (only will be for this shell)

Update for your shell session


export APXS2=/location/to/apxs



Next locate where your Apache 2.2 mod_passenger.so module is located.

Usually located at


/usr/lib/ruby/gems/1.x/gems/passenger-4.0.x/buildout/apache2/mod_passenger.so

You can also verify where Apache is loading it from by checking your PuppetMaster Vhost configuration file.

Usually located in Apache’s conf.d directory


vim /etc/httpd/conf.d/puppetmaster.conf

After you have located it, rename your Apache 2.2 mod_passenger.so module to something else. You don’t want it to get overwritten in case you still want to use Passenger with your old Apache version.

Rename Apache 2.2 mod_passenger.so


cd /usr/lib/ruby/gems/1.x/gems/passenger-4.0.x/buildout/apache2
mv ./mod_passenger.so ./mod_passenger_httpd22.so



Now all that’s left is recompiling mod_passenger.so against Apache.2.4.

Recompile Passenger


passenger-install-apache2-module

passenger-install_f

Now follow the directions for the recompile.

After the recompile, verify the LoadModule path is correct in your PuppetMaster.conf VHost config file.

If it is, just start Apache and you should be good to go.

Have fun! 🙂

Installing HHVM with Apache 2.4 on CentOS 6.5 (64 bit)

This is for those of you who love being on the bleeding edge of technology like me. This will be a brief introduction to installing Apache 2.4 and Facebook’s HHVM (Hip Hop Virtual Machine) in order to increase web application performance.

Apache 2.4 is the newest iteration of Apache’s web server with multiple performance improvements and Facebook’s HHVM is the new kid on the block that brings massive performance gains to PHP. HHVM achieves this by compiling PHP into bytecode, which is then translated into machine code by HHVM’s JIT (Just in Time) compiler. When using HHVM, this also gives the ability to use Facebook’s new statically typed language called HACK.

HHVM also works with most of PHP’s popular frameworks. If you work with popular enterprise level frameworks like Symfony 2, this can be an amazing asset.


First we need to prepare the install process by adding a few repositories for yum to use. Since CentOS 6.5 (as of the time of this post) doesn’t contain Apache 2.4 in their base or epel repositories, we need to look for another option. We could compile from source, however Remi Collet and Jan Kaluza from Red Hat have created a RHEL repo httpd24-epel that contains Apache 2.4 that is perfect for our needs. This repo installs Apache 2.4 in /opt. View why here.


For HHVM we have the same couple of options. We could either build it from source, or we can use Naresh Kumar’s wonderful repo called the Hop 5 Repo.

Using these repos is the best choice since we can manage our Apache 2.4 and HHVM installs with our package manager and not have to worry about future problems.


— PREPARATION —

Go to the repo directory

cd /etc/yum.repos.d

Add the Remi Repo

sudo wget http://repos.fedorapeople.org/repos/jkaluza/httpd24/epel-httpd24.repo

Add the Hop 5 Repo

sudo wget http://www.hop5.in/yum/el6/hop5.repo


— INSTALL PROCESS —

Install Apache 2.4

sudo yum install httpd24-httpd httpd24-httpd-devel httpd24-mod_ssl

This will place Apache 2.4 under /opt.
See why here

Install HHVM

sudo yum install hhvm

hhvm_install_f


— CONFIGURATION PROCESS —

Configure Apache
This article uses a VHost and assumes you already know how to setup one for Apache, however a Virtual Host is not necessary for HHVM.

Edit httpd.conf

cd /opt/rh/httpd24/root/etc/conf
vim httpd.conf

Ensure this line is not commented out

IncludeOptional conf.d/*.conf

Configure a Virtual Host for Apache

Go to the Apache 2.4 config directory

cd /opt/rh/httpd24/root/etc/conf.d

Create a Virtual Host config file as root (if non existent)

vim httpd24-vhosts.conf

Add the following lines

<VirtualHost *:80>
  ServerName hhvmtest.dev
  DocumentRoot /var/www/html/hhvmtest
  ErrorLog logs/hhvmtest.dev-error_log
  CustomLog logs/hhvmtest.dev-access_log common

  # where HHVM is running   # use either Proxy Pass or ProxyPassMatch   # ProxyPass routes all traffic to FastCGI   ProxyPass / fcgi://127.0.0.1:9000/var/www/html/hhvmtest   # ProxyPassMatch regular expression routes only PHP files   ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/html/hhvmtest/$1
  <Directory /var/www/html/hhvmtest> # relaxed permissions for testing     AllowOverride all     Options -MultiViews     Require all granted   <Directory> </VirtualHost>


— TESTING —

Start HHVM as a server in FastCGI mode in the background (run as root or sudo it)

/usr/bin/hhvm --mode server -vServer.Port=9000 -vServer.Type=fastcgi &

Verify HHVM is running and PID

ps aux | grep hhvm

hhvm-running

Start Apache

sudo service htttpd24-httpd start

Create Document Root

cd /opt/rh/httpd24/root/var/www/html
mkdir hhvmtest

Create index.php

cd /opt/rh/httpd24/root/var/www/html/hhvmtest
vim index.php

Add the following lines


 <?hh echo 'test ';
  $test = 2 + 2;
  echo  $test;
  echo phpinfo();

Create index.hh

vim index.hh

Add the following lines


 <?hh echo 'test ';
  $test = 2 + 2;
  echo  $test;
  echo phpinfo();


Now open your browser and go to

http://hhvmtest.dev/index.php

If everything goes correctly you should see the string

test 4 HipHop

Now open your browser and go to

http://hhvmtest.dev/index.hh

If everything goes correctly you should see the string

test 4 HipHop

When you output

phpinfo();

You should see the string 'HipHop'.

HHVM returns the string HipHop when you output phpinfo.



Also verify HHVM is working for php tags by changing in both index.php and index.hh

<?hh

to

<?php 


If you want to run HHVM on system boot. Either create an init bash script or just add the above HHVM line to rc.local

Go to rc.local

cd /etc/rc.local
vim rc.local

Add the following line to the bottom of rc.local

/usr/bin/hhvm --mode server -vServer.Port=9000 -vServer.Type=fastcgi &

That’s it enjoy! 😀