Module: CommonFunctions
- Defined in:
- lib/common_functions.rb
Overview
A helper module that aggregates functions that are not part of Neptune’s core functionality. Specifically, this module contains methods to scp files to other machines and the ability to read YAML files, which are often needed to determine which machine should be used for computation or to copy over code and input files.
Class Method Summary collapse
-
.get_from_yaml(keyname, tag, required = true) ⇒ Object
Given the AppScale keyname, reads the associated YAML file and returns the contents of the given tag.
-
.get_random_alphanumeric(length = 10) ⇒ Object
Returns a random string composed of alphanumeric characters, as long as the user requests.
-
.get_secret_key(keyname, required = true) ⇒ Object
Returns the secret key needed for communication with AppScale’s Shadow node.
-
.scp_file(local_file_loc, remote_file_loc, target_ip, public_key_loc, is_dir = false) ⇒ Object
Performs the actual remote copying of files: given the IP address and other information from scp_to_shadow, attempts to use scp to copy the file over.
-
.scp_to_shadow(local_file_loc, remote_file_loc, keyname, is_dir = false) ⇒ Object
Copies a file to the Shadow node (head node) within AppScale.
-
.shell(cmd) ⇒ Object
Executes a command and returns the result.
Class Method Details
.get_from_yaml(keyname, tag, required = true) ⇒ Object
Given the AppScale keyname, reads the associated YAML file and returns the contents of the given tag. The required flag (default value is true) indicates whether a value must exist for this tag: if set to true, this method aborts if the value doesn’t exist or the YAML file is malformed. If the required flag is set to false, it returns nil in either scenario instead.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/common_functions.rb', line 108 def self.get_from_yaml(keyname, tag, required=true) location_file = File.("~/.appscale/locations-#{keyname}.yaml") if !File.exists?(location_file) raise BadConfigurationException.new("An AppScale instance is not " + "currently running with the provided keyname, \"#{keyname}\".") end begin tree = YAML.load_file(location_file) rescue ArgumentError if required abort("The yaml file you provided was malformed. Please correct any" + " errors in it and try again.") else return nil end end value = tree[tag] if value.nil? and required abort("The file #{location_file} is in the wrong format and doesn't" + " contain a #{tag} tag. Please make sure the file is in the correct" + " format and try again.") end return value end |
.get_random_alphanumeric(length = 10) ⇒ Object
Returns a random string composed of alphanumeric characters, as long as the user requests.
33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/common_functions.rb', line 33 def self.get_random_alphanumeric(length=10) random = "" possible = "0123456789abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVWXYZ" possibleLength = possible.length length.times { |index| random << possible[Kernel.rand(possibleLength)] } return random end |
.get_secret_key(keyname, required = true) ⇒ Object
Returns the secret key needed for communication with AppScale’s Shadow node. This method is a nice frontend to the get_from_yaml function, as the secret is stored in a YAML file.
142 143 144 |
# File 'lib/common_functions.rb', line 142 def self.get_secret_key(keyname, required=true) return CommonFunctions.get_from_yaml(keyname, :secret, required) end |
.scp_file(local_file_loc, remote_file_loc, target_ip, public_key_loc, is_dir = false) ⇒ Object
Performs the actual remote copying of files: given the IP address and other information from scp_to_shadow, attempts to use scp to copy the file over. Aborts if the scp fails, which can occur if the network is down, if a bad keyname is provided, or if the wrong IP is given. If the user specifies that the file to copy is actually a directory, we append the -r flag to scp as well.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/common_functions.rb', line 66 def self.scp_file(local_file_loc, remote_file_loc, target_ip, public_key_loc, is_dir=false) local_file_loc = File.(local_file_loc) ssh_args = "-o StrictHostkeyChecking=no 2>&1" ssh_args << " -r " if is_dir public_key_loc = File.(public_key_loc) cmd = "scp -i #{public_key_loc} #{ssh_args} #{local_file_loc} root@#{target_ip}:#{remote_file_loc}" cmd << "; echo $? >> ~/.appscale/retval" retval_loc = File.("~/.appscale/retval") FileUtils.rm_f(retval_loc) begin Timeout::timeout(-1) { CommonFunctions.shell("#{cmd}") } rescue Timeout::Error abort("Remotely copying over files failed. Is the destination machine" + " on and reachable from this computer? We tried the following" + " command:\n\n#{cmd}") end loop { break if File.exists?(retval_loc) Kernel.sleep(5) } retval = (File.open(retval_loc) { |f| f.read }).chomp if retval != "0" abort("\n\n[#{cmd}] returned #{retval} instead of 0 as expected. Is " + "your environment set up properly?") end return cmd end |
.scp_to_shadow(local_file_loc, remote_file_loc, keyname, is_dir = false) ⇒ Object
Copies a file to the Shadow node (head node) within AppScale. The caller specifies the local file location, the destination where the file should be placed, and the name of the key to use. The keyname is typically specified by the Neptune job given, but defaults to ”appscale” if not provided.
52 53 54 55 56 57 |
# File 'lib/common_functions.rb', line 52 def self.scp_to_shadow(local_file_loc, remote_file_loc, keyname, is_dir=false) shadow_ip = CommonFunctions.get_from_yaml(keyname, :shadow) ssh_key = File.("~/.appscale/#{keyname}.key") CommonFunctions.scp_file(local_file_loc, remote_file_loc, shadow_ip, ssh_key, is_dir) end |
.shell(cmd) ⇒ Object
Executes a command and returns the result. Is needed to get around Flexmock’s inability to mock out Kernel:‘ (the standard shell exec method).
26 27 28 |
# File 'lib/common_functions.rb', line 26 def self.shell(cmd) return `#{cmd}` end |