Vagrant Tips for Windows

| Comments

Here are some tips to improve the day-to-day Vagrant tasks on a Windows machine.

  • Saving diskspace
  • Using a better terminal
  • Using a better text editor

Moving the Vagrant home folder to another disk

Vagrant puts its boxes by default in your home directory (~/.vagrant.d). But it can fill up diskspace really quickly. Especially if you are creating Windows VM’s. So what you want to do is edit the VAGRANT_HOME variable and give it a value which suits your needs (to a cheaper or bigger disk). Here’s the Powershell command:

1
[Environment]::SetEnvironmentVariable("VAGRANT_HOME", "D:\vagrant_home", "User")

Using Cmder as an alternative terminal

OK. Microsoft is trying but they will never succeed to overrule the power of a Linux terminal and commandline. But with Cmder you can simulate the Linux experience rather decently. And if you decide to use the slightly bigger msysgit version of Cmder, you will have all Unix commands ready in PATH so that you can git init or cat instantly on every machine. Yay! git

Using Sublime to edit the Vagrantfile

I love Sublime as a text editor. Install it with Chocolatey and then add subl.exe command to your path. Here’s (again) a way to do that with Powershell:

1
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";%ProgramFiles%\Sublime Text 3", [System.EnvironmentVariableTarget]::Machine)

Now you can go to Cmder, cd to you vagrant machine folder and type:

1
subl Vagrantfile

Now you can work from the terminal with Sublime instead of juggling with Notepad instances.

Add Powershell syntax colors to Sublime text

In Sublime Text:

  • Press Ctrl + Shift + P
  • Select ‘Install Package’
  • Select ‘PowerShell’

Debian Sid on the Bare Metal (Thinkpad X250)

| Comments

Let’s install Gnome 3.16 (since 3.18 is not yet in the repo’s) on the latest Debian and see if we can get productive with programming and labs (Javascript development and Vagrant).

Download the netinst iso and burn it

The Debian installer iso’s typically do not include all drivers needed, which is a pain if you need to get an Intel nic working like me on my Thinkpad X250. Luckily, you can download iso’s which contain the non-free firmware. So if you are not morally against the act of utilizing non-free software this is the easiest way to go.

Download the non-free testing netinst iso from here. Burn it to USB since we are going the bare metal way. If you are on a Mac or on Linux the easiest way is by issuing a ‘dd’ command. First check with ‘fidsk -l’ which pointer the USB device has on your system. In my case it is ‘sdd’.

1
2

sudo dd if=firmware-testing-amd64-netinst.iso of=/dev/sdd

Boot it and install

I still needed to add some extra firmware for my Intel wireless chips. I downloaded them from kernel.org, extracted the files on a USB and inserted it in the laptop. The install process continued and bite me. I’m already working on my new Debian system with Gnome 3.16.

hostname

Since Gnome 3.16 is already eye candy litte adjustments are needed.

version

Install the basics

This is my usual first round of commands after a new install:

1
2
3
4
su
apt-get update
apt-get upgrade
apt-get install vim visudo git gitk linux-headers-$(uname -r) chromium gdebi wget curl build-essential

After that I can add myself to the sudoers with visudo:

1
2
su
visudo

visudo

So now the base is ready. In the next post I will add more details about the development tools I use.

The Pipeline

| Comments

Yesterday we ended with a developerish Powershell script:

1
2
3
4
5
6
$pst = Get-ChildItem -Path 'c:\' -Include '*.pst' -Recurse -ErrorAction SilentlyContinue

foreach ($f in $pst) {
        $name = $env:USERNAME + '-' + $f.Name
        Copy-Item $f.FullName -Destination "C:\temp\pst-share1\$name"
    }

It loops over all objects in the $pst array. Foreach item in the $pst array, it generates a new file name and the item is copied to another folder with the new file name.

There is another way to accomplish just this, by using the pipeline and instead of foreach, we will be using Foreach-Object.

1
2
3
4
 $pst | ForEach-Object { 
        $name = $env:USERNAME + '-' + $_.Name
        Copy-Item $_.FullName -Destination "C:\temp\pst-share2\$name"
   }

Each method will yield the same result. Foreach-Object is a bit slower though, and has the ‘$_.’ notation which is typically Powershell. I prefer the first method because it feels more natural to me. But it does not mean I will not use the pipeline.

