J. Bobby Lopez – Personal Blog

This is my personal blog. It includes articles I’ve personally written, along with interesting articles I have come across or have commented on at various points in time on the web.  The articles I’ve personally written are mostly about technology and software, but often about other things as well.  I am always eager to hear different perspectives on the topics I am interested in, so please feel free to comment and share your own opinions!  If you do register for an account on this site, please also send me a separate note by e-mail, since I do get a lot of spam. Thanks!

Tiny linux disk usage reporting script – dux.bash

I decided to write a very small disk usage reporting script that provides some extra information than does just using ‘du‘ directly.  The script of course uses du, among other command line tools and parsing commands to generate the little report.  It suits my needs for the moment. Hopefully others out there will also find it useful.

Firstly, here is the script output to give you an idea of how to execute it, what it does, and how it looks:

$ ./dux.bash /home/jbl /home/jbl
Building extended du reports for /home/jbl in /home/jbl ...
[du extended report]:
13G     ./Personal
4.7G    ./DATA
2.4G    ./Pictures
1.4G    ./Downloads
Total (GB): 21.5
 
373M    ./core
260M    ./tmp
73M     ./game-saves
37M     ./new-music
33M     ./new-books
32M     ./vim-env
24M     ./random-tools
15M     ./stuff
Total (MB): 847

The script takes two arguments, the directory you want to analyze, and the directory where you want to store the reports.

As you will see, the script provides me an at-a-glance look at the following characteristics of a particular directory structure:

  • Grouping and separation of larger (GB sized) directories from smaller (MB sized) directories.
  • Directories sorted by size in each group.
  • Total sizes for each group of files and directories.

With this output I can see clearly which directories are causing the most contention, and how much of an impact they have compared to other directories.

The script is very crude, and probably needs some work and error correction (accounting for files off or root, etc.)   It also creates some temporary text files (used to construct the report), which is the reason for the second argument to the script.  However for now it’s doing what I need, so I figure it’s worth sharing.  Here it is:

#!/bin/bash
echo "Building extended du reports for $1 in $2 ...";
cd $1
du -sh $1/* > $2/du-output.txt
cat $2/du-output.txt | egrep '([0-9][0-9]M)' > ~jbl/du-output-MB.txt
cat $2/du-output.txt | egrep '[0-9]G'> ~jbl/du-output-GB.txt
cat $2/du-output-MB.txt | sort -hr > $2/du-output-MB-sorted.txt
cat $2/du-output-GB.txt | sort -hr > $2/du-output-GB-sorted.txt
echo '[du extended report]:';
cat $2/du-output-GB-sorted.txt
echo -ne "Total (GB): " && cat ~jbl/du-output-GB-sorted.txt | perl -pe 's/^(\d+\.+\d+|\d+)\w*.*/$1/g' | paste -sd+ | bc
echo ""
cat $2/du-output-MB-sorted.txt
echo -ne "Total (MB): " && cat ~jbl/du-output-MB-sorted.txt | perl -pe 's/^(\d+\.+\d+|\d+)\w*.*/$1/g' | paste -sd+ | bc

I’m not sure what more I will need from it going forward, so it may not get much love in the way of improvements.  Since it would be nice to have it on each system I’m using, I may convert it to a single script that has no need to generate temporary text files.  

Nuff said!  Hopefully you find either the script, or portions of it useful in some way!

For convenience, I’ve also added this script as a public gist so you can download dux.bash from github.

Cheers!

Checking OS Version Across Multiple Hosts with Ansible

Often when you are maintaining a large number of servers, it is useful to be able to query those systems all at once to find out information like IP address, configured hostnames, and even the OS version.  

In this post we’re going to focus on pulling the OS version from multiple systems at once with a single Ansible playbook.  

First, lets get an idea of how our directory structure should look in the end, then we’ll break things down:

Ansible playbook and file-system layout:

[~/sources/ansible]
$ tree .
.
├── get-os-version.yaml
├── group_vars
│   └── linux
├── hosts
│   └── home
│   ├── archive.jbldata.com
│   ├── jbllnxwks.jbldata.com
│   └── yoga2.jbldata.com
└── host_vars
 
4 directories, 5 files

Now that we know how things should look in the end, lets setup our host configurations.

Host configurations:

[~/sources/ansible]
$ tree hosts/
hosts/
└── home
 ├── archive.jbldata.com
 ├── jbllnxwks.jbldata.com
 └── yoga2.jbldata.com
 
1 directory, 3 files
 
[~/sources/ansible]
$ cat hosts/home/archive.jbldata.com 
[linux]
archive.jbldata.com

As you can see, the host configurations can be fairly simple and straight-forward to start, following the directory structure outlined above. Now lets setup our group_vars.

Group configuration:

[~/sources/ansible]
$ cat group_vars/linux 
---
ansible_ssh_private_key_file: /home/jbl/.ssh/jbldata_id_rsa

In this case, each of the servers I’m dealing with are secured by password-protected SSH keys, so I’m setting up my group vars to reference the correct SSH private key to use when connecting to these servers.  Pretty simple so far?  Great, now lets look at the playbook.

The Ansible playbook: get-os-version.yaml

---
- name: Check OS Version via /etc/issue
 hosts: linux
 tasks:
 - name: cat /etc/issue
 shell: cat /etc/issue
 register: etc_issue
 - debug: msg="{{etc_issue.stdout_lines}}"

This playbook is very simple, but does exactly what we need.   Here we are specifying the use of the ‘shell’ module in order to execute the cat command on our remote servers.

We use the ‘register’ keyword to save the resulting output of the command in a variable called ‘etc_issue’.  We then use the ‘debug’ module to print the contents of that variable via ‘etc_issue’.  

When executing a command via the ‘shell’ module, there are several return values that we have access to, which are also now captured in the ‘etc_issue’ variable. In order to access the specific return value we are interested in, we use ‘debug’ to dump the STDOUT return value specifically via ‘etc_issue.stdout_lines’.

Now we have an Ansible playbook and associated configuration that allows us to quickly query multiple servers for their OS version.

It’s important to note that since I’m using password-protected SSH keys, that I’m using SSH Agent before I execute the playbook.  This only has to be done once for repeated runs of the same playbook within your current terminal session, for example:

[~/sources/ansible]
$ ssh-agent 
SSH_AUTH_SOCK=/tmp/ssh-82DKhToCuPUu/agent.4994; export SSH_AUTH_SOCK;
SSH_AGENT_PID=4995; export SSH_AGENT_PID;
echo Agent pid 4995;
 
 
[~/sources/ansible]
$ ssh-add ~/.ssh/jbldata_id_rsa
Enter passphrase for /home/jbl/.ssh/jbldata_id_rsa: 
Identity added: /home/jbl/.ssh/jbldata_id_rsa (/home/jbl/.ssh/jbldata_id_rsa)

Now, we’re ready to execute the ansible playbook.  Here’s the resulting output:

[~/sources/ansible]
$ ansible-playbook -i hosts/home get-os-version.yaml 
 
PLAY [Check OS Version via /etc/issue] *****************************************
 
TASK [setup] *******************************************************************
ok: [jbllnxwks.jbldata.com]
ok: [yoga2.jbldata.com]
ok: [archive.jbldata.com]
 
TASK [cat /etc/issue] **********************************************************
changed: [yoga2.jbldata.com]
changed: [jbllnxwks.jbldata.com]
changed: [archive.jbldata.com]
 
TASK [debug] *******************************************************************
ok: [archive.jbldata.com] => {
 "msg": [
 "Ubuntu 14.04.3 LTS \\n \\l"
 ]
}
ok: [yoga2.jbldata.com] => {
 "msg": [
 "Ubuntu 14.04.5 LTS \\n \\l"
 ]
}
ok: [jbllnxwks.jbldata.com] => {
 "msg": [
 "Debian GNU/Linux 5.0 \\n \\l"
 ]
}
 
PLAY RECAP *********************************************************************
archive.jbldata.com : ok=3 changed=1 unreachable=0 failed=0 
jbllnxwks.jbldata.com : ok=3 changed=1 unreachable=0 failed=0 
yoga2.jbldata.com : ok=3 changed=1 unreachable=0 failed=0

