I’ve been playing with Docker off and on for almost a year and noticed that I have a lot of abandoned images on my system that are left over from experimenting.  This post contains a few commands you can use to clean up your system.

To illustrate what I mean by “abandoned images”, here’s the output of `docker images` on my machine.

That last image is 11 months old and at this point I have no idea what the hell I was doing with it — time to clean!

The list below is a (mostly) plagiarized repost of an answer left by Ulises Reyes on Stack Overflow and explains how to clean up old images.

 

Delete One Image

Easy!

docker rmi <the_image_id>

 

Delete All Images

The `docker rmi` command can accept a list of image IDs so destroying all images is pretty easy:

docker rmi $(docker images -q)

 

Stop and Delete All Images

Gracefully (SIGTERM) stop all images then delete them.

docker rm $(docker stop $(docker ps -q))

 

KILL and Delete All Images

SIGKILL all images then delete them.

docker rm $(docker kill $(docker ps -q))

 

Delete All Images Except for…

If you want to delete all images except for a select few it can be done using grep.  Basically you will make a call to `docker images` then filter the list using grep.

The example below will delete all images that do NOT have contain the words “dont”, “kill” and “me”.

Note — the `awk {‘print $3}` is what actually prints out the image ID.

docker rmi $(docker images | grep -v 'dont\|kill\|me' | awk {'print $3'})

Here’s a nice snippet that can be used in a PostgreSQL database to output the current database’s size.

SELECT pg_size_pretty(pg_database_size(current_database())) AS human_size, 
       pg_database_size(current_database())                 AS raw_size;

That statement with output something along the lines of:

human_size  | raw_size
------------+--------------
181 GB      | 193841573064

git push origin hamsterAt work we have been using GitLab for a while and it’s been pretty good but we have recently opted to move to GitHub Enterprise.  As a result there are a number of small repos we have hosted on GitLab that now need to be moved over to GitHub.

Additionally, this should generically work for any git repository migration but I’m explicitly calling out “gitlab” and “github” in hopes it makes the post easier to follow — and because it’s my actual use case.

The process is as follows:

  1. Mirror clone the old repo @ GitLab
  2. Mirror push to the new repo @ GitHub with pre-commit hooks skipped
  3. Update the push URL for the mirror cloned repo

Why clone as `mirror`?

Because it’s like `–bare` but with more magic!

This blurb from the git docs pretty much covers it:

–mirror
Set up a mirror of the source repository. This implies –bare. Compared to –bare, –mirror not only maps local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository.

And from GitHub’s docs:

As with a bare clone, a mirrored clone includes all remote branches and tags, but all local references will be overwritten each time you fetch, so it will always be the same as the original repository.

Why skip pre-commit hooks?

You may not need to do this but the repos I’ve been working on have a lot of pre-commit stuff that runs — tests, static analysis, etc.  For the purpose of just pushing the entire repo to a new location i don’t care about this stuff.  `–no-verify` tells git to push and skip the hooks.

Repo Migration Process

Developer Change Process

For developers who are using the repos being migrated, the process for pointing @ GitHub is a one liner.

If you have attempted to install the Nokogiri gem and encountered errors similar to the output below… I feel your pain and have a solution.

The Pain

➜ z gem install nokogiri Building native extensions. This could take a while... ERROR: Error installing nokogiri: ERROR: Failed to build gem native extension.
/Users/mariozig/.rvm/rubies/ruby-2.2.1/bin/ruby -r ./siteconf20150318-11691-1hlore5.rb extconf.rb
checking if the C compiler accepts ... yes
checking if the C compiler accepts -Wno-error=unused-command-line-argument-hard-error-in-future... no
Building nokogiri using packaged libraries.
checking for gzdopen() in -lz... yes
checking for iconv using --with-opt-* flags... yes
************************************************************************
IMPORTANT NOTICE:
Building Nokogiri with a packaged version of libxml2-2.9.2
with the following patches applied:
 - 0001-Revert-Missing-initialization-for-the-catalog-module.patch
 - 0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch
Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:
gem install nokogiri -- --use-system-libraries
 [--with-xml2-config=/path/to/xml2-config]
 [--with-xslt-config=/path/to/xslt-config]
If you are using Bundler, tell it to use the option:
bundle config build.nokogiri --use-system-libraries
 bundle install