What about the pipeline?

In Powershell you can pass an array of objects as input to another function (cmdlet). This is really cool. With DOS, Vbscript and other scripting languages, there are only 3 types of interfaces:

  • STDIN
  • STDOUT
  • STDERR

..which accept a textstream as input and as output. Powershell accepts objects as input and output. Using objects as input and executing stages within the PowerShell runtime eliminates the need to serialize data structures, or to extract them by explicitly parsing text output.

These objects expose a set of properties and methods so you can do cool stuff with it. Most of the time, we also want to treat a collection of objects like a database table and query it. For this purpose, there are functions like

  • foreach-object
  • compare-object
  • where-object
  • select-object
  • sort-object

So I can create an array of file system objects like this:

1
Get-Childitem $env.homepath\dropbox -Recurse

Or

1
$env.homepath\dropbox | get-ChildItem -Recurse

Which will return an array of objects of all my Dropbox data. Suppose I want to filter the .docx files and copy them all to c:\temp:

1
Get-ChildItem $env:HOMEPATH\Dropbox -Recurse | Where-Object { $_.Name -like "*.docx*" } | Copy-Item -Destination c:\temp

Of course, you can make all kinds of smart collections, e.g. only copy the docs which have a LastAccessTime before 2008 or so (remember, you can query all properties and methods with get-member).

So this article should explain the Powershell pipeline and why it is cool. Next, let’s learn about the objects and how you can create custom ones for your system reports.

Powershell Without Google

| Comments

At work I find myself using Powershell a lot. Here are a few tips to use Powershell without Googling all the time.

Suppose you want to check if there are any PST’s on a harddrive and let’s pretend you know nothing, just like Jon Snow.

Find out what cmdlets are available with Get-Command

Obviously we need to recurse directories to see if there are any files with a .pst extension. So let’s see if there’s a cmdlet.aspx) with ‘dir’ in it.

1
2
3
4
5
6
7
PS C:\Users\Jacqueline> get-command '*dir*'

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           chdir -> Set-Location
Alias           dir -> Get-ChildItem
Alias           rmdir -> Remove-Item

Get-ChildItem looks like the cmdlet we need. Let’s see how it works with the help files.

Get the help files

The problem with command line interfaces: you can’t ‘guess’ which command to use and what the parameters are. So you will need to read the help files. Unfortunately, the help files are in c:\windows\system32, so you need to run the command as an Administrator.

You can only update-help once a day unless you use the -Force parameter.

So open a console as an Admin and run:

1
PS C:\> update-help -UICulture en-US -force

Needless to say an Internet connection is required. What if you don’t have one?

Saving help to an alternate location

In that case you can save the help files on an alternate location or on a netwerk share and then update-help.

1
PS C:\> save-help -DestinationPath C:\powershell\help2 -force -UICulture en-US

and then (as an Administrator):

1
PS C:\> Update-Help -SourcePath C:\powershell\help2\ -force -UICulture en-US

Now you can use the help files.

Using the help

1
PS C:\> Help Get-ChildItem

Will display all there is to know about Get-Childitem. Like parameters and what kind of parameters it accepts (string, arrays and so on). If you scroll down the help you get to see the remarks:

1
2
3
4
5
REMARKS
    To see the examples, type: "get-help Get-ChildItem -examples".
    For more information, type: "get-help Get-ChildItem -detailed".
    For technical information, type: "get-help Get-ChildItem -full".
    For online help, type: "get-help Get-ChildItem -online"

The -examples are very convenient if you want to have a quick solution.

So now we can play a bit with Get-ChildItem. Let’s discover its syntax:

1
2
3
4
5
6
7
8
9
10

SYNTAX
    Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Exclude <String[]>] [-Force] [-Include <String[]>] [-Name] [-Recurse] [-UseTransaction
    [<SwitchParameter>]] [<CommonParameters>]

    Get-ChildItem [[-Filter] <String>] [-Exclude <String[]>] [-Force] [-Include <String[]>] [-Name] [-Recurse] -LiteralPath <String[]> [-UseTransacti
    on [<SwitchParameter>]] [<CommonParameters>]

    Get-ChildItem [-Attributes <FileAttributes]>] [-Directory] [-File] [-Force] [-Hidden] [-ReadOnly] [-System] [-UseTransaction] [<CommonParameters>
    ]