And that’s pretty much it!  Now we just have to add more hosts under our hosts/ configuration, and we can query as many servers as we want from a single command.  Happy orchestrating!

Our Galaxy is a Seed that Will Eventually Grow into it’s Own Universe

The universe is accelerating away from the center of the Big Bang.

The universe is cooling down, because galaxies are moving away from each other.
The number of stars in the sky will diminish over time, there will eventually be a few, then there will be none. This is the current theory (paraphrased) held by many scientists today, typically referred to as heat death.

I’m no scientist, but I like to visualize.  Read this article: Speculative Sunday: Can a Black Hole Explode?

I was inspired, in particular by this image:

This artist’s impression shows the remains of a star that came too close to a supermassive black hole. Extremely sharp observations of the event Swift J1644+57 with the radio telescope network EVN (European VLBI Network) have revealed a remarkably compact jet, shown here in yellow. – ESA/S. Komossa/Beabudai Design

 

The above image is an artists rendition of the results of the data received from an “earth-sized radio telescope”. The detail is specific, even if interpreted. What I’m seeing here is a pattern. Spiral falling / contraction (gravity), with a projection of stuff out the north and south poles. This projection from the black hole is likely directly related to the consumption of the star, which we see visualised as the star being smeared in a spiral around the singularity.

This is the pattern. Gravity pulls things in on one “plane” and creates a jet stream at the north and south poles of the black hole.  The jet stream is comprised of particles of matter that have been deflected or have narrowly escaped being captured by the black whole, only to be accelerated away at high speed again.   Now this particular aspect of how black holes function is very interesting because the process heats up space, to the point where it could potentially create or influence the creation of stars within a galaxy.  Think about that for a moment.

To create a star, or star-system, you don’t need THE Big Bang.  You don’t need super-galaxies, or galaxies or star-systems.  What you need is a black hole.  Every star that dies turns into a black hole (or a neutron star, then a black hole).You just need a black hole to create a star, and planets, and there I suggest, life?

My hypothesis is this.  Even if all our galaxies are moving away from each other over billions of years, and even though light and heat will diminish – new stars, new galaxies, and new universes will be created, just as the “first” one was.  And this dimension will continue on for other new life forms to grow and learn and figure this all out all over again.

Watch Cosmos: A Spacetime Odyssey if you have no idea what I’m talking about, then come back to this article.

http://www.space.com/18893-black-hole-jets-similarities.html
http://www.thephysicsmill.com/2015/06/14/speculative-sunday-can-a-black-hole-explode/
https://en.wikipedia.org/wiki/Neutron_star

Note: After writing this, I read up on Hawking Radiation, and found that black holes do die if they don’t feed (on other stars), they will eventually evaporate.  This is kind of poetic.

Soft Skills: The Software Developer’s Life Manual – A Review [Audiobook]

I’m almost through the book Soft Skills: The Software Developer’s Life Manual. I’m listening to the audio-book.  I like it, it’s pretty good. Along with the benefit of having the author, John Sonmez narrate his own book, he also provides a lot of commentary, discussion, and elaboration.  At first I thought it was annoying that the author would go off on a tangent every once in a while, then say “back to the book” and continue the verbatim reading.

However later I realized that the commentary and discussion were worth the tangents.  There are several very valuable tid-bits of information in this book, such as references and discussion of Pomodoro Technique, and KanbanFlow. The book touches a very broad scope of topics, from software development methodologies to personal finance management tips.  The book tries to help it’s readers see the habits and actions (or lack thereof) that are required to achieve a high degree of quality, consistency and professionalism in your career.

One of the things to keep in mind is that this book discusses a lot of tools and techniques that are documented external to the book itself.  The author frequently references his company’s website where the reader can find more information.

This book and the topics it discusses are very relevant to the success of an aspiring software developer.  Worth a read!

rbenv and multiple local ruby version installs (like perlbrew)

When I was using perl as my primary development language, I had a platform of tools in place to make my perl development fun and productive. This included tools like Perl::Dancer, DBIx::Class, cpanm, and perlbrew. Perlbrew was a tool I used to maintain multiple versions of perl in my local development environment, so that I could test my code against multiple perl and module versions to ensure that it worked on the largest range of platforms ( and to avoid dependency related bugs ).

This allowed me to run my code against Perl 5.10, 5.12, and 5.14, and so on each with their own module-base, fully isolated from each-other.

Now I’m working with many different tools these days, and haven’t had the opportunity to work with other languages to the extent that I’ve worked with Perl, but I have been playing with Ruby and Golang. Using Ruby, I immediately thought that I would like to play with multiple versions of Ruby without altering the ‘system’ ruby on my workstation. A quick search of ‘perlbrew for ruby’ lead me to rbenv which seems to be exactly what I was looking for.

Some examples of how rbenv works:

# list all available versions:
$ rbenv install -l
 
# install a Ruby version:
$ rbenv install 2.0.0-p247
 
# Sets a local application-specific Ruby version by writing the version name to a .ruby-version file in the current directory.
$ rbenv local 1.9.3-p327
 
# Sets the global version of Ruby to be used in all shells by writing the version name to the ~/.rbenv/version file.
$ rbenv global 1.8.7-p352
 
# Sets a shell-specific Ruby version by setting the RBENV_VERSION environment variable in your shell
$ rbenv shell jruby-1.7.1
 
# Lists all Ruby versions known to rbenv, and shows an asterisk next to the currently active version.
$ rbenv versions 1.8.7-p352 1.9.2-p290 * 1.9.3-p327 (set by /Users/sam/.rbenv/version) jruby-1.7.1 rbx-1.2.4 ree-1.8.7-2011.03
 
# Displays the currently active Ruby version, along with information on how it was set.
$ rbenv version 1.9.3-p327 (set by /Users/sam/.rbenv/version)
 
# Displays the full path to the executable that rbenv will invoke when you run the given command.
$ rbenv which irb
/Users/sam/.rbenv/versions/1.9.3-p327/bin/irb

How to Backup an Ubuntu Desktop (12.04, 14.04)

Source: http://askubuntu.com/questions/9135/how-to-backup-settings-and-list-of-installed-packages

Warning: Read about caveats in the link above before use

#——————————————————-

## The backup script
 dpkg --get-selections > ~/Package.list
 sudo cp -R /etc/apt/sources.list* ~/
 sudo apt-key exportall > ~/Repo.keys
 rsync --progress /home/`whoami` /path/to/user/profile/backup/here
## The Restore Script
 rsync --progress /path/to/user/profile/backup/here /home/`whoami`
 sudo apt-key add ~/Repo.keys
 sudo cp -R ~/sources.list* /etc/apt/
 sudo apt-get update
 sudo apt-get install dselect
 sudo dpkg --set-selections < ~/Package.list
 sudo dselect

#——————————————————-

Who is this for: users that have normal regular use of their computer, that have done minimal or no configuration outside their home folder, did not mess up startup scripts and services. A user that wants to have his software restored to how it was when he installed it with all customizations being done and kept in their home folder.

Who this will not fit for: servers geeks, power users with software installed by source (restoring the package list might break your system), users that have changed the startup script of some application to fit better their needs. Caution: there is a big chance any modifications outside home will be over written.

Expressing Your Authority May Be Working Against You

It doesn’t matter whether you are a senior engineer, a team lead, or an IT manager – eventually you will encounter the situation.  A meeting or discussion that becomes slightly more animated than usual.  Opinions are strong, and it is clear that consensus will not be found on this particular contentious issue today.   As a senior engineer, team lead, or manager, it is fair and understood that sometimes you will have to make a call one way or the other.   This article is not about whether or not you should make that call.  This article is about how to make that call.

Lets say for example that you are in a meeting with many of your direct reports, and these direct reports may be working on different aspects of the same project – or – they may be on different teams, still working toward the successful completion of a specific project.  There is a contentious concern, perhaps on the complexity around a specific problem where dead-lines need to be set.  Opinions are being vocalized, and the volumes of those voices are getting louder.  There doesn’t seem to be a clear way to reason out the differences of opinion at the moment. People are being blamed, fingers are being pointed.  You are the team lead/manager.  What do you do?