Note, however, that nokogiri is not fully compatible with arbitrary
versions of libxml2 provided by OS/package vendors.
************************************************************************
Extracting libxml2-2.9.2.tar.gz into tmp/x86_64-apple-darwin14.1.0/ports/libxml2/2.9.2... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxml2/0001-Revert-Missing-initialization-for-the-catalog-module.patch...
Running 'patch' for libxml2 2.9.2... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxml2/0002-Fix-missing-entities-after-CVE-2014-3660-fix.patch...
Running 'patch' for libxml2 2.9.2... OK
Running 'configure' for libxml2 2.9.2... OK
Running 'compile' for libxml2 2.9.2... OK
Running 'install' for libxml2 2.9.2... OK
Activating libxml2 2.9.2 (from /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/x86_64-apple-darwin14.1.0/libxml2/2.9.2)...
************************************************************************
IMPORTANT NOTICE:
Building Nokogiri with a packaged version of libxslt-1.1.28
with the following patches applied:
 - 0001-Adding-doc-update-related-to-1.1.28.patch
 - 0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch
 - 0003-Initialize-pseudo-random-number-generator-with-curre.patch
 - 0004-EXSLT-function-str-replace-is-broken-as-is.patch
 - 0006-Fix-str-padding-to-work-with-UTF-8-strings.patch
 - 0007-Separate-function-for-predicate-matching-in-patterns.patch
 - 0008-Fix-direct-pattern-matching.patch
 - 0009-Fix-certain-patterns-with-predicates.patch
 - 0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch
 - 0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch
 - 0014-Fix-for-bug-436589.patch
 - 0015-Fix-mkdir-for-mingw.patch
Team Nokogiri will keep on doing their best to provide security
updates in a timely manner, but if this is a concern for you and want
to use the system library instead; abort this installation process and
reinstall nokogiri as follows:
gem install nokogiri -- --use-system-libraries
 [--with-xml2-config=/path/to/xml2-config]
 [--with-xslt-config=/path/to/xslt-config]
If you are using Bundler, tell it to use the option:
bundle config build.nokogiri --use-system-libraries
 bundle install
************************************************************************
Extracting libxslt-1.1.28.tar.gz into tmp/x86_64-apple-darwin14.1.0/ports/libxslt/1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0014-Fix-for-bug-436589.patch...
Running 'patch' for libxslt 1.1.28... OK
Running patch with /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch...
Running 'patch' for libxslt 1.1.28... OK
Running 'configure' for libxslt 1.1.28... ERROR, review '/Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2/ext/nokogiri/tmp/x86_64-apple-darwin14.1.0/ports/libxslt/1.1.28/configure.log' to see what happened.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details. You may
need configuration options.
Provided configuration options:
 --with-opt-dir
 --with-opt-include
 --without-opt-include=${opt-dir}/include
 --with-opt-lib
 --without-opt-lib=${opt-dir}/lib
 --with-make-prog
 --without-make-prog
 --srcdir=.
 --curdir
 --ruby=/Users/mariozig/.rvm/rubies/ruby-2.2.1/bin/$(RUBY_BASE_NAME)
 --help
 --clean
 --use-system-libraries
 --enable-static
 --disable-static
 --with-zlib-dir
 --without-zlib-dir
 --with-zlib-include
 --without-zlib-include=${zlib-dir}/include
 --with-zlib-lib
 --without-zlib-lib=${zlib-dir}/lib
 --enable-cross-build
 --disable-cross-build