Here we see it accepts a -Path parameter which is an array because there are brackets: String[]. So we can input multiple search locations by creating an array of locations.

Now type:

1
get-help array

And you will see you get very valuable information about how to create an array. I could create an array like this:

1
$search = @($env:HOMEPATH,"c:\temp")

Notice the quotes around c:\temp because we’re dealing with strings. The $env:HOMEPATH is already a variable which returns a string.

We can test the array like follows:

1
2
3
4
PS C:\Users\Jacqueline> $search = @($env:HOMEPATH\Dropbox,"c:\temp")
PS C:\Users\Jacqueline> $search
\Users\Jacqueline\Dropbox
c:\temp

Now we can do a search ilke this:

1
get-childitem -path $search -Recurse -Include "*.pst" 

I don’t want to look at all those red error messages, so let’s suppress them:

1
get-childitem -path $search -Recurse -Include "*.pst" -ErrorAction silentlycontinue

And now for real:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PS C:\Temp> get-childitem -path $search -Recurse -Include "*.pst" -ErrorAction SilentlyContinue


    Directory: C:\Users\Jacqueline\Dropbox\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         5-4-2013     18:33      211305472 jacqueline.pst


    Directory: C:\temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        26-7-2015     13:12        5242880 archive.pst
-a----        26-7-2015     13:12        5242880 old.pst

Let’s put the result in a variable, like so:

1
$pst = Get-ChildItem -Path "c:\" -Include "*.pst" -Recurse -ErrorAction SilentlyContinue

Investigating $pst with Get-Member

Like Get-Command and Get-Help, Get-Member is a really import cmdlet you should know about. With Get-Member we can investigate which properties and methods are available. How can I actually write a script or type a command-line command without having to memorize every object model found on MSDN?

Once you connect to an object you can pipe that object to Get-Member; in turn, Get-Member will enumerate the properties and methods of that object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

PS C:\Temp> $pst | Get-Member

   TypeName: System.IO.FileInfo

Name                      MemberType     Definition
----                      ----------     ----------
Mode                      CodeProperty   System.String Mode{get=Mode;}
AppendText                Method         System.IO.StreamWriter AppendText()
CopyTo                    Method         System.IO.FileInfo CopyTo(string destFileName), System.IO.FileInfo... Create                    Method         System.IO.FileStream Create()
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
CreateText                Method         System.IO.StreamWriter CreateText()
Decrypt                   Method         void Decrypt()
Delete                    Method         void Delete()
Encrypt                   Method         void Encrypt()
Equals                    Method         bool Equals(System.Object obj)

--MORE

Scrolling down the list you will notice a Method GetType. Let’s run that:

1
2
3
4
5
PS C:\Temp> $pst.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

So $pst is an Array (we already knew that..) but what is in the array?

1
2
3
4
5
6

PS C:\Temp> $pst | ForEach-Object { write-host $_.GetType()}
System.IO.FileInfo
System.IO.FileInfo
System.IO.FileInfo
System.IO.FileInfo

So, we’ve got an array full of FileInfo objects. Each objects has a set of methods and properties, which we can query by using Get-Member.

Fun stuff to do with arrays

Powershell and any other scripting language is all about gathering input, do stuff with this input and generate the output. You can send the objects through the pipeline and sort them and query them.

So let’s do that with the $pst array.

  • Sort the array alphabetically: $pst | Select-Object name,lastwritetime,fullname | Sort-Object lastwritetime
  • Only show the pst with my name in it: PS C:\Temp> $pst | Where-Object {$_.Name -match "jacq*"}

Copying and renaming the PST’s to another location

Let’s copy the PST’s to another location and rename then so some admin can import the PST into a mailbox.

Just copying is not that hard:

1
$pst | Copy-Item -Destination C:\Temp\pst-share

But if I want to rename the file as well I have to be a bit more ‘developerish’:

1
2
3
4
foreach ($f in $pst) {
    $name = $env:USERNAME + "-" + $f.Name
    Copy-Item $f.FullName -Destination "C:\temp\pst-share\$name"
  }

Let’s debate on this script tomorrow.

Hello Again

| Comments

