new ssh client and install_cookbook missing recipes fix
This commit is contained in:
parent
8f038aaf07
commit
f68a00bfa9
@ -47,6 +47,10 @@ def create_recipes(metafile, md, attr_id)
|
||||
cook_name = md.name.empty? ? File.basename(File.dirname(metafile)) : md.name
|
||||
|
||||
recipes_dir = File.join(File.dirname(metafile), "recipes")
|
||||
unless File.exists?(recipes_dir) and File.readable?(recipes_dir)
|
||||
puts "Recipes folder not found."
|
||||
return true
|
||||
end
|
||||
Dir.chdir(recipes_dir)
|
||||
recipes = Dir.glob("*.rb")
|
||||
|
||||
|
@ -54,6 +54,14 @@ class Ci(object):
|
||||
node.boot = ['disk', 'cdrom']
|
||||
environment.nodes.append(node)
|
||||
|
||||
node2 = Node('slave')
|
||||
node2.memory = 2048
|
||||
node2.vnc = True
|
||||
node2.disks.append(Disk(size=30*1024**3))
|
||||
node2.interfaces.append(Interface(network))
|
||||
node2.boot = ['network']
|
||||
environment.nodes.append(node2)
|
||||
|
||||
devops.build(environment)
|
||||
except Exception, e:
|
||||
logger.error("Failed to build environment: %s\n%s" % (str(e), traceback.format_exc()))
|
||||
|
@ -41,10 +41,20 @@ class HTTPClient(object):
|
||||
|
||||
|
||||
class SSHClient(object):
|
||||
class get_sudo(object):
|
||||
def __init__(self, client):
|
||||
self.client = client
|
||||
|
||||
def __enter__(self):
|
||||
self.client.sudo_mode = True
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.client.sudo_mode = False
|
||||
|
||||
def __init__(self):
|
||||
self.channel = None
|
||||
self.sudo = False
|
||||
self.sudo_mode = False
|
||||
self.sudo = self.get_sudo(self)
|
||||
|
||||
def connect_ssh(self, host, username, password):
|
||||
self.ssh_client = paramiko.SSHClient()
|
||||
@ -55,53 +65,39 @@ class SSHClient(object):
|
||||
self.ssh_client.connect(host, username=username, password=password)
|
||||
self.sftp_client = self.ssh_client.open_sftp()
|
||||
|
||||
def open_channel(self):
|
||||
if not self.channel:
|
||||
self.channel = self.ssh_client.invoke_shell()
|
||||
|
||||
def aquire_sudo(self):
|
||||
if not self.channel:
|
||||
self.open_channel()
|
||||
if not self.sudo:
|
||||
logging.info("Aquiring sudo")
|
||||
self.channel.send("sudo -s\n")
|
||||
self._recv_until("%s: " % self.username)
|
||||
self.channel.send("%s\n" % self.password)
|
||||
self._recv_until("# ")
|
||||
self.sudo = True
|
||||
|
||||
def exec_cmd(self, command, sudo=False):
|
||||
def exec_cmd(self, command):
|
||||
logging.info("Executing command: '%s'" % command)
|
||||
if not self.channel:
|
||||
self.open_channel()
|
||||
if sudo and not self.sudo:
|
||||
self.aquire_sudo()
|
||||
self.channel.send("%s\n" % command)
|
||||
if sudo or self.sudo:
|
||||
return self._recv_until("# ")
|
||||
else:
|
||||
return self._recv_until("$ ")
|
||||
chan = self.ssh_client.get_transport().open_session()
|
||||
stdin = chan.makefile('wb')
|
||||
stdout = chan.makefile('rb')
|
||||
stderr = chan.makefile_stderr('rb')
|
||||
cmd = "%s\n" % command
|
||||
if self.sudo_mode:
|
||||
cmd = 'sudo -S bash -c "%s"' % cmd.replace('"', '\\"')
|
||||
chan.exec_command(cmd)
|
||||
if stdout.channel.closed is False:
|
||||
stdin.write('%s\n' % self.password)
|
||||
stdin.flush()
|
||||
result = {
|
||||
'stdout': [],
|
||||
'stderr': [],
|
||||
'exit_status': chan.recv_exit_status()
|
||||
}
|
||||
for line in stdout:
|
||||
result['stdout'].append(line)
|
||||
for line in stderr:
|
||||
result['stderr'].append(line)
|
||||
|
||||
def mkdir(self, path, sudo=False):
|
||||
return result
|
||||
|
||||
def mkdir(self, path):
|
||||
logging.info("Creating directory: %s" % path)
|
||||
if not sudo:
|
||||
self.sftp_client.mkdir(path)
|
||||
else:
|
||||
self.open_channel()
|
||||
self.aquire_sudo()
|
||||
self.channel.send("mkdir %s\n" % path)
|
||||
self._recv_until("# ")
|
||||
return self.exec_cmd("mkdir %s\n" % path)
|
||||
|
||||
|
||||
def rmdir(self, path, sudo=False):
|
||||
def rmdir(self, path):
|
||||
logging.info("Removing directory: %s" % path)
|
||||
if not sudo:
|
||||
self.ssh_client.exec_command("rm -rf %s" % path)
|
||||
else:
|
||||
self.open_channel()
|
||||
self.aquire_sudo()
|
||||
self.channel.send("rm -rf %s\n" % path)
|
||||
self._recv_until("# ")
|
||||
return self.exec_command("rm -rf %s" % path)
|
||||
|
||||
def scp(self, frm, to):
|
||||
logging.info("Copying file: %s -> %s" % (frm, to))
|
||||
@ -119,9 +115,9 @@ class SSHClient(object):
|
||||
curdir = remote_root
|
||||
else:
|
||||
curdir = os.path.join(remote_root, rel)
|
||||
self.sftp_client.mkdir(curdir)
|
||||
self.mkdir(curdir)
|
||||
for fl in fls:
|
||||
self.sftp_client.put(
|
||||
self.scp(
|
||||
os.path.join(root, fl),
|
||||
os.path.join(curdir, fl)
|
||||
)
|
||||
@ -129,10 +125,3 @@ class SSHClient(object):
|
||||
def disconnect(self):
|
||||
self.sftp_client.close()
|
||||
self.ssh_client.close()
|
||||
|
||||
def _recv_until(self, data):
|
||||
buff = ""
|
||||
while not buff.endswith(data):
|
||||
resp = self.channel.recv(9999)
|
||||
buff += resp
|
||||
return buff
|
||||
|
@ -38,7 +38,49 @@ class TestNode(TestCase):
|
||||
cookbook_remote_path = os.path.join(SAMPLE_REMOTE_PATH, "sample-cook")
|
||||
release_remote_path = os.path.join(SAMPLE_REMOTE_PATH, "sample-release.json")
|
||||
|
||||
host = str(ci.environment.node['admin'].ip_address)
|
||||
logging.info("Starting slave node")
|
||||
admin_node = ci.environment.node['admin']
|
||||
admin_ip = admin_node.ip_address
|
||||
node = ci.environment.node['slave']
|
||||
node.start()
|
||||
|
||||
slave_id = node.interfaces[0].mac_address.replace(":", "").upper()
|
||||
|
||||
while True:
|
||||
logging.info("Waiting for slave agent to run...")
|
||||
nodes = json.loads(self.client.get(
|
||||
"http://%s:8000/api/nodes" % admin_ip
|
||||
))
|
||||
time.sleep(15)
|
||||
if len(nodes) > 0:
|
||||
logging.info("Node found")
|
||||
break
|
||||
|
||||
cluster = json.loads(self.client.post(
|
||||
"http://%s:8000/api/clusters" % admin_ip,
|
||||
data='{ "name": "MyOwnPrivateCluster", "release": 1 }',
|
||||
log=True
|
||||
))
|
||||
|
||||
resp = json.loads(self.client.put(
|
||||
"http://%s:8000/api/clusters/1" % admin_ip,
|
||||
data='{ "nodes": ["%s"] }' % slave_id
|
||||
))
|
||||
|
||||
cluster = json.loads(self.client.get(
|
||||
"http://%s:8000/api/clusters/1" % admin_ip
|
||||
))
|
||||
if len(cluster["nodes"]) == 0:
|
||||
raise ValueError("Failed to add node into cluster")
|
||||
|
||||
resp = json.loads(self.client.put(
|
||||
"http://%s:8000/api/nodes/%s" % (admin_ip, slave_id),
|
||||
data='{ "new_roles": [1, 2], "redeployment_needed": true }'
|
||||
))
|
||||
if len(resp["new_roles"]) == 0:
|
||||
raise ValueError("Failed to assign roles to node")
|
||||
|
||||
"""
|
||||
self.remote.connect_ssh(host, "ubuntu", "r00tme")
|
||||
|
||||
self.remote.rmdir(cookbook_remote_path)
|
||||
@ -100,56 +142,28 @@ class TestNode(TestCase):
|
||||
|
||||
for cmd in commands:
|
||||
self.remote.exec_cmd(cmd)
|
||||
|
||||
cluster = json.loads(self.client.post(
|
||||
"http://%s:8000/api/clusters" % host,
|
||||
data='{ "name": "MyOwnPrivateCluster", "release": 1 }',
|
||||
log=True
|
||||
))
|
||||
|
||||
nodes = json.loads(self.client.get(
|
||||
"http://%s:8000/api/nodes" % host
|
||||
))
|
||||
if len(nodes) == 0:
|
||||
raise ValueError("Nodes list is empty")
|
||||
node_id = nodes[0]['id']
|
||||
|
||||
resp = json.loads(self.client.put(
|
||||
"http://%s:8000/api/clusters/1" % host,
|
||||
data='{ "nodes": ["%s"] }' % node_id
|
||||
))
|
||||
|
||||
cluster = json.loads(self.client.get(
|
||||
"http://%s:8000/api/clusters/1" % host
|
||||
))
|
||||
if len(cluster["nodes"]) == 0:
|
||||
raise ValueError("Failed to add node into cluster")
|
||||
|
||||
resp = json.loads(self.client.put(
|
||||
"http://%s:8000/api/nodes/%s" % (host, node_id),
|
||||
data='{ "new_roles": [1, 2], "redeployment_needed": true }'
|
||||
))
|
||||
if len(resp["new_roles"]) == 0:
|
||||
raise ValueError("Failed to assign roles to node")
|
||||
|
||||
"""
|
||||
logging.info("Provisioning...")
|
||||
task = json.loads(self.client.put(
|
||||
"http://%s:8000/api/clusters/1/changes/" % host,
|
||||
"http://%s:8000/api/clusters/1/changes/" % admin_ip,
|
||||
log=True
|
||||
))
|
||||
task_id = task['task_id']
|
||||
logging.info("Task created: %s" % task_id)
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
while True:
|
||||
try:
|
||||
task = json.loads(self.client.get(
|
||||
"http://%s:8000/api/tasks/%s/" % (host, task_id)
|
||||
"http://%s:8000/api/tasks/%s/" % (admin_ip, task_id)
|
||||
))
|
||||
self.check_tasks(task)
|
||||
break
|
||||
except StillPendingException:
|
||||
pass
|
||||
|
||||
"""
|
||||
# check if recipes executed
|
||||
ret = self.remote.exec_cmd("test -f /tmp/chef_success && echo 'SUCCESS'")
|
||||
if not "SUCCESS" in ret.split("\r\n")[1:]:
|
||||
@ -168,8 +182,8 @@ class TestNode(TestCase):
|
||||
if not gen_pwd or gen_pwd == 'password':
|
||||
raise Exception("Password generation failed!")
|
||||
|
||||
|
||||
self.remote.disconnect()
|
||||
"""
|
||||
|
||||
def check_tasks(self, task):
|
||||
if task['status'] != 'SUCCESS':
|
||||
|
Loading…
Reference in New Issue
Block a user