Module: Mortar::Local::InstallUtil

Includes:
Helpers
Included in:
Controller, Java, Jython, Pig, Python
Defined in:
lib/mortar/local/installutil.rb

Defined Under Namespace

Classes: BindingClazz

Instance Method Summary collapse

Methods included from Helpers

#action, #ask, #confirm, #copy_if_not_present_at_dest, #default_host, #deprecate, #display, #display_header, #display_object, #display_row, #display_table, #display_with_indent, #download_to_file, #ensure_dir_exists, #error, error_with_failure, error_with_failure=, extended, extended_into, #format_bytes, #format_date, #format_with_bang, #full_host, #get_terminal_environment, #home_directory, #host, #hprint, #hputs, included, included_into, #installed_with_omnibus?, #json_decode, #json_encode, #line_formatter, #longest, #output_with_bang, #pending_github_team_state_message, #quantify, #redisplay, #retry_on_exception, #running_on_a_mac?, #running_on_windows?, #set_buffer, #shell, #spinner, #status, #string_distance, #styled_array, #styled_error, #styled_hash, #styled_header, #suggestion, #test_name, #ticking, #time_ago, #truncate, #warning, #with_tty, #write_to_file

Instance Method Details

#download_file(url, dest_file_path, command = nil) ⇒ Object

Downloads the file at a specified url into the supplied directory



115
116
117
118
119
120
121
122
# File 'lib/mortar/local/installutil.rb', line 115

def download_file(url, dest_file_path, command=nil)
  response = get_resource(url, command)
  
  File.open(dest_file_path, "wb") do |dest_file|
    dest_file.write(response.body)
  end

end

#ensure_mortar_local_directory(relative_dir) ⇒ Object



69
70
71
# File 'lib/mortar/local/installutil.rb', line 69

def ensure_mortar_local_directory(relative_dir)
  FileUtils.mkdir_p(File.join(local_install_directory, relative_dir))
end

#extract_tgz(tgz_path, dest_dir) ⇒ Object

Given a path to a foo.tgz or foo.tar.gz file, extracts its contents to the specified output directory



100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/mortar/local/installutil.rb', line 100

def extract_tgz(tgz_path, dest_dir)
  FileUtils.mkdir_p(dest_dir)
  Gem::Package::TarReader.new(Zlib::GzipReader.open(tgz_path)).each do |entry|
    entry_path = File.join(dest_dir, entry.full_name)
    if entry.directory?
      FileUtils.mkdir_p(entry_path)
    elsif entry.file?
      File.open(entry_path, "wb") do |entry_file|
        entry_file.write(entry.read)
      end
    end
  end
end

#get_resource(url, command = nil) ⇒ Object

Perform a get request to a url and follow redirects if necessary.



125
126
127
# File 'lib/mortar/local/installutil.rb', line 125

def get_resource(url, command=nil)
  make_call(url, 'get', 0, 0, command)
end

#gitignore_template_pathObject



65
66
67
# File 'lib/mortar/local/installutil.rb', line 65

def gitignore_template_path
  File.expand_path("../../templates/project/gitignore", __FILE__)
end

#head_resource(url, command = nil) ⇒ Object

Perform a head request to a url and follow redirects if necessary.



130
131
132
# File 'lib/mortar/local/installutil.rb', line 130

def head_resource(url, command=nil)
  make_call(url, 'head', 0, 0, command)
end

#http_date_to_epoch(date_str) ⇒ Object



195
196
197
# File 'lib/mortar/local/installutil.rb', line 195

def http_date_to_epoch(date_str)
  return Time.httpdate(date_str).to_i
end

#install_date(subsection) ⇒ Object



84
85
86
87
88
89
90
91
92
# File 'lib/mortar/local/installutil.rb', line 84

def install_date(subsection)
  install_file = install_file_for(subsection)
  if File.exists?(install_file)
    File.open(install_file, "r") do |f|
      file_contents = f.read()
      file_contents.strip.to_i
    end
  end
end

#install_file_for(subdirectory) ⇒ Object



94
95
96
# File 'lib/mortar/local/installutil.rb', line 94

def install_file_for(subdirectory)
  File.join(local_install_directory, subdirectory, "install-date.txt")
end

#is_newer_version(subdir, url, command = nil) ⇒ Object

Given a subdirectory where we have installed some software and a url to the tgz file it’s sourced from, check if the remote version is newer than the installed version



212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/mortar/local/installutil.rb', line 212

def is_newer_version(subdir, url, command=nil)
  existing_install_date = install_date(subdir)
  if not existing_install_date then
    # There is no existing install
    return true
  end
  remote_archive_date = url_date(url, command)
  if not remote_archive_date
    return false
  end
  return existing_install_date < remote_archive_date
end

#jython_cache_directoryObject



61
62
63
# File 'lib/mortar/local/installutil.rb', line 61

def jython_cache_directory
  jython_directory + "/cachedir"
end

#jython_directoryObject



57
58
59
# File 'lib/mortar/local/installutil.rb', line 57

def jython_directory
  local_install_directory + "/jython"
end

#local_install_directoryObject



41
42
43
# File 'lib/mortar/local/installutil.rb', line 41

def local_install_directory
  ENV.fetch('MORTAR_LOCAL_DIR', File.join(project_root, local_install_directory_name))
end