Internet is now mainstream. Social Media is for the masses. Living a digital life is the norm.

Windows is not longer the default OS for the people. People use tablets, smartphones and they run Android and iOS.

Coding is easier. It’s just JavaScript.

Infrastructure is a piece of cake with Docker.

Everything is connected (the Internet of Things).

I think I want to break away from the digital life and grow my own vegetables.

alt text

Unity Is Ok

| Comments

During my quest to find the perfect Linux distribution I must admit I came to like Ubuntu. Sorry RMS, but I think Ubuntu is quite OK.

Here’s why.

  • Easy dual monitor setup
  • Easy printer and scanner installation
  • Eyecandy
  • PPA
  • Sound works out of the box
  • Unity is keyboard friendly
  • You can turn off the ‘include online search results in the Dash

The Dash by the way makes me very productive. Just hit the superkey and the first character of the application you want to start. This means there’s no need to configure keyboard shortcuts. Hell, there’s no need to configure anything at all. It works and the defaults are good. I’m in productive mode right away.

alt text

Debian on the Bare Metal

| Comments

Today I took the plunge and installed Debian instead of Windows 8.1 on my main machine. Indeed, on the bare metal.

I first checked if my hardware compatibility. There’s an awesome (portable) tool called HWiNFO you can run and check what hardware is inside your computer. Then you can check if there’s Linux support. The most important hardware pieces are video cards, networking hardware and audio.

For instance, I happen to own an Intel 4000 HD Graphics adapter. I had to compile and install the drivers. Lucky for me, the README files were quite good.