Well, lets look at what you should not do, with some suggestions on how you might handle these situations differently:

  1. Do Not Swear
    • It may seem to you that swearing at a meeting to get the attention of your team is either hip, cool, contemporary, or resonant with authority, but you would be dead wrong.
    • Anyone who really wants to succeed, and wants their teams and their company to succeed, will always want to bring positivity to the table.  By swearing (and I mean anything that is obviously vulgar, saying something like “what the fuck”), you are tarnishing the respect that your direct reports may have had for you.
    • With you being in a senior position, your direct reports look up to you, and will often try to mimic your mannerisms and the method by which you work (without full context of course), and they will replicate these mannerisms upon interactions with other teams and team members.
    • If you are swearing because you are highly frustrated, and simply lost control, then that is another matter that you need to address, immediately.
    • Apologize – If you do swear, communicate to your team that you are indeed frustrated, and did not mean to offend anyone.  Apologize sincerely to the whole team, and this will immediately re-gain any respect you may have lost, since you are showing the team that you are responsible for your actions, and are willing to concede when you’ve made a mistake.  This takes courage, and is a great example to set for your team.
  2. Do Not Raise Your Voice
    • There are many situations where raising your voice might be appropriate, for example to get everyone’s attention so that a meeting can begin.  Context is very important.
    • However, raising your voice for the sake of making a point (or to invalidate a point being made by someone else), or to express your authority will only back-fire, as you will lose the respect of those to whom you are trying to make your point.
    • Silence is golden – if you need to visibly show your disappointment or disagreement with an individual or a decision being made at a meeting, then the best thing to do is to be quiet.  Stand up, and hold your hand out as if you are pushing something away from you (think Neo in the Matrix).  Make it visible that you have something to say, or that you disagree, or would like to take the discussion off-line.  Your teams will respect you even more if you are able to command the attention of a room with silence.  Any fool can get attention by being loud and abrasive.
    • Again, by raising your voice, you are setting an example for others to do the same as well.  Your team members will take your queue and start to build a paradigm around how they see you acting and reacting, and they will do the same – believing either that this is what it takes to be successful, or that this is how YOU would rather interact.  They may even raise their voice against you in the very same meeting, with the misguided belief that you would see this as a positive characteristic in them.  Do not perpetuate this line of thinking.  If you are able to command a room with silence, then everyone else will follow suit and become silent, at which point a real and valuable conversation can once again be had.
  3. Do Not Perpetuate Fact-less Finger-pointing
    • Just because someone on your team makes a claim against another, doesn’t mean it is true.  If one team member claims that they are in a bad situation, or that they “are blocked” by another team or individual, do not simply jump on that finger-pointing train.  This is the equivalent of joining a pitch-fork mob against a monster which you didn’t know existed only a few minutes ago.  As a leader, you should be critical of all information coming your way, especially the hearsay that tends to happen when a second party is criticising a third.  It is a purely reactive method of dealing with people and situations, and it does more harm than good.
    • Ask questions – but from the perspective of information-gathering, not finger pointing.  What this means is that you are taking ‘people’ out of the picture, and instead are looking at ‘facts’ (current status and configuration, time-stamps, and corroborating evidence).  Instead of just taking those who claim that the ‘sky is falling’ at their word.
    • If you are going to address someone who is to be the defendant of a particular criticism, don’t ask them “Did you do (or not do) x?”.  Instead of being open about the obstacles which have prevented them from completing a certain task, this puts people on the defensive.  Try instead to be on their side.  If you are sincerely interested in achieving success for all teams, and for the entire company, and not just for yourself or your team, then show this by being helpful.  Instead, make statements like “What can I do to help move x along?”, or “Can we spend a few moments to break down this objective into smaller tasks?  Perhaps I or someone from my team can assist with moving this along?”.  This kind questioning puts the person being criticised in a position to ask for, and accept help if they need it.  If it is simply a matter of prioritization, something the person hadn’t gotten around to just yet, or if they simply lost sight of the tasks – they will once again be aware that the task needs attention.  They may even be embarrassed that you are offering to assist them with such a simple task that they will openly concede that they’ve simply lost sight of it, and would likely resolve the situation right away to avoid further embarrassment.
    • Bring people together.  Be an example to the person raising the issue or making the criticism by bringing together the parties involved so that there can be a quick and constructive dialogue about current obstacles or perceived road-blocks.  Show people how to solve problems without escalation, so that they can perpetuate a positive methodology around people-handling, and so that they themselves can become positive role-models that others can aspire to.
    • If you instead believe that perpetuating unfounded criticism and finger-pointing is a good thing, and that is all you believe you can or should do; then all you will end up doing is to make people feel alienated.  Those who are being criticised will go on the defensive, and they will likely want to avoid interacting with you (or anyone else on the finger-pointing bandwagon) going forward.  This does nothing to improve collaboration within or between teams.  Your organization and your company will suffer because of it.

Getting upset at your direct reports, raising your voice in order to re-claim a conversation, or simply ignoring input from specific people is a sure-fire way to diminish your reputation and earned respect across your entire team.  For the most part, private sector IT including software development, systems administration, and project management, is all thought-work.  It is important to be aware of and to understand how much psychology plays a part in the success of a team or organization.  Positivity breeds positivity, and the inverse is true as well.

Ansible Playbooks – Externalization and Deduplication

Image result for ansible

Externalization and Deduplication

Developers who understand the concepts of modularity and deduplication should immediately recognize the power behind being able to include settings and commands from external files.   It is seriously counter-productive to maintain multiple scripts or playbooks that have large blocks of code or settings that are exactly the same.   This is an anti-pattern.

Ansible is a wonderful tool, however it can often be implemented in counter-productive ways.  Lets take variables for example.

Instead of maintaining a list of the same variables across multiple playbooks, it is better to use Variable File Separation.

The Ansible documentation provides an excellent example of how to do this.  However I feel that the reasoning behind why you would want to do it falls short in describing the most common use-case, deduplication.

The documentation discusses the possible needs around security or information sensitivity.  I also believe that deduplication should be added to that list.  Productivity around how playbooks are managed can be significantly increased if implemented in a modular fashion using Variable File Separation, or vars_files.   This by the way also goes for use of the includes_vars module.

Here are a list of reasons why you should immediately consider a deduplication project around your Ansible playbook variables:

Save Time Updating Multiple Files

This may seem like a no-brainer, but depending on the skills and experience of the person writing the playbook, this can become a significant hindrance to productivity.   Because of Ansible’s agent-less and decentralized manner, playbooks can be written by anyone who wants to get started with systems automation.  Often, these can be folks without significant proficiencies in programmer-oriented text editors such as Vim, Emacs, or Eclipse – or with bash scripting experience around command-line tools like awk, sed, and grep.

It is easy to imagine a Java developer without significant Linux command-line experience opening up one playbook at a time, and modifying the value for the same variable, over and over… and over again.

The best way for folks without ninja text-editing skills to stay productive is to deduplicate, and store common variables and tasks in external files that are referenced by multiple playbooks.

Prevent Bugs and Inconsistent Naming Conventions

In a perfect world, everyone would understand what a naming convention was.  All our variables would be small enough to type quickly, clear enough to understand its purpose, and simple enough that there would never be a mis-spelling or type-o.  This is rarely the case.

If left un-checked, SERVER_1_IP can also be SERVER1_IP, Server_1_IP, and server_1_ip.  All different variable names across multiple files, referencing the same value for the exact same purpose.

This mess can be avoided by externalizing this information in a shared file.

Delegate Maintenance and Updates to Variables That Change Frequently

In some environments, there may be playbook variables that need to change frequently.  If these variables are part of some large all-encompassing playbook that only some key administrators have access to be able to modify, your teams could be left waiting for your administrator to have free cycles available just to make a simple change.  Again, deduplication and externalization to the rescue!  Have these often-changing variables externalized so that users who need these changes immediately can go ahead and commit these changes to very specific, isolated files within your version control system that they have special rights to modify.

