def deploy(config, root_scope, remote = None, dry_run = True, ip_address = None): deploy_host = None all_names = [] if remote is None: hostname = socket.gethostname() else: hostname = remote print("Deploying on %s (dry-run = %s)" % (hostname, dry_run)) try: servers = root_scope.get_variable("Host", ["std"]).value for server in servers: all_names.append(server.name) if server.name == hostname: deploy_host = server except Exception: print("The std module is not loaded or does not contain the definition of Host") return if deploy_host is None: print("Unable to find a host to deploy on the current machine %s" % hostname) print("Host found in model: " + ", ".join(all_names)) return export = Exporter(config) json_data = export.run(root_scope, offline = True) files = export.get_offline_files() if remote is not None: ip_address = remote agent = Agent(config, False, hostname, offline = True, deploy = not dry_run, remote = ip_address) agent._offline_files = files host_id = "[%s," % deploy_host.name for item in json.loads(json_data.decode("utf-8")): if host_id in item["id"]: agent.update(Resource.deserialize(item)) if agent._queue.size() == 0: print("No configuration found for host %s" % hostname) return print("Deploying config") agent.deploy_config() #agent.close()
def get_fact(res, fact_name): """ Get the fact with the given name from the database """ cfg = Config.get() resource_id = Exporter.get_id(res) fact_value = None if cfg["config"]["offline"] == "true": fact_value = Offline.get().get_fact(resource_id, fact_name, Unknown(source = res)) else: url = cfg["config"]["server"] + "/fact/%s?id=%s" % (fact_name, resource_id) try: with request.urlopen(url) as f: fact_value = f.read().decode('utf-8') except: fact_value = Unknown(source = res) if cfg["config"]["unknown-dummy"] == "true" and isinstance(fact_value, Unknown): return dummy_value Stats.get("get fact").increment() return fact_value
def bootstrap(config): """ Bootstrap IMP on a remote server by provisioning a VM, configuring it and starting the IMP server there. """ console = logging.StreamHandler() LOGGER.addHandler(console) LOGGER.setLevel(logging.INFO) root_scope = compile_model(config) mgmt_server = get_mgmt_server_from_model(root_scope) # provision the mgmt server iaas_agent = Agent(config, False, mgmt_server.iaas.name, offline=True, deploy=True) export = Exporter(config) export.run(root_scope, offline=True) mgmt_vm_resource = Resource.get_resource(mgmt_server) iaas_agent.update(mgmt_vm_resource) print("Bootstrapping IaaS config and booting management server") while iaas_agent._queue.size() > 0: iaas_agent.deploy_config() # wait for the vm to come online get its ip print("Waiting for %s to become available" % mgmt_server.name) facts = None while facts is None: all_facts = iaas_agent.get_facts(mgmt_vm_resource) for vm_key in all_facts.keys(): if vm_key == mgmt_vm_resource.id.resource_str() and "ip_address" in all_facts[vm_key]: facts = all_facts[vm_key] if facts is None: print("No response, waiting 5s for retry") time.sleep(5) # wait for the server to respond to ssh while True: result = run("/usr/bin/ssh", ARGS + ["ec2-user@" + facts["ip_address"], "echo 'OK'"]) if result[0] == "OK": break else: time.sleep(5) # now add our ssh key to the root user deploy_key(facts["ip_address"], mgmt_vm_resource.key_value) # now recompile the model for the mgmt server and do a remote deploy Offline.get().set_facts(str(mgmt_vm_resource.id.resource_str()), facts) root_scope = compile_model(config) deploy(config, root_scope, remote=mgmt_server.name, dry_run=False, ip_address=facts["ip_address"]) ## now boot all other servers, these are already available in the root_scope of the previous compile servers = set(root_scope.get_variable("Host", ["std"]).value) vm_servers = [] for server in servers: vm_resource = Resource.get_resource(server) if vm_resource is not None: vm_servers.append(vm_resource) iaas_agent.update(vm_resource) print("Booting all other servers") while iaas_agent._queue.size() > 0: iaas_agent.deploy_config() # collect facts about all server print("Waiting for servers to become available") facts = {} while len(vm_servers) > len(facts): for vm in vm_servers: if vm.id.resource_str() not in facts: all_facts = iaas_agent.get_facts(vm) for vm_key in all_facts.keys(): if vm_key not in facts and "ip_address" in all_facts[vm_key]: Offline.get().set_facts(vm_key, all_facts[vm_key]) facts[vm_key] = all_facts[vm_key] if len(vm_servers) > len(facts): print("No response, waiting 5s for retry") time.sleep(5) # now recompile the model once again with all facts and deploy to all servers root_scope = compile_model(config) # wait for the server to come online, deploy the ssh key and deploy the config print("Waiting for the server to come online, add our key to the root user and deploy the configuration") vm_todo = list(vm_servers) while len(vm_todo) > 0: for vm in list(vm_todo): ip = facts[vm.id.resource_str()]["ip_address"] result = run("/usr/bin/ssh", ARGS + ["ec2-user@" + ip, "echo 'OK'"]) if result[0] == "OK": print("%s up" % vm.id.attribute_value) deploy_key(ip, vm.key_value) deploy(config, root_scope, remote=vm.name, dry_run=False, ip_address=ip) print("%s done" % vm.id.attribute_value) vm_todo.remove(vm) time.sleep(5) # now a final run with bootstrap off # now recompile the model once again with all facts and deploy to all servers root_scope = compile_model(config, bootstrap="false") # wait for the server to come online, deploy the ssh key and deploy the config print("Deploying final non-bootstrap configuration") vm_todo = list(vm_servers) for vm in list(vm_todo): ip = facts[vm.id.resource_str()]["ip_address"] deploy(config, root_scope, remote=vm.name, dry_run=False, ip_address=ip) vm_todo.remove(vm)
def export(options, config, compile): from Imp.export import Exporter export = Exporter(config, options) export.run(compile)