Tips for optimizing graphics:

  • Install xrandr to enable extended mode on your dual monitor setup

  • Install gdm3 (however I’m not sure if this did the trick that my display suddenly became beautiful.

desktop

For Evernote and Spotify are no Linux packages, so I installed them as addins in Chrome. It makes them look like they are native. Suddenly I came to understand the importance of Chromebooks!

Next week I get to order a MacBook Pro (courtesy to my boss). Then Windows has disappeared form all my computers, except the virtual ones I need for work (and Visual Studio).

XFCE4 on Debian Netinstall (Jessie) in VMware Workstation

| Comments

I have to admit that trying out Linux Distributions is one of my guilty pleasures. I enjoy configuring my desktop just the way I want it and to be in full control. Working in the terminal makes me very productive and now that I’m getting the hang of Vim it’s totally addictive. I’ve tried Vim (and NERDTree) on Windows 8.1 but it’s just not the same. For instance, if you drop to a shell the dosbox opens whereas I prefer to stay in the same terminal.

I was very impressed by the simplicity of Crunchbang that I decided to try and create my own Linux distro from scratch. This is what I did.

You can download Debian Jessie here.

Install Jessie with the options that suit you. It becomes critical at the Software selection part. Make sure you select only the Standard System utilities:

installer

Then finish the installation and logon as root. These are the first apps to install. Then type: visudo:

1
2
3
$apt-get install sudo vim curl build-essential linux-headers-$(uname -r) sudo

$visudo

I’m going to add my personal logon account to the sudoers, like this:

visudo

If you hit ‘ctrl-o’ it will ask you to which file to save. Just accept what it suggests and press enter.

It’s also wise to disable the annoying beep that you get to hear by each and every typo:

1
vim /etc/inputrc

Uncomment ‘set bell-style none’

1
vim /etc/vim/vimrc

Add ‘set vb’. Also enable syntax here by uncommenting: syntax on.

Now logoff and logon with your user account, because now you can use sudo.

Enable free and contrib repo’s and install vmware-tools

Open /etc/apt/sources.list and change it as follows.

1
2
3
4
$ sudo vim /etc/apt/sources.list
:%s/main/main contrib non-free

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

Insert the Vmware tools CD and mount it as follows:

1
2
$ sudo mkdir /mnt/cdrom
$ sudo mount -t iso9660 -o ro /dev/cdrom /mnt/cdrom

Now the Vmware tools are in /mnt/cdrom and you can install them as usual.

Enable fancy dircolors and syntax coloring in vim

1
$ vim ~/.bashrc # uncomment dircolors

Install XFCE

1
2
3
4
$ sudo apt-get install xorg xfce4 lightdm wicd gdebi
$ sudo apt-get install xfce4-goodies
$ sudo apt-get install git gitk
$ sudo apt-get install gtk2-engines-murrine

You can also combine this to one command.

Restart and login your new XFCE4 desktop.

Eyecandy

Go to Settings –> Appearance and enable anti-aliasing under the font tab:

appearance

Enable transparent label text background on the desktop:

1
$ vim ~/.gtkrc-2.0

Add the following text:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
style "xfdesktop-icon-view" {
XfdesktopIconView::label-alpha = 0
}
widget_class "*XfdesktopIconView*" style "xfdesktop-icon-view"

# You can also change the font colors.

style "xfdesktop-icon-view" {
XfdesktopIconView::label-alpha = 0

base[NORMAL] = "#ffffff"
base[SELECTED] = "#5D97D1"
base[ACTIVE] = "#5D97D1"

fg[NORMAL] = "#ffffff"
fg[SELECTED] = "#ffffff"
fg[ACTIVE] = "#ffffff"
}
widget_class "*XfdesktopIconView*" style "xfdesktop-icon-view"

Open Settings –> Window Manager Tweaks –> Compositor and enable display compositing:

tweaks

Install a theme. My favorite is Albatross. Just create a folder ~/.themes and clone the Albatross theme from github

Result

And then you end up with something like this:

desk

And another Linux desktop is installed.

Nodejs and Mongoose

| Comments

Onto the next step on my journey learning Node.

I’m going to create registration system for informale care volunteers. Volunteers can sign in and provide all sort of details about themselves. If you are a volunteer and you want to go on vacation or just need some rest, you can browse the directory and find a replacement volounteer.

We basically need an addressbook of volunteers.

The first functional specs are:
* we need a volunteer
* the volunteer can have a status like available or unavailable
* the volunteer has all sorts of charecteristics which he or she may edit herself.
* the volunteer should be able to logon and may only chanqe her or his own details.

We also have some technical requirements
* we want to write one language for the whole stack
* the app should be platform indepent, lightweight and open source

We can meet the tech reqs by using a webserver running on node.js. For the database we choose MongoDb and Mongoose for the ORM, because these seem to be the most popular.

Designing the API

/volunteers/1234:
GET: show volunteer 1234
PUT: if exists updates volunteer 1234
DELETE: delete volunteer 1234
POST: will not work

/volunteers:
GET: read
PUT: bulk update volunteers
DELETE: deletes all volunteers
POST: creates new volunteer

The first tests

1
2
3
4
5
6
7
8
mkdir iVolunteer
cd iVolunteer
npm install mocha
npm install should
npm install mongoose

mkdir test
vim volunteertest.js

I studied the Mongoose and Mocha sites thoroughly to get this. For me it is better to read the documentation from the code maintainer, because then I know I’m using the right syntax.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var should = require('should');
var mongoose = require('mongoose');

var Schema = mongoose.Schema;

var volunteerSchema = new Schema({
  firstname:  String,
  lastname: String
});


var Volunteer = mongoose.model('Volunteer', volunteerSchema);
mongoose.connect('mongodb://localhost:27017/betadb');

describe('Volunteer', function(){

  beforeEach(function(done){
    //clean the database:
    Volunteer.remove(done);
  });

  describe('#save()', function() {
    it('should save', function(done) {
      var volunteer = new Volunteer({firstname: 'Joe' })
        volunteer.save(function(err) {
          if (err) return done(err);
          //assert.equal(volunteer.firstname,'Joe');
          volunteer.should.have.property('firstname','Joe');
          done();
        });
      });
   });
});

A Node HTTP Server

| Comments

Just like c# (which is my first language), you can import libraries with Node. They’re called modules. One of these modules is ‘http’. Let’s see how we can create a http server with this module.

hellopizza.js
1
2
3
4
5
6
7
8
9
10
11
12
var http = require('http');

//the http module has a function: createServer which takes a callback as a parameter:

http.createServer(function(request,response) {
       response.writeHead('200');
       response.write("one pepperoni pizza please");
       response.end();

    }).listen(8080);

console.log("listening on 8080");

We can run this with node:

1
2
jacqueline:public$ node hellopizza.js
listening on 8080

Browse to the page with curl:

curl
1
2
jacqueline:$ curl localhost:8080
one pepperoni pizza please