Cleaner Version Control History (and therefore Audit History)

If you have the same variables referenced by multiple files, and you make changes to each of those files before you commit them to version control, then your version control history can become a complete mess.  Your version control history will show a change to a single value affecting multiple files.  If you come from a software development background, and are familiar with the concept of code reviews, then you can appreciate being able to look at a simple change to a hard-coded value (or a constant), and see that it only affects one or two files.

I hope the reasons above convince some of you to start browsing your playbook repositories for possible candidates for deduplication.  I really believe that such refactoring projects can boost productivity and execution speed for individuals and teams looking to push changes faster while minimizing obstacles around configurations shared by multiple systems.  Send me a note if this inspires you to start your own deduplication project!

Examples of recursion, in Perl, Ruby, and Bash

This article is in response to the following question posted in the Perl community group on  LinkedIn:

I’m new to PERL and trying to understand recursive subroutines. Can someone please explain with an example (other than the factorial ;) ) step by step, how it works? Thanks in Advance.

Below, are some very simplified code examples in Perl, Ruby, and Bash.

A listing of the files used in these examples:

blopez@blopez-K56CM ~/hello_scripts 
$ tree .
 ├── hello.pl
 ├── hello.rb
 └── hello.sh
0 directories, 3 files
blopez@blopez-K56CM ~/hello_scripts $


Recursion example using Perl:

– How the Perl script is executed, and it’s output:

blopez@blopez-K56CM ~/hello_scripts $ perl hello.pl "How's it going!"
How's it going!
How's it going!
How's it going!
^C
blopez@blopez-K56CM ~/hello_scripts $

– The Perl recursion code:

#!/usr/bin/env perl
use Modern::Perl;
my $status_update = $ARGV[0]; # get script argument
 
sub hello_world
{
&nbsp;&nbsp;&nbsp; my $status_update = shift; # get function argument
&nbsp;&nbsp;&nbsp; say "$status_update";
&nbsp;&nbsp;&nbsp; sleep 1; # sleep, or eventually crash your system
&nbsp;&nbsp;&nbsp; &amp;hello_world( $status_update ); # execute myself with argument
}
 
&amp;hello_world( $status_update ); # execute function with argument


Recursion example using Ruby:

– How the Ruby script is executed:

