Installing rbenv through shell script

685 views Asked by At

I've created a shell script to install rbenv onto a fresh virtual machine, everyone seems to be working fine, however, once and a while it seems that rbenv fails to install. I'd like to add some extra error checking throughout the way to ensure that the install happens, and if something failed, re-start the install.

Some notes:

  • This is a small part of a larger script
  • This is all done through whiptail dialog
  • I'm redirecting the output to an events.log file >&$log_fd...

This is what I currently have:

set_rbenv(){
  # install rbenv
  RUBY_VERSION="2.1.4"
  RBENV_ROOT="/root/.rbenv"
  PROFILE="/root/.bashrc"

  # check if rbenv is installed
  if [[ ! `which rbenv` ]]; then

    if [[ ! -d "$RBENV_ROOT" ]]; then
      echo "Cloning rbenv..." >&$log_fd 2>&1
      git clone https://github.com/rbenv/rbenv.git $RBENV_ROOT >&$log_fd 2>&1
    fi

    if [[ ! -d "$RBENV_ROOT/plugins/ruby-build" ]]; then
      git clone https://github.com/rbenv/ruby-build.git $RBENV_ROOT/plugins/ruby-build >&$log_fd 2>&1
    fi

    if [[ ! `grep -e '/.rbenv\/bin' $PROFILE` ]]; then
      echo "rbenv not in PATH ... adding..." >&$log_fd 2>&1
      echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> $PROFILE 2>&1
    fi
    if [[ ! `grep -e '^\eval "$(rbenv init -)"' $PROFILE` ]]; then
      echo "rbenv init not in .bashrc... adding..." >&$log_fd 2>&1
      echo 'eval "$(rbenv init -)"' >> $PROFILE 2>&1
    fi
    . $PROFILE
    echo "Finished Installing rbenv..." >&$log_fd 2>&1
  else
    echo "rbenv already installed... skipping!" >&$log_fd 2>&1
  fi

  if [ ! -d "$RBENV_ROOT/versions" ]; then
    echo "$RBENV_ROOT/versions doesn't exist ... creating..."
    mkdir $RBENV_ROOT/versions >&$log_fd 2>&1
  fi

  if [ ! -d "$RBENV_ROOT/versions/$RUBY_VERSION" ]; then
    echo "$RBENV_ROOT/versions/$RUBY_VERSION doesn't exist ... creating..." >&$log_fd 2>&1
    mkdir $RBENV_ROOT/versions/$RBENV_VERSION >&$log_fd 2>&1
  fi

  # check if ruby version is installed
  if [[ ! `rbenv version | grep $RUBY_VERSION` ]]; then
    echo "installing ruby 2.1.4" >&$log_fd 2>&1
    rbenv install $RUBY_VERSION >&$log_fd 2>&1
    rbenv global $RUBY_VERSION >&$log_fd 2>&1

    if [ ! -d "$RBENV_ROOT/versions/$RUBY_VERSION/etc" ]; then
      echo "$RBENV_ROOT/versions/$RUBY_VERSION/etc doesn't exist ... creating..." >&$log_fd 2>&1
      mkdir $RBENV_ROOT/versions/$RUBY_VERSION/etc >&$log_fd 2>&1
    fi

  else
    echo "ruby $RUBY_VERSION already exists... skipping!" >&$log_fd 2>&1
  fi
  (( STATUS += 35 ))
  echo $STATUS
}

While the install itself can fail at anytime on the new VM, I'm screwed if rbenv installs, but nothing else does (like ruby-build) or the $PATH, etc.

Would it make more sense to just encase every command in it's own if statement outside of the initial if which rbenv, or is there a more robust way to ensure the install completes successfully?

1

There are 1 answers

0
Ram Saiegh On

You can actually perform this task more easily using configuration management tools such as Ansible, puppet or Chef. Instead of trying to specify "how" to check and use endless IF statement, you can specify "what" to check and use existing framework to do so.

For example, in Ansible you can specify to update cache & install latest version of foo using apt module:

- hosts: all
  remote_user: root
  tasks:
  - name: Install the package foo
    apt:
      name: foo
      state: present
      update_cache: yes

More information