Module: Machines::Commands::Installation

Includes:
FileOperations
Included in:
Machines::Core
Defined in:
lib/machines/commands/installation.rb

Constant Summary collapse

APTGET_QUIET =
'apt-get -q -y'

Instance Method Summary collapse

Methods included from FileOperations

#append, #chmod, #chown, #copy, #create_from, #link, #mkdir, #remove, #remove_version_info, #rename, #replace, #write

Instance Method Details

#add_ppa(name, key_name) ⇒ Object

Adds a PPA source and updates apt

Examples:

add_ppa 'mozillateam/firefox-stable', 'mozilla'

Parameters:

  • name (String)

    Name of the PPA

  • key_name (String)

    What to check in apt-key list to ensure it installed



13
14
15
16
17
18
# File 'lib/machines/commands/installation.rb', line 13

def add_ppa name, key_name
  [
    Command.new("add-apt-repository ppa:#{name}", "apt-key list | grep -i #{key_name} #{echo_result}"),
    update
  ]
end

#deb(source, options) ⇒ Object

Adds a DEB source

Examples:

sudo deb 'http://dl.google.com/linux/deb/ stable main',
          key: 'https://dl-ssl.google.com/linux/linux_signing_key.pub',
          name: 'Google'

Parameters:

  • source (String)

    URL of the package. If YOUR_UBUNTU_VERSION_HERE is included then it is replaced by the Ubuntu version name

  • options (Hash)

Options Hash (options):

  • :key (String)

    URL of key

  • :name (String)

    Used to check apt-key list to ensure it installed



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/machines/commands/installation.rb', line 30

def deb source, options
  command = "echo deb #{source} >> /etc/apt/sources.list"
  if source =~ /YOUR_UBUNTU_VERSION_HERE/
    command = "expr substr `cat /etc/lsb-release | grep DISTRIB_CODENAME` 18 20 | xargs -I YOUR_UBUNTU_VERSION_HERE #{command}"
  end
  [
    Command.new(command, check_string(source.gsub(/ .*$/, ''), '/etc/apt/sources.list')),
    Command.new("wget -q #{options[:key]} -O - | apt-key add -", "apt-key list | grep -i #{options[:name]} #{echo_result}"),
    update
  ]
end

#debconf(app, setting, type, value) ⇒ Object

Preseed debconf to allow silent installs

Parameters:

  • app (String)

    Name of application to configure

  • setting (String)

    The setting to set

  • type (String)

    Data type of the value

  • value

    The value to set (Ruby types supported)



47
48
49
50
51
# File 'lib/machines/commands/installation.rb', line 47

def debconf app, setting, type, value
  command = "echo #{app} #{setting} #{type} #{value} | debconf-set-selections"
  check = "debconf-get-selections | grep #{app} #{echo_result}"
  Command.new(command, check)
end

#extract(package, options = {}) ⇒ Object

Download, extract, and remove an archive. Currently supports zip, tar.gz, tar.bz2.

Examples:

sudo extract 'http://dl.suckless.org/dwm/dwm-6.0.tar.gz'

Parameters:

  • package (String)

    Package name to extract

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :to (Optional String)

    folder to clone or extract to (defaults to /usr/local/src)



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/machines/commands/installation.rb', line 59

def extract package, options = {}
  name = File.basename(package)
  if package[/.zip/]
    cmd = 'unzip -qq'
  elsif package[/.tar.gz/]
    cmd = 'tar -zxf'
  elsif package[/.tar.bz2/]
    cmd = 'tar -jxf'
  else
    raise "extract: Unknown extension for #{package}"
  end
  dir = cmd =~ /unzip/ ? File.basename(name, '.zip') : File.basename(name).gsub(/\.tar.*/, '')
  dest = options[:to] || '/usr/local/src'
  Command.new("cd #{dest} && wget #{package} && #{cmd} #{name} && rm #{name} && cd -", check_dir("#{File.join(dest, dir)}"))
end

#gem(package, options = {}) ⇒ Object

Install a gem

Parameters:

  • package (String)

    Name of the gem

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :version (String)

    Optional version number



79
80
81
82
# File 'lib/machines/commands/installation.rb', line 79

def gem package, options = {}
  version =  " -v \"#{options[:version]}\"" if options[:version]
  Command.new("gem install #{package}#{version}", check_gem(package, options[:version]))
end

#gem_update(options = '') ⇒ Object

Update gems

Examples:

Update Rubygems

gem_update '--system'


87
88
89
# File 'lib/machines/commands/installation.rb', line 87

def gem_update options = ''
  Command.new("gem update #{options}", nil)
end

#git_clone(url, options = {}) ⇒ Object

Clone (or update) a project from a Git repository

Parameters:

  • url (String)

    URL to clone

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :to (Optional String)

    Folder to clone to

  • :tag (Optional String)

    Checkout this tag after cloning (requires :to)

  • :branch (Optional String)

    Switch this branch when cloning

Raises:

  • (ArgumentError)


97
98
99
100
101
102
103
104
105
106
107
# File 'lib/machines/commands/installation.rb', line 97

def git_clone url, options = {}
  raise ArgumentError.new('git_clone Must include a url and folder') if url.nil? || url.empty?
  raise ArgumentError.new('specifying :tag also requires :to') if options[:tag] && options[:to].nil?
  branch = "--branch #{options[:branch]} " if options[:branch]
  dir = options[:to] || url.gsub(/^.*\/|.git/, '')
  command = "test -d #{dir} && (cd #{dir} && git pull) || git clone --quiet #{branch}#{url}"
  command << " #{options[:to]}" if options[:to]
  command = Command.new(command, check_dir(options[:to]))
  command = [command, Command.new("cd #{options[:to]} && git checkout #{options[:tag]}", "git name-rev --name-only HEAD | grep #{options[:tag]}")] if options[:tag]
  command
end

#install(packages, options = {}) ⇒ Object

Installs one or more packages using apt, deb or git clone and install.sh (See extract to just uncompress tar.gz or zip files). Packages are installed separately to aid progress feedback. Ensure this is the main package as dpkg get-selections is used to validate installation.

Examples:

Install apt packages

install %w(build-essential libssl-dev mysql-server)

Download and install a deb using dpkg then remove the deb

install 'http://example.com/my_package.deb'

Download and phantomjs to /usr/local/lib and add bin/phantomjs to /usr/local/bin

install 'http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-x86_64.tar.bz2', bin: 'bin/phantomjs'

Download dwm into /usr/local/src/dwm-6.0 and install

install 'http://dl.suckless.org/dwm/dwm-6.0.tar.gz', make: true

Parameters:

  • packages (Symbol, String, Array)

    URL to download and install, string or array of apt packages

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :as (Optional Symbol)

    Specify :dpkg to download URL and run dpkg

  • :bin (Optional String)

    Specify the bin file to link to (e.g. '/bin/executable' will create a link /usr/local/bin/executable that points to /usr/local/lib/bin/executable)

  • :make (Optional Boolean)

    Set to true to run sudo make clean install



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/machines/commands/installation.rb', line 127

def install packages, options = {}
  if packages.is_a?(String)
    if packages =~ /^http:\/\//
      commands = []
      if packages =~ /\.deb$/i
        name = File.basename(packages)
        commands << Command.new("cd /tmp && wget #{packages} && dpkg -i --force-architecture #{name} && rm #{name} && cd -", nil)
      else
        commands << extract(packages, :to => '/tmp')
        name = File.basename(packages).gsub(/\.(tar|zip).*/, '')

        if options[:as] == :dpkg
          commands << Command.new("cd /tmp/#{name} && dpkg -i --force-architecture *.deb && cd - && rm -rf /tmp/#{name}", nil)
        elsif options[:bin]
          commands << rename("/tmp/#{name}", "/usr/local/lib")
          commands << link("/usr/local/lib/#{name}/#{options[:bin]}", "/usr/local/bin/#{File.basename(options[:bin])}")
        elsif options[:make]
          commands << rename("/tmp/#{name}", "/usr/local/src")
          commands << Command.new("cd /usr/local/src/#{name} && make clean install", nil)
        end
      end
      return commands
    else
      packages = [packages]
    end
  end

  if packages.is_a?(Array)
    commands = packages.map do |package|
      Command.new("#{APTGET_QUIET} install #{package}", check_package(package))
    end
  end
  commands
end

#uninstall(packages) ⇒ Object

Remove one or more Ubuntu packages

Parameters:

  • packages (Array)

    Packages to remove



164
165
166
167
168
# File 'lib/machines/commands/installation.rb', line 164

def uninstall packages
  packages.map do |package|
    Command.new("#{APTGET_QUIET} purge #{package}", check_package(package, false))
  end
end

#updateObject

Updates Ubuntu packages



171
172
173
# File 'lib/machines/commands/installation.rb', line 171

def update
  Command.new("#{APTGET_QUIET} update > /tmp/apt-update.log", check_string('Reading package lists', '/tmp/apt-update.log'))
end

#upgradeObject

Update, upgrade, autoremove, autoclean apt packages



176
177
178
179
180
181
# File 'lib/machines/commands/installation.rb', line 176

def upgrade
  # TODO: Check that check_command really checks the correct command with `echo $?`
  %w(update upgrade autoremove autoclean).map do |command|
    Command.new("#{APTGET_QUIET} #{command}", check_command('echo $?', '0'))
  end
end