blopez@blopez-K56CM ~/hello_scripts 
$ ruby hello.rb "Doing great!"
Doing great!
Doing great!
Doing great!
^Chello.rb:7:in `sleep': Interrupt
&nbsp;&nbsp; &nbsp;from hello.rb:7:in `hello_world'
&nbsp;&nbsp; &nbsp;from hello.rb:8:in `hello_world'
&nbsp;&nbsp; &nbsp;from hello.rb:8:in `hello_world'
&nbsp;&nbsp; &nbsp;from hello.rb:11:in `'
blopez@blopez-K56CM ~/hello_scripts $

Note: In Ruby’s case, stopping the script with CTRL-C returns a bit more debugging information.

– The Ruby recursion code:

#!/usr/bin/env ruby
status = ARGV[0] # get script argument
 
def hello_world( status ) # define function, and get script argument
&nbsp;&nbsp;&nbsp; puts status
&nbsp;&nbsp;&nbsp; sleep 1 # sleep, or potentially crash your system
&nbsp;&nbsp;&nbsp; return hello_world status # execute myself with argument
end
 
hello_world status # execute function with argument

Recursion example using Bash:

– How the Bash script is executed:

blopez@blopez-K56CM ~/hello_scripts $ bash hello.sh "..nice talking to you."
..nice talking to you.
..nice talking to you.
..nice talking to you.
^C
blopez@blopez-K56CM ~/hello_scripts $

– The Bash recursion code:

#!/usr/bin/env bash
 
mystatus=$1 # get script argument
 
hello_world() {
&nbsp;&nbsp;&nbsp; mystatus=$1 # get function argument
&nbsp;&nbsp;&nbsp; echo "${mystatus}"
&nbsp;&nbsp;&nbsp; sleep 1 # breath between executions, or crash your system
&nbsp;&nbsp;&nbsp; hello_world "${mystatus}" # execute myself with argument
}
 
hello_world "${mystatus}" # execute function with argument

Managing Your SMTP Relay With Postfix – Correctly Rejecting Mail for Non-local Users

Image result for SMTP postfix

I manage a few personal mail relays that I use for relaying my own mail and for experimentation purposes (mail logs are a great source of unique and continuously flowing data that can you use to try out different ideas in GUI, database, or parser development).  One of them was acting up recently.  I got a message from my upstream mail-queue host saying that they’ve queued up quite a bit of mail for me over the last few weeks, and that I should investigate, as they do want to avoid purging the queue of valid mail.

Clearly I wanted to avoid queuing up mail on a remote server that is intended for my domain, and so I set out about understanding the problem.

What I found was that there was a setting in my /etc/postfix/main.cf that, although it was technically a valid setting, was incorrect for the role that mail-server was playing.  Specifically the mail server was supposed to be rejecting email completely for non-local users, instead of just deferring it with a “try again later” message.

In this case, I’m using Postfix v2.5.5. The settings that control this configuration in /etc/postfix/main.cf are as follows:

  • unknown_local_recipient_reject_code
  • local_recipient_maps

local_recipient_maps

local_receipient_maps defines the accounts that this mail server will accept and relay mail for. All other accounts would be “rejected” by the mail server.

However, how rejected mail is treated by Postfix depends on how it is configured, and this was the problem with this particular server.

For Postfix, it is possible to mark a message as “rejected”, but actually have it mean “rejected right now, but maybe not permanently, so try again later”. This “try again later” will cause the e-mail message to be queued on the upstream server, until it reaches some kind of retry time-out and delivery is once again attempted. Of course this will fail again, and again.

This kind of configuration is great for testing purposes, because it allows you to test the same messages over and over again without losing them, or to queue them up so that they can be reviewed to ensure they are indeed invalid e-mail messages. However this is not the state you want your mail server to be in permanently. At some point once things are ready for long-term (production) use, you want your mail server to actually reject messages permanently.

unknown_local_recipient_reject_code

That is where unknown_local_recipient_reject_code comes in. This configuration property controls what the server means when it “rejects” a message. Does it mean right now, or permanently?

The SMTP server response code to reject mail permanently is 550, and the code to reject mail only temporarily is 450.

Here is how you would configure Postfix to reject mail only temporarily:

unknown_local_recipient_reject_code = 450

And here is how you set Postfix to reject mail permanently:

unknown_local_recipient_reject_code = 550

In my case, changing the unknown_local_recipient_reject_code from 450 to 550 is what solved the problem.

In summary, if you ever run into an issue with your Postfix mail server where you believe mail is set to be REJECTED but it still seems to be queuing up on your up-stream mail relay, double-check the unknown_local_recipient_reject_code.

# Local recipients defined by local unix accounts and aliases only
local_recipient_maps = proxy:unix:passwd.byname $alias_maps
 
# 450 (try again later), 550 (reject mail)
unknown_local_recipient_reject_code = 550

References
http://www.postfix.org/LOCAL_RECIPIENT_README.html
http://www.postfix.org/postconf.5.html#unknown_local_recipient_reject_code

Why is my daughter strong? I didn’t clip her wings: Ziauddin Yousafzai at TED2014

Related article: Why is my daughter strong? I didn’t clip her wings: Ziauddin Yousafzai at TED2014

From the article:

In October 2012, a Taliban-affiliated gunman shot Ziauddin Yousafzai’s daughter Malala soon after she boarded a bus en route to her school. In Swat, Pakistan — where Ziauddin and Malala live — the Taliban had outlawed all girls from attending school — but Yousafzai, an educator and steadfast crusader for women’s rights in Pakistan, refused to take Malala out of his school.

Bad advice on “free advice”

Cross-post from LinkedIn, in response to How Seeking ‘Free’ Works Against Our Career Success:

I cannot completely agree here. There are many who offer free advice that also happens to be good advice. Alternatively, it is important for advice seekers to learn how to distinguish between good and bad advice by learning to think critically about the information they are receiving – by asking deeper, probing questions. Every answer received should lead to further questions. While I do agree that it is important to learn how to be independent and make your own way in this world (as in the example of parents encouraging children to pay for their own education), I do not see how this directly relates to giving or receiving free advice, or how free advice (as suggested in this article) can be considered to be bad advice without further inquiry. With regard to the job seeker asking for his/her resume to be reviewed, that was simply a lazy request. You cannot help those who are not willing to put in the effort to help themselves, regardless of whether or not your advice is free.

Stephen Colbert Interviews Neil deGrasse Tyson at Montclair Kimberley Academy – 2010-Jan-29

Cross-post from LinkedIn, in response to Stephen Hawking: Black Holes May Not Have ‘Event Horizons’ After All:

So relevant: http://www.youtube.com/watch?v=YXh9RQCvxmg Stephen Colbert interviews Dr. Neil deGrasse Tyson. The entire interview (starts about 6 mins in) is just a wholly wonderful discussion. I wish more people would watch it, over and over again. Dr. Tyson tries to elaborate on the very same topic (current understanding of black holes). Simply engrossing and inspiring. The interview is long, but the elaboration of black holes starts about 1hr 6 mins into the video. Enjoy!

Beautiful people do not just happen.

“The most beautiful people we have known are those who have known defeat, known suffering, known struggle, known loss, and have found their way out of the depths. These persons have an appreciation, a sensitivity, and an understanding of life that fills them with compassion, gentleness, and a deep loving concern. Beautiful people do not just happen.”
― Elisabeth Kübler-Ross

Every Minute is a Reflection of Life

 “Time passes so quickly. Minutes are like seconds.  Hours fly by in a wink. Responsibilities are inherited, expanded.  Your self-image pushes you forward to embrace the challenge. Thinking becomes a luxury.  Quick fixes and band-aid solutions become the norm. There is always something to do, somewhere to go, something to be acquired.

Adapt.  It becomes increasingly important to be concise.  To be clear.  To avoid trivialities. However you cannot lose who you are.  What motivated you to go where you have gone, and to be who you are today? It likely makes no difference, since who we are, and the motivations that drive us change with us every day. What is important, in fact the only thing that is important, is that you continue to try to be a better you.

There is no better critic of your personal character than you.  You think about it.  Don’t lie to yourself. It does bother you to see people suffering in one part of the world, while corporations bask in wasteful ignorance in another. It does bother you that most of society is locked into a dependant relationship with such corporations. But the cure for the world’s pain can only come from awareness and education.  No one is different from anyone else. Aggression breeds aggression.  Tolerance breeds tolerance.  Empathy breeds empathy.

Simple things can make a big difference under just the right circumstances. Never give up, but don’t be hard on yourself for not going as far as you would have liked, as fast as you would have liked. Time passes so quickly.”

My Little Angel

We took our daughter, Phoebe to a photo shoot recently and I was just in awe at the results.  So many photos of her that looked almost surreal!  The photographer did an excellent job!

Eventually I’ll post the rest of them, but for now here are a few of my favourites.  Yes my dear friends, I made this :)

phoebe2 phoebe1 phoebe3

My Fun With Necrolinguaphilia

Last night I attended a talk given by Dr. Damian Conway (of Perl Best Practices fame) titled “Fun With Dead Languages“.  Although this is a talk that Damian had given previously, it is the first time that I heard it, and I’m so glad I did!

I was the first to arrive at the Mozilla office building at 366 Adelaide, and so was able to score a sweet parking spot right across the street (no small feat in downtown Toronto).

I arrived and introduced myself to Damian as he was preparing for his delivery shortly before a herd of approximately 70 hackers (according to Mozilla) from all language and computing backgrounds started pouring through the meeting room doors to be seated.

Damian has a very energetic style of presentation, and was able to hold our attention while covering everything from the virtual extinction of the Gros Michel Banana, to the benefits and efficiencies of stack-based programming (using PostScript as an example).  He compares many, very different languages including Befunge, Brainfuck, Lisp, and Piet, and suggests that a great place to look for new ideas is what he calls the “Language Morgue”, where he includes languages such as Awk, Prolog, Cobol… and even C++ as examples of dead languages and language paradigms.

Mr. Conway also dived into excruciating detail on how the Latin natural language can be used as an effective computer programming language, and has even gone so far as to write a module called Lingua::Romana::Perligata, which he has made available on the CPAN.

I also had the special treat of sitting right behind Sacha Chua who brilliantly sketched notes of the entire talk in real-time.  I haven’t had the pleasure of formally meeting Sacha just yet (didn’t even say “hello”, my bad!) as I didn’t want to distract her.  Aside from having my mind blown by Damian’s talk, I was also being mesmerized by Sacha’s artistic skills, and so I do feel somewhat justified in keeping my mouth shut just to absorb everything that was going on right in front of me (front-row seats FTW!).

20130806 Fun with Dead Languages - Damian Conway

Sacha has made her “Fun With Dead Languages” sketch notes publicly available on her blog for everyone to review and enjoy, and has placed it under a Creative Commons license, so please share freely (and drop her a note to say “thanks!”).

Overall, I learned a lot from this talk and appreciate it immensely.  The energy of the audience made the discussion that much more enjoyable.  If you are interested in programming languages or language theory in general, I suggest you attend this talk the next time Damian decides to deliver it (or find a recording if one happens to be available?).  Damian Conway’s insights and humorous delivery are well worth the brainfuck ;)

Maybe Big Brother Isn’t As Bad as You Think..

Cross-post from LinkedIn, in response to Maybe Big Brother Isn’t As Bad as You Think:

“This is a future Orwell could not have predicted. And Big Brother may turn out to be a pretty nice guy.” I respectfully disagree. As others have noted, there is (and always will be) a huge asymmetry in the information being shared and consumed as far as “Big Brother” and state surveillance is concerned. The “sharing” in this case is one-way. Only those in power would have the ability to view and make sense of the data.

Your argument that we “choose to share data” because we get something in return, is flawed. Most people do not choose to share the kind of data that we are referring to in this regard, otherwise it would be done freely and intentionally, and the secretive information gathering we are witnessing here would not be taking place. Even the information we do share “intentionally”, is done so for the most part by many of us who do not pay attention to, and truly consider the ramifications of the many disclaimers, license agreements, and privacy policies that we agree to on a daily basis. What we get in return, as you suggest, is far from a fair compromise.

This one-way “sharing” means that those who are in power have not only the ability to collect this information, but also the tools and the ability to analyse this data and generate statistics that the rest of us have no choice but to consume as facts. Aside from the ability to collect and “make sense of” the data, on our behalf – those in power also have the ability to limit and restrict infrastructure and resources in order to manipulate the “facts” at the source. For example, the ability to manipulate DNS or shut down ISPs to prevent the dissemination of data – effective censorship. Many people have been detained or persecuted (or worse) simply for “sharing” their thoughts and beliefs.

How can you make an anti-Orwellian argument, a case *for* “Big Brother”, and suggest that this kind of sharing can be good and benefit us all equally, when the vast amount of information we are talking about can be controlled from source to audience by such small percentage of the population? I suggest you pay attention the thoughts and many works of notable individuals such as Noam Chomsky, Glen Greenwald, and Lawrence Lessig, and perhaps reconsider your position on this matter. I am currently reading Greenwald’s latest book “With Liberty and Justice for Some: How the Law Is Used to Destroy Equality and Protect the Powerful”. I am sure you would find it most enlightening.

For those more visually/audibly inclined: “Noam Chomsky & Glenn Greenwald – With Liberty and Justice For Some”

httpv://www.youtube.com/watch?v=v1nlRFbZvXI

Installing CentOS 6.4 from a Net Install Image on a Virtual Host

An Opportunity To Play Around with CentOS

One of the personal projects that I’ve always had itching away at the back of my mind was the urge to revamp my home network monitoring and security.  One of the tools that I love using for network monitoring is Xymon.  However, this gives me an opportunity to do things slightly different.  I have decided to give CentOS a go instead of my typical choice of Debian for a Linux distro in a server environment.  I am curious to see what advancements have been made in the RPM world, and I’d like to keep my Red Hat skills up to date.  What better way to do so than to set up a CentOS server with some production tools and services on it :)

Pre-installation Setup

So here we are, I have the CentOS Netinst (Net Install) image loaded into a VM, and I boot up the guest.

Since this is a fresh install on a 20GB virtual disk, I’m going to select “Install or upgrade an existing system” here.

I press “enter” and lots of console logging and scrolling action takes place.

Eventually I am prompted to “test the media”.  Usually this is referring to a physical CD typically used to install the OS on a physical server.  To me the phrasing feels a bit antiquated in this day of cloud services.

In any case, I still say yes, hoping that it will catch any errors in the ISO image file before I run into a bug during the installation process.  Better safe than sorry.

After the virtual disk is “successfully verified” to be OK, I try to move forward with the installation.

Be sure to note that after your virtual disk is verified OK, that the installer may decide to eject your CD media, in order to give you an opportunity to test other media.

Since I have no other media to test, this is actually kind of annoying. In order to continue with the installation, I have to go into the VM settings and re-connect the CDROM to the VM.

Select your language and keyboard options if the defaults are not suitable.  Otherwise, just  move past these dialogues by selecting “OK”, or hitting enter.

 

When you are asked “What type of media contains the installation image?”, select “URL”.
Continue reading Installing CentOS 6.4 from a Net Install Image on a Virtual Host

What is the “Cloud”?

The “Cloud” Will Save Us!

You hear about it every day, “cloud services”, “cloud storage”, “the cloud as a platform”. But what is the “cloud” really? The definition of what the “cloud” is, is different for everyone.  Some believe it is the implementation of a certain group of technologies, such as web servers, virtual hosts, and GUI frameworks.  Others believe it is a philosophy for modern software development and implementations – in particular web-based and mobile implementations. Others still see the “cloud” as simply a way of out-sourcing infrastructure – yet still somehow see the need to have dedicated “Cloud Administrators”.

So what is the “Cloud” really?  I offer my humble opinion below.

In With Old, Out with the New

Virtualization has been around for a very long time, so has Software as a Service (SaaS) and Platform as a Service (PaaS).  These technologies have been with us in different forms and iterations since the time of X11.  Of course, these technologies have evolved significantly over time, but that does not make them revolutionary, merely evolutionary.

I keep hearing phrases and comments to the effect of “the cloud changes everything”, when in fact it really doesn’t.  It is simply another form of outsourcing.  The real benefit of todays’ “cloud” technology is that it makes (or seems to make) management of infrastructure easier.  But convenience always come with a price.

Easier? Maybe Not So Much.. Especially For Seasoned Professionals

The easier things are, the more often you are likely to do them.  If it becomes easier to deploy apps via Amazon EC2/S3, or to a DotCloud instance, then there is a strong likelihood your organization will deploy more of them.  Instead of managing infrastructure, you are now concerned with managing deployment practices, configuration standards, and code-bases. Not to mention the human resources required to maintain those applications going forward.

The infrastructure “problem” doesn’t go away, it’s just relocated – it’s now someone else’s problem.

Over-Reacting and Under-Utilizing

When organizations frantically down-size their teams in a drastic attempt to remain modern, it bothers me; saddens me really, because deep down I know that the new cloud-based technologies these organizations are hoping to take advantage of are simply re-iterations and re-implementations of the same technologies they’ve always had to deal with.  HTTP, CSS, SSH, and Linux, for example.  It is quite likely that most companies with significant IT resources already have people who are skilled enough to rip through the implementation of “cloud” technologies, armed only with their previous experiences, and the core “problem-solver” attitude that they’ve always had, that doesn’t go away with time.

“Not enough Cloud experience.” Really? Do you mean using a GUI web interface to setup a remote host?  Or perhaps you mean the command-line configuration that needs to be done to YAML formatted text files in order to get a Rails application up and running?  Of course old-hat Systems Administrators or Web-Application developers don’t know “precisely” how it all works – the first time around.  But after the effort is put in to get the application up and running, to document the setup and check it into version control, and to automate as much of the time-consuming or repetitive manual tasks as much as possible, the rest is, as they say, “cake”.  What you need to focus on is developing the kind of people who can do all of this, and have fun with it.  This is how you effectively re-train.  This is how you retain good talent.  You have to allow the people you have to show you they can adapt.  It is a waste of experience to let people go because their experience is not up-to-date.  That’s not their fault.

More Of The Same, Spot The Patterns

Newer scripting languages and frameworks are being hyped as if they can do things that have never been done before.  I’ve seen this with the likes of Ruby, Python, and Perl. Despite the fact that Perl has one of the largest, organized, stable, and well-tested libraries  of any programming language to date (the CPAN), it doesn’t get the same kind of love that newer languages like Ruby and Python do, especially in corporate environments.  Sometimes it in fact does pay to re-invent the wheel, but most often it does not.

In Conclusion

If you are still trying to figure out what the “cloud” really is, know that it is simply a string of technologies that have been around for a long time, re-branded to look new and cool (for marketing purposes), and bundled with some new management tools and remote storage to make things “easier”.

To sales and marketing folks, it could simply mean trendy and cool.  To developers, it may mean LAMP or MEAN.  To systems and infrastructure people it could mean hyper-visors, virtual machines, and software containers.  To DevOps folks, it may involve Puppet, Chef, and Ansible automations, or Continuous Integration.

To recruiters and hiring managers, it often means Amazon AWS and Spring Framework Experience.  And to end-users, it typically means anything they can access from all of their phones, laptops, tablets, and PCs simultaneously.

The “Cloud” means many things to many different people.  My humble opinion? At it’s core – at the heart of the all the technology and implementation that has made it all possible; are tools, software, and individual experience that have been around since the beginning, and it is ALL based on the concept of Open Communication, and the spirit and foundation of Free and Open-Source Software.

Just Another Perl Hacker

Sometimes writing small snippets of code can be meditative.

The other day, I realized that, even though I happen to be, among other things, Just Another Perl Hacker, I never bothered to write my own JAPH signature.  So I went ahead and wrote up a very simple (but effective) one.  Once it was complete, it dawned on me that other perl hackers may appreciate the ability to generate a signature like my own.

Since perl is all about code reuse and sharing, I figured I would write up a JAPH signature generator so that anyone can have an awesomely obfuscated JAPH signature like I do.

Firstly here’s my JAPH signature:

1
2
$_='Kvtu!Bopuifs!Qfsm!Ibdlfs-!K/!Cpccz!Mpqf{';
@_=split//;foreach(@_){print chr(ord()-1)}

You can run the JAPH signature by copy/pasting it to a text file (e.g., japh_sig.pl), and running with

1
perl japh_sig.pl

Which returns:

Just Another Perl Hacker, J. Bobby Lopez

You can also run the JAPH signature straight off the command line (with ‘perl -e’), but you have to replace the single quote characters in the string with double-quote characters, for example:

1
perl -e '$_="Kvtu!Bopuifs!Qfsm!Ibdlfs-!K/!Cpccz!Mpqf{";@_=split//;foreach(@_){print chr(ord()-1)}'

This is all just for fun of course, but if you do end up using my JAPH signature generator, please let me know by sending me a quick message on Twitter to @jbobbylopez.

Have Fun!

The JAPH Signature Generator

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
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env perl
##############################################
# USAGE:
#   perl japh.pl This is my awesome signature
#
# OUTPUT:
#   Your JAPH Signature:
#       $_='Uijt!jt!nz!bxftpnf!tjhobuvsf';
#       @_=split//;foreach(@_){print chr(ord()-1)} 
#
#   Returns:
#       This is my awesome signature
#
# AUTHOR: J. Bobby Lopez &lt;jbl@jbldata.com&gt;
##############################################
 
use feature say;
 
my $offset = 1;
my $signature = join (" ", @ARGV);
my $obfus_sig;
 
my @obfus = ();
my @sig = split //, $signature;
 
foreach my $c (@sig)
{
    push @obfus, ( chr ( ord($c) + $offset ) );
}
 
$obfus_sig = join ("", @obfus);
 
say &lt;&lt;"OUT";
 
Your JAPH Signature:
\t\$_='$obfus_sig';
\t\@_=split//;foreach(\@_){print chr(ord()-$offset)} 
 
OUT
print "Returns:\n\t";
@_=split//,$obfus_sig;foreach(@_){print chr(ord()-$offset)};
say;
1;

Please join us in welcoming the newest member of our family!

On January 28th, at around 5am EST, the newest member of our family was born.  Weighing in at around 6lbs 3oz, and just under 20 inches in length; our daughter, Phoebe Isabelle Lopez, arrived into our world.. and we couldn’t be more thrilled to have her!

20130207_154749 Phoebe

 

 

 

 

 

Phoebe has been a very good baby, getting lots of rest and food and exercise.  She loves to look at ceiling fans and the patterns on our curtains.  She doesn’t seem too interested in toys yet though.  Sandra has been singing songs to her all day, changing the lyrics to include Phoebe’s name in the song.  Somehow we always end up adding the word “poop” or “poo” to the lyrics.

There are so many things that you need to learn when becoming a new parent.  It takes a lot of patience most of all, but the world of “baby stuff” is truly a huge world unto it’s own.  I know stuff about diapers, creams, mixing formulas, changing the Diaper Genie “correctly” (using the bulit-in cutter, and not a pair of scissors), and I have mastered swaddling.

We are not getting a lot of sleep, and sometimes it’s not worth trying to get another 20 minutes before she cries, so we just go with the flow, and so far it’s been working.

Phoebe truly is a special soul, and a blessing to us.  We are very thankful to have her home safe, sound, and healthy!

More pictures soon!

Edit: More pictures here!

Why You Shouldn’t be Sharing “Live” Documents by E-mail

 

If you and your team, in 2013, are still sharing Microsoft Office (Word, Excel) documents via internal corporate e-mail, I’ve got news for you.  You’re doing it wrong.

“Live documents” are documents that are actively being updated and collaborated on by multiple people.  Collaborating on these documents by e-mail is a process that you should avoid.  It is a process that can eat away at your team’s productivity precious minutes at a time, and can severely impede your team’s work-flow and ability to stay synchronised.

I’ve been involved with projects where this method of collaboration was adopted.  Whenever I recognize this to be the case, I would immediately share my concerns, and try to suggest better ways of getting the team organized. There are always better ways to do it.

One of the biggest problems with e-mail document sharing is that there is no tracking or accountability.  There is no way to easily know what version of the document you have in your possession.  Is it the latest?  Perhaps it’s new enough?  Ever had to find an email with a document attachment, and ended up trying to craft clever little search terms to search your inbox?  Even if you find the document you were looking for, there is no way for you to know whether it is the last official revision, unless a system is implemented to allow “official” versions of the document to reside in a central location.

If there is a point-person in charge of managing this kind of set-up (for example, a simple system implemented with shared folders), and the maintainer ends up leaving the company for any reason (vacation, short-term disability, lay-off), then you still end up in a bad situation.  Without someone actively maintaining the structure of the document store, things will end up getting messy very quickly.  Users will begin storing documents in arbitrary locations (whatever feels right at the time), and before you know it, you will have to start yet another document archive clean-up project.

Version control is ubiquitous, and it is here to stay.  Any company (in any industry, not just IT) not seriously considering a process for document revision control should at least make it a point to have the discussion at least once a year.  You may find that your current document handling processes are actually a significant time waster, and that implementing a document management system could save you a lot of time (or money) over the long run.

There are many document sharing and collaboration technologies available today.  Some of the more popular include Sharepoint (if you are a Microsoft shop) or Documentum.  There are also many open source (free) packages, such as Drupal, Joomla, and Liferay.  There are even projects like Etherpad that make collaboration just plain fun.  You can also roll-your-own (if you are so inclined) by developing a custom system on top of foundational version control software such as Git or Bazaar, as I personally have done in the past.

Do your research when considering a content management system.  Some important considerations you might want to make include:

  • Is it easy to set up?
  • Is it easy to use?  Does it blend well with our team’s work-flow?
  • Is it safe?  Is it easy to make backups?
  • What kind of security mechanisms does it have built-in?
  • Is it easy to get our data out of the system (strong import/export functionality), in the event that we decide to move to another system in the future?
  • Is it cross-platform, or does it tie us to a specific platform (operating system)?
  • Is the cost worth the investment for a company our size?

The important thing here is to start thinking about it.  Be open to evaluating multiple products before you decide on a system that blends best with your organization’s work-flow. Software is about solving problems, which includes eliminating routine and time-consuming tasks.  If your company is not continually looking at new ways to improve efficiencies via clever (and practical) software implementations, then it will eventually be left in the dust as more efficient start-ups and entrepreneurs bring their shiny new productivity platforms to the game.

Team Meetings at the Workplace

I’ve been to many team meetings (or “all hands”) that have, in the end, provided no real value to the team in attendance.  It is very possible (and likely quite common) that most meetings are actually a waste of time (as many of my closest colleagues and friends would agree).  However, this does not always have to be the case.

Meetings are important to have.  They provide an opportunity for team members to share not just the facts, but also how they feel about the current situation for a given project.  Team meetings can often provide context for the day-to-day work that each of us is involved with.  Just as importantly, it is an opportunity for leaders to maintain an awareness of how their team members are feeling, in order to better estimate how the team might respond given additional stress.

Meetings have to be run with intention in order to be successful.  Topics should be specific, and every topic discussion should end with an actionable deliverable assigned to a specific individual.  This may sound a bit restricting, but it goes a long way toward saving your team more time for actual work, along with giving them (and yourself) more time to relax.

There are many meetings that I have attended where discussions were essentially a one-way dialogue between the presenter and the rest of the team, where feedback was neither elicited nor volunteered.  When the host (usually a team lead, manager, or PM) asks the ever gripping question “..any questions or comments on this?”, and a conference call of about twenty or so people falls dead-silent.. well, I would consider that a problem.

Often the problem is that the meeting is too broad, involving too many people who don’t work with each other on a regular day-to-day basis.  Smaller meetings are the key to success.  Meetings should be specific, covering 3-5 of the most important items or active projects.  Meetings should also be quick (standing meetings are often very effective).  Questions and responses should be clear and to the point.  “What’s the status of the X project?”   “What’s changed from last week?”  “What do you need to keep this on track?”

Team meetings shouldn’t get too technical either.  That’s what e-mail, white-boards, and dedicated meetings are for.  Having technical discussions at team meetings will rarely be beneficial, and will often just turn into an echo chamber or a religious debate.  These types of discussions are good to have, but not when leadership is at the table.

When leadership is at the table (Managers, Sr. Managers, Directors),  the focus of the meeting should be for the leadership team to identify the most critical issues to address, and do all that is necessary to raise the collective spirit of the team; with feedback that is directly related to the work that they are doing.  The only way to do this is to be aware of the team’s accomplishments since the last meeting.  Every little inch matters.  Every little unit of work and motivation you can squeeze out of your team will benefit your project, and your stakeholders.   I am not suggesting micro-management, nor am I advocating unnecessarily cracking the whip.  Instead, what I would suggest is that teams work together to develop processes and routines that will continually provide positive, targeted feedback on the work that the staff has accomplished.

 

Adventures with Ubuntu 12.04 and Linux Mint 14 (Nadia)

Over the last week I’ve been playing around with Ubuntu 12.04 (Precise Pangolin) and Linux Mint 14 (Nadia).  Although I can appreciate Linux Mint (it is indeed very elegant), I think I will be sticking with Ubuntu 12.04 LTS for the time being.

My affection for the Unity interface that comes with Ubuntu 12.04 stems from the fact that I’ve been a heavy user of Mac OSX over the last year.  Before that, I was using Ubuntu 9.04, but the UI was heavily modified and stripped down, as I was a heavy user of the Xmonad window manager.

Having that experience with Xmonad, which is essentially a high-productivity, tiling window manager; and later working with the MacBook Pro (Late 2011) OSX environment, I’ve come to appreciate how important it is to have a powerful desktop UI that also gets out of your way.  The Unity interface follows that line of thinking, and is a real treat to work with once you start getting the hang of it.

There are some drawbacks to Unity, especially with regard to how applications are organized within the launcher, however I find that overall it will be a very rewarding environment to work in.

Luckily I have all my Vim and GNU Screen configuration files checked into version control, so it was easy enough for me to get GVim and all my other cross-platform apps up and running in my new desktop environment with minimal fuss.

Some screen shots of my desktop environment below:

The only real problems that I ran into with Ubuntu 12.04 were problems that were really hardware related. I’m running an ASUS S56CM Ultrabook, which has an oddly integrated Nvidia GT635M GPU.   So for now, I need to run my graphics intensive (OpenGL) applications via Bumblebee v3.0, however once that was set up, everything worked fantastically!

Flowers still hanging in there

image

To my surprise the flowers we planted in early spring are still hanging in there!

image

The last rainfall really helped a lot; it was starting to get pretty dry at one point earlier in the year.

Hopefully I”ll get a chance to rip out some weeds over the weekend.

image

It”ll be sad to see them wither away in the fall :(

Be sure to enjoy the rest of your summer!

People Getting Along

It always surprises me when people share a bit more about themselves than they realize, especially those who think themselves fairly reserved, quiet, or “better than thou”.

I find this occurs when a big change has happened (or is happening) in that person’s life; a life-changing change. Sometimes these are the only moments when you get any kind of real insight into how that person thinks and reacts under pressure, or how they truly feel about the people and the issues in the world around them.

Enjoy The Silence

httpv://youtu.be/RTOLMbKjLeY

♫ Words like violence break the silence ♫
♫ Come crashing in into my little world ♫
♫ Painful to me, pierce right through me ♫
♫ Can’t you understand, oh my little girl? ♫

♫ All I ever wanted, all I ever needed Is here in my arms ♫
♫ Words are very unnecessary They can only do harm ♫

♫ Words are spoken to be broken ♫
♫ Feelings are intense, words are trivial ♫
♫ Pleasures remain, so does the pain ♫
♫ Words are meaningless and forgettable ♫

♫ All I ever wanted, all I ever needed Is here in my arms ♫
♫ Words are very unnecessary They can only do harm ♫

Wikipedia: Enjoy The Silence

Experiences and Recorded History

It is amazing to me how far we have come technologically, yet we are still so far away from being able to record experiences with any degree of accuracy.  It is the experiences that we have that make us who we are, our identities.  And so it goes to reason that who we are can never be conveyed to another person or individual with any degree of accuracy.

There will always be gaps.. pieces of the puzzle missing so as to prevent anyone from seeing a clear picture of who you are, both inside and out.  The people around you the most will (should) have the fairest ideas about who you are overall; but even they woun’t have all the information.  There will always be little details about your personality, your dreams, and your fears that no one will ever be aware of, simply because they reside nowhere but within your own mind.

People Aren’t Smart Enough for Democracy to Flourish, Scientists Say

It’s occurred to me fairly often of the past several years that the reason why democracy doesn’t achieve ideal results is simply because most voters are ill-informed about the real issues facing the world; and not just the issues being relayed via cable television news networks.  This article simply confirms my assumptions.. unfortunately.

For example, if people lack expertise on tax reform, it is very difficult for them to identify the candidates who are actual experts. They simply lack the mental tools needed to make meaningful judgments.

Nagel concluded that democracies rarely or never elect the best leaders. Their advantage over dictatorships or other forms of government is merely that they “effectively prevent lower-than-average candidates from becoming leaders.”

Read the full article here –>>

Are your feelings as important as those of others around you? Should they be?

Ever feel like you’re in a position to make a decision where there can be no reasonably useful or positive outcome?  Ever feel like the the choice in front of you will simply lead to misery (or at very least, be anti-climactic), regardless of the path you take?

We are all selfish in our own little (or not so little) ways.  We have all said, done, and been involved with things in the past that has shaped us into the individuals we are today.  Everyone at some point will regret some of the decisions they’ve made.  At the same time we understand that, in most cases, we would not have acquired the wisdom of experience gained by making those decisions in the first place.  Wisdom aside, we may never again have the opportunity to engage experiences we have always quietly longed for.

I, of course, am not a God fearing man by any means.  I don’t believe that chosing whether or not to consume pork or beef will have any major karmic consequence (aside from what can naturally occur health-wise if proper diet isn’t maintained).  I believe that whatever happens to us in our lives is the result of either a) the decisions we have made in the past, b) the decisions that others have made which happen to affect us by consequence, or c) cascading events over time, including genetics and environmental changes. Any moral conflicts which stir in my mind are the result of my own experiences and what I’ve come to see as good, bad, or taboo.

Having said that, “let your conscience be your guide” becomes a double-edged sword. Taking your own feelings into account is just as important as taking into account the feelings and wishes of others (isn’t it?).  One day you may find that the very thing you’ve avoided in order to “do the right thing” – to be the best model of a good person that you can be (from the perspective of your current society/environment),  could very well end up being your biggest regret.

There is of course a significant portion of our population that, by default, will put their own feelings first, before the feelings of others.  Lets call this group the “me first” group.  This type of person will consider the feelings of others as an after-thought, and usually in a reactive manner, should their general lack of consideration put them in an uncomfortable situation.

I am not one to be inconsiderate of the feelings of others.. for the most part.

On the flip-side, there are those who feel that their desires and feelings should always be considered first, in any situation.  I guess these people also fall squarely into the “me first” group.  Many of these people have a knack for twisting culture, tradition and social norms to support their “me first” mind-set.

But isn’t making your own feelings an equal or greater priority over the feelings of others place you in the “me first” group as well?  It depends.

It’s all about patterns – how often do you do it? How regularly does it occur? To what extent? I would imagine that the “me first” group are “me first” people most, if not all of the time.  Whereas, those who have to consciously think about putting their own feelings first – who generally put others first, and themselves second (or last) don’t necessarily get lumped into the “me first” group.  Of course, a single selfish action can cause you to be labelled one way or the other.  I suppose also, over time, people can shift in and out of the “me first” group depending on their current life situation.

But anyone capable of using the space between their ears can understand the difference between an intermittent, irregular behavior, and that of behavior which is regular, recurring, and often predictable.

So.. does a selfish act committed by a generally un-selfish person, make that person generally selfish?  Everyone is selfish to some degree.  Understood.  However there are extremes that need to be taken into account, extremes that most people cannot (or will not) acknowledge.  Practical wisdom to the rescue.

ACTA is part of a multi-decade, worldwide copyright campaign

Ars Technica recently talked to Michael Geist, a legal scholar at the University of Ottawa, about this effort. He told us that rather than making their arguments at the World Intellectual Property Organization, where they would be subject to serious public scrutiny, the US and other supporters of more restrictive copyright law have increasingly focused on pushing their agenda in alternative venues, such as pending trade deals, where negotiations are secret and critics are excluded.

Read the full article at ArsTechnica.

The Apache Software Foundation Celebrates the 17th Anniversary of the Apache HTTP Server with the release of v2.4

World’s most popular Web Server powers nearly 400 million Websites across the globe

Numerous enhancements make Apache HTTP Server v2.4 ideally suited for Cloud environments. They include:
•    Improved performance (lower resource utilization and better concurrency)
•    Reduced memory usage
•    Asyncronous I/O support
•    Dynamic reverse proxy configuration
•    Performance on par, or better, than pure event-driven Web servers
•    More granular timeout and rate/resource limiting capability
•    More finely-tuned caching support, tailored for high traffic servers and proxies.

Read the full press release at The Apache Foundation’s blog.

Insights on Technology, Science, Philosophy, and Society. Exploring Patterns, Logic, Reason, Empathy, and The Golden Rule. “Seek first to understand, then to be understood.” – Stephen R. Covey