#local_install_directory_nameObject



31
32
33
# File 'lib/mortar/local/installutil.rb', line 31

def local_install_directory_name
  ".mortar-local"
end

#local_log_dirObject



45
46
47
# File 'lib/mortar/local/installutil.rb', line 45

def local_log_dir
  project_root + "/logs"
end

#local_project_gitignoreObject



53
54
55
# File 'lib/mortar/local/installutil.rb', line 53

def local_project_gitignore
  project_root + "/.gitignore"
end

#local_udf_log_dirObject



49
50
51
# File 'lib/mortar/local/installutil.rb', line 49

def local_udf_log_dir
  local_log_dir + "/udf"
end

#make_call(url, call_func, redirect_times = 0, errors = 0, command = nil) ⇒ Object

Make a request to a mortar resource url. Check response for a redirect and if necessary call the new url. Excon doesn’t currently support automatically following redirects. Adds parameter that checks an environment variable to identify the test making this call (if being run by a test).



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/mortar/local/installutil.rb', line 139

def make_call(url, call_func, redirect_times=0, errors=0, command=nil)
  if redirect_times >= 5
    raise RuntimeError, "Too many redirects.  Last url: #{url}"
  end

  if errors >= 5
    raise RuntimeError, "Server Error at #{url}"
  end

  
  query = {}
  if test_name
    query[:test_name] = test_name
  end
  if command
    query[:command] = command
    if Mortar::Auth.has_credentials
      query[:user] = Mortar::Auth.user
    end
  end

  headers = {'User-Agent' => Mortar::USER_AGENT}
  if call_func == 'head'
    response = Excon.head( url, 
                          :headers => headers,
                          :query => query
                         )
  elsif call_func == 'get'
    response = Excon.get( url, 
                          :headers => headers,
                          :query => query
                        )
  else
    raise RuntimeError, "Unknown call type: #{call_func}"
  end

  case response.status
  when 300..303 then 
    make_call(response.headers['Location'], call_func, redirect_times+1, errors)
  when 500..599 then
    sleep(make_call_sleep_seconds)
    make_call(url, call_func, redirect_times, errors+1)
  else
    response
  end
end

#make_call_sleep_secondsObject



186
187
188
# File 'lib/mortar/local/installutil.rb', line 186

def make_call_sleep_seconds
  2
end

#note_install(subdirectory) ⇒ Object

Drops a marker file for an installed package, used to help determine if updates should be performed



75
76
77
78
79
80
81
82
# File 'lib/mortar/local/installutil.rb', line 75

def note_install(subdirectory)
  install_file = install_file_for(subdirectory)
  File.open(install_file, "w") do |install_file|
    # Write out the current epoch so we know when this
    # dependency was installed
    install_file.write("#{Time.now.to_i}\n")
  end
end

#osx?Boolean

Returns:

  • (Boolean)


190
191
192
193
# File 'lib/mortar/local/installutil.rb', line 190

def osx?
  os_platform_name = RbConfig::CONFIG['target_os']
  return os_platform_name.start_with?('darwin')
end

#project_rootObject



35
36
37
38
39
# File 'lib/mortar/local/installutil.rb', line 35

def project_root
  # note: assumes that CWD is the project root, is
  # this a safe assumption?
  Dir.getwd
end

#render_script_template(template, template_params) ⇒ Object



244
245
246
247
# File 'lib/mortar/local/installutil.rb', line 244

def render_script_template(template, template_params)
  erb = ERB.new(File.read(template), 0, "%<>")
  erb.result(BindingClazz.new(template_params).get_binding)
end

#reset_local_logsObject



256
257
258
259
260
261
262
# File 'lib/mortar/local/installutil.rb', line 256

def reset_local_logs
  if File.directory? local_log_dir
    FileUtils.rm_rf local_log_dir
  end
  Dir.mkdir local_log_dir
  Dir.mkdir local_udf_log_dir
end

#run_templated_script(template, template_params) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/mortar/local/installutil.rb', line 225

def run_templated_script(template, template_params)
  # Insert standard template variables
  template_params['project_home'] = File.expand_path("..", local_install_directory)
  template_params['local_install_dir'] = local_install_directory

  unset_hadoop_env_vars
  reset_local_logs
  # Generate the script for running the command, then
  # write it to a temp script which will be exectued
  script_text = render_script_template(template, template_params)
  script = Tempfile.new("mortar-")
  script.write(script_text)
  script.close(false)
  FileUtils.chmod(0755, script.path)
  system(script.path)
  script.unlink
  return (0 == $?.to_i)
end

#unset_hadoop_env_varsObject

so Pig doesn’t try to load the wrong hadoop jar/configuration this doesn’t mess up the env vars in the terminal, just this process (ruby)



251
252
253
254
# File 'lib/mortar/local/installutil.rb', line 251

def unset_hadoop_env_vars
  ENV['HADOOP_HOME'] = ''
  ENV['HADOOP_CONF_DIR'] = ''
end

#url_date(url, command = nil) ⇒ Object



199
200
201
202
203
204
205
206
207
# File 'lib/mortar/local/installutil.rb', line 199

def url_date(url, command=nil)
  result = head_resource(url, command)
  last_modified = result.get_header('Last-Modified')
  if last_modified
    http_date_to_epoch(last_modified)
  else
    nil
  end
end