/Users/mariozig/.rvm/gems/ruby-2.2.1/gems/mini_portile-0.6.2/lib/mini_portile.rb:279:in `block in execute': Failed to complete configure task (RuntimeError)
 from /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/mini_portile-0.6.2/lib/mini_portile.rb:271:in `chdir'
 from /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/mini_portile-0.6.2/lib/mini_portile.rb:271:in `execute'
 from /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/mini_portile-0.6.2/lib/mini_portile.rb:66:in `configure'
 from /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/mini_portile-0.6.2/lib/mini_portile.rb:109:in `cook'
 from extconf.rb:278:in `block in process_recipe'
 from extconf.rb:177:in `tap'
 from extconf.rb:177:in `process_recipe'
 from extconf.rb:487:in `<main>'
extconf failed, exit code 1
Gem files will remain installed in /Users/mariozig/.rvm/gems/ruby-2.2.1/gems/nokogiri-1.6.6.2 for inspection.
Results logged to /Users/mariozig/.rvm/gems/ruby-2.2.1/extensions/x86_64-darwin-14/2.2.0/nokogiri-1.6.6.2/gem_make.out

The Problem

For some reason Apple’s Yosemite version of OSX does not have a system accessible installation of libxml2.  Nokogiri requires this in order to compile and luckily Xcode has a version of libxml2 bundled with it — we just need to specify it when installing the gem.  It’s important to get Nokogiri installed correctly because as of right now Rails 4.2.1.rc4 automatically attempts to install it and you will feel pain.

How I Solved It

gem install nokogiri -- --use-system-libraries=true --with-xml2-include=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/libxml2

Jim Weirich was awesome.I had a discussion with a coworker today where he openly asked if rake tasks can take arguments… and if they can, can the task’s arguments have default values set.

Passing defaulted arguments to a rake task is actually super easy and I can definitely empathize with people who ask have no idea this is possible.  If you look over a typical unparameterized rake file the DSL looks SORTA like methods but sorta not and it can be a little confusing. This post aims to serve as an example of how to pass arguments to your rake tasks and more importantly, how to set default values.

Here’s an example rake task with sole purpose of yelling your arguments into your face:

namespace :arg_yellifier do
  desc 'Yells your argument directly into your face'
  task :yell, [:phrase] do |t, args|
    args.with_defaults(phrase: "don't tell anyone but... yolo")
    puts args[:phrase].upcase + '!'
  end
end

The way you call :yell is like this:

➜ projects rake arg_yellifier:yell[quietness]
QUIETNESS!

As you can see, this task takes in an argument called `:phrase` that is set to the value of “quietness” then uppercases it and finally adds a bang to the end.

When you use a block in conjunction with `task` it exposes two variables. The first, which I’ve called `t`, is the task object and the second, `args` is set of arguments passed in by the user.  For this rake task args has one item named `:phrase` and it can be accessed via `args.phrase` or `args[:phrase]`.

The interesting thing here is that `args` is not some kind of hybrid hash. It’s actually an instance of the Rake::TaskArguments class. This is awesome because we can call methods on it such as `with_defaults`.  `with_defaults` simply takes a list of key: value pairs where the key is the arg name and the value is it’s default value.

Check it out in action:

➜ projects rake arg_yellifier:yell
DON'T TELL ANYONE BUT... YOLO!

 

Dear Users of zsh:

If you’re calling rake tasks with arguments and have problems running rake tasks with arguments… such as..

➜ projects rake arg_yellifier:yell[quietness]
zsh: no matches found: arg_yellifier:yell[quietness]

You need to escape the `[` and `]` like this:

➜ projects rake arg_yellifier:yell\[muhahahah\]
MUHAHAHAH!

 

I use Postgres.app to run a local Postgres server while doing development work and it’s great. Postgres.app basically provides a completely contained pg server that’s ready to go out of the box — just launch the app and you’re good to go.

Unfortunately because it’s a self contained app things are installed in non-standard places.

More specifically, while installing the `pg` gem on a system I recently had it fail with this error:Continue reading

For some reason my brain has defected and has chosen a life of NEVER being able to recall basically anything related to Ruby’s % notation. After seeing this list on a recent Arkency blog post (an awesome blog) I’ve decided to steal repost it here for my own personal reference.


 

%q[ ] # Non-interpolated String (except for \\ \[ and \])
%Q[ ] # Interpolated String (default)
%r[ ] # Interpolated Regexp (flags can appear after the closing delimiter)
%i[ ] # Non-interpolated Array of symbols, separated by whitespace
%I[ ] # Interpolated Array of symbols, separated by whitespace
%w[ ] # Non-interpolated Array of words, separated by whitespace
%W[ ] # Interpolated Array of words, separated by whitespace
%x[ ] # Interpolated shell command

barely-wait-credit-great-workplaceSometimes you accidentally commit code under the wrong author or committer credentials.  This has happened to me a few times while writing code from computers with global git settings.  By using `git filter-branch` it is possible to rewrite history… muhahahah!

This snippet will run through your branch’s historical commits and rename the author and committer attributes.

It basically looks for all commits containing a given `$OLD_EMAIL` and resets the following properties:

  • GIT_AUTHOR_NAME
  • GIT_AUTHOR_EMAIL
  • GIT_COMMITTER_NAME
  • GIT_COMMITTER_EMAIL

The code:

This code is an updated version of the “nuclear option” code provided in the ProGit book.

Finally just push:

git push --force --tags origin 'refs/heads/*'