def up(self): """ Starts an AppScale deployment with the configuration options from the AppScalefile in the current directory. Raises: AppScalefileException: If there is no AppScalefile in the current directory. """ contents = self.read_appscalefile() # If running in a cluster environment, we first need to set up SSH keys contents_as_yaml = yaml.safe_load(contents) if not LocalState.ensure_appscalefile_is_up_to_date(): contents = self.read_appscalefile() contents_as_yaml = yaml.safe_load(contents) # Construct a run-instances command from the file's contents command = [] for key, value in contents_as_yaml.items(): if key in self.DEPRECATED_ASF_ARGS: raise AppScalefileException( "'{0}' has been deprecated. Refer to {1} to see the full changes.". format(key, NodeLayout.APPSCALEFILE_INSTRUCTIONS )) if value is True: command.append(str("--%s" % key)) elif value is False: pass else: if key == "ips_layout": command.append("--ips_layout") command.append(base64.b64encode(yaml.dump(value))) elif key == "disks": command.append("--disks") command.append(base64.b64encode(yaml.dump(value))) elif key == "user_commands": command.append("--user_commands") command.append(base64.b64encode(yaml.dump(value))) else: command.append(str("--%s" % key)) command.append(str("%s" % value)) run_instances_opts = ParseArgs(command, "appscale-run-instances").args if 'infrastructure' not in contents_as_yaml: # Generate a new keypair if necessary. if not self.valid_ssh_key(contents_as_yaml, run_instances_opts): add_keypair_command = [] if 'keyname' in contents_as_yaml: add_keypair_command.append('--keyname') add_keypair_command.append(str(contents_as_yaml['keyname'])) add_keypair_command.append('--ips_layout') add_keypair_command.append( base64.b64encode(yaml.dump(contents_as_yaml['ips_layout']))) add_keypair_opts = ParseArgs( add_keypair_command, 'appscale-add-keypair').args AppScaleTools.add_keypair(add_keypair_opts) AppScaleTools.run_instances(run_instances_opts)
def test_appscale_with_ips_layout_flag_and_success(self): # assume that ssh is running on each machine fake_socket = flexmock(name='socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args(('1.2.3.5', 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args(('1.2.3.6', 22)) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # assume that we have ssh-keygen and ssh-copy-id flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we have a ~/.appscale flexmock(os.path) os.path.should_call('exists') os.path.should_receive('exists').with_args(LocalState.LOCAL_APPSCALE_PATH) \ .and_return(True) # and assume that we don't have public and private keys already made path = LocalState.LOCAL_APPSCALE_PATH + self.keyname public_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.pub' private_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.key' os.path.should_receive('exists').with_args(public_key).and_return(False) os.path.should_receive('exists').with_args(private_key).and_return(False) # next, assume that ssh-keygen ran fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we can rename the private key flexmock(shutil) shutil.should_receive('copy').with_args(path, private_key).and_return() # finally, assume that we can chmod 0600 those files fine flexmock(os) os.should_receive('chmod').with_args(public_key, 0600).and_return() os.should_receive('chmod').with_args(path, 0600).and_return() # and assume that we can ssh-copy-id to each of the three IPs below flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also, we should be able to copy over our new public and private keys fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('id_rsa[.pub]?'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.5 appengine: 1.2.3.6 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.add_keypair(options)
def test_appscale_with_ips_layout_flag_and_success(self): # assume that ssh is running on each machine fake_socket = flexmock(name='socket') fake_socket.should_receive('connect').with_args((IP_1, 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args((IP_2, 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args((IP_3, 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args((IP_4, 22)) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # assume that we have ssh-keygen and ssh-copy-id flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we have a ~/.appscale flexmock(os.path) os.path.should_call('exists') os.path.should_receive('exists').with_args(LocalState.LOCAL_APPSCALE_PATH) \ .and_return(True) # and assume that we don't have public and private keys already made path = LocalState.LOCAL_APPSCALE_PATH + self.keyname public_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.pub' private_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.key' os.path.should_receive('exists').with_args(public_key).and_return(False) os.path.should_receive('exists').with_args(private_key).and_return(False) # next, assume that ssh-keygen ran fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we can rename the private key flexmock(shutil) shutil.should_receive('copy').with_args(path, private_key).and_return() # finally, assume that we can chmod 0600 those files fine flexmock(os) os.should_receive('chmod').with_args(public_key, 0600).and_return() os.should_receive('chmod').with_args(path, 0600).and_return() # and assume that we can ssh-copy-id to each of the three IPs below flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also, we should be able to copy over our new public and private keys fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('id_rsa[.pub]?'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = FOUR_NODE_CLUSTER argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.add_keypair(options)
def up(self): """ Starts an AppScale deployment with the configuration options from the AppScalefile in the current directory. Raises: AppScalefileException: If there is no AppScalefile in the current directory. """ contents = self.read_appscalefile() # If running in a cluster environment, we first need to set up SSH keys contents_as_yaml = yaml.safe_load(contents) if not LocalState.ensure_appscalefile_is_up_to_date(): contents = self.read_appscalefile() contents_as_yaml = yaml.safe_load(contents) # Construct a run-instances command from the file's contents command = [] for key, value in contents_as_yaml.items(): if key in self.DEPRECATED_ASF_ARGS: raise AppScalefileException( "'{0}' has been deprecated. Refer to {1} to see the full changes." .format(key, NodeLayout.APPSCALEFILE_INSTRUCTIONS)) if value is True: command.append(str("--%s" % key)) elif value is False: pass else: if key == "ips_layout": command.append("--ips_layout") command.append(base64.b64encode(yaml.dump(value))) elif key == "disks": command.append("--disks") command.append(base64.b64encode(yaml.dump(value))) elif key == "user_commands": command.append("--user_commands") command.append(base64.b64encode(yaml.dump(value))) else: command.append(str("--%s" % key)) command.append(str("%s" % value)) run_instances_opts = ParseArgs(command, "appscale-run-instances").args if 'infrastructure' not in contents_as_yaml: # Generate a new keypair if necessary. if not self.valid_ssh_key(contents_as_yaml, run_instances_opts): add_keypair_command = [] if 'keyname' in contents_as_yaml: add_keypair_command.append('--keyname') add_keypair_command.append(str( contents_as_yaml['keyname'])) add_keypair_command.append('--ips_layout') add_keypair_command.append( base64.b64encode(yaml.dump( contents_as_yaml['ips_layout']))) add_keypair_opts = ParseArgs(add_keypair_command, 'appscale-add-keypair').args AppScaleTools.add_keypair(add_keypair_opts) AppScaleTools.run_instances(run_instances_opts)