예제 #1
0
def destroy(config, args):
    """Remove project from a node with all related services and 
    files."""
    log = logging.getLogger('kraftwerk.destroy')
    if confirm("Remove project %s from node %s along with all services and data?" % 
            (args.project.name, args.node.hostname)):
        args.node.ssh(config.template("scripts/project_destroy.sh", project=args.project))
        print "Project %s removed from node %s" % \
            (args.project.name, args.node)
        for service in args.project.services(args.node):
            args.node.ssh(service.destroy_script)
예제 #2
0
def load(config, args):
    """Load a timestamped dumpdir from the same node. (No support yet
    for user provided dumps). To load data from another node use
    `sync-services`."""
    if not confirm("WARNING: This isn't considered production ready just yet. Continue?"):
        return
    if not args.no_backup:
        timestamp = args.project.dump(args.node)
        print "Pre-load backup: %s" % args.project.dump_path(timestamp)
    args.project.load(args.node, args.timestamp)
    print "Service data from %s loaded at %s" % (args.timestamp, args.node.hostname)
예제 #3
0
def sync_services(config, args):
    """Snapshot service data and restore on another node. This is a 
    destructive action. Kraftwerk does an additional dump before 
    loading new data just in case."""
    if confirm("WARNING: This isn't considered production ready just yet. Continue?"):
        timestamp = args.project.sync_services(args.srcnode, args.destnode)
예제 #4
0
def create_node(config, args):
    """Commissions a new server node."""
    log = logging.getLogger('kraftwerk.create-node')

    if 'pubkey' in config:
        pubkey_paths = [config["pubkey"]]
    else:
        pubkey_paths = [os.path.join(os.environ['HOME'], '.ssh', f) for f \
            in ['id_rsa.pub', 'id_dsa.pub']]

    for path in pubkey_paths:
        if os.path.exists(path):
            print 'SSH public key: %s' % path
            with open(path) as fp:
                pubkey = fp.read().strip()
            break
    else:
        pubkey = raw_input('Your SSH public key (for root login): ')
    
    if not re.search(r'^[a-z0-9.-]+$', args.hostname):
        raise CommandError(
            "Invalid hostname (must contain only letters, numbers, ., and -): %r"
            % args.hostname)
    
    # Query driver for size, image, and location
    
    image_id = str(getattr(args, 'image-id', config["image_id"]))
    for i in config.driver.list_images():
        if str(i.id) == image_id:
            image = i
            break
    else:
        sys.exit("Image %s not found for this provider. Aborting." % image_id)

    size_id = str(getattr(args, 'size_id', config["size_id"]))
    for s in config.driver.list_sizes():
        if str(s.id) == size_id:
            size = s
            break
    else:
        sys.exit("Size %s not found for this provider. Aborting." % size_id)
        
    location_id = str(getattr(args, 'location-id', config.get("location_id", "0")))
    if location_id != 'None':
        for l in config.driver.list_locations():
            if str(l.id) == location_id:
                location = l
                break
        else:
            sys.exit("Location %s not found for this provider. Aborting." % location_id)
    else:
        location = None
    
    if isinstance(config.driver, ec2.EC2NodeDriver):
        extra = dict(ex_userdata="""#!/bin/bash
echo '%s' > /root/.ssh/authorized_keys""" % pubkey)
        if not "keyname" in config:
            config["keyname"] = raw_input("EC2 Key Pair [default=\"default\"]: ") or "default"
        extra.update(ex_keyname=config["keyname"])
        if 'securitygroup' in config:
            extra.update(ex_securitygroup=config["securitygroup"])
    elif isinstance(config.driver, rackspace.RackspaceNodeDriver):
        extra = dict(ex_files={'/root/.ssh/authorized_keys': pubkey})
    elif isinstance(config.driver, linode.LinodeNodeDriver):
        from libcloud.base import NodeAuthSSHKey
        extra = dict(auth=NodeAuthSSHKey(pubkey))
    
    create_info = dict(name=args.hostname, location=location,
        image=image, size=size, **extra)
    node = config.driver.create_node(**create_info)
    public_ip = node.public_ip
    
    # Poll the node until it has a public ip
    while not public_ip:
        time.sleep(3)
        for node_ in config.driver.list_nodes():
            if node.id == node_.id and node_.public_ip:
                public_ip = node_.public_ip[0]

    if type(public_ip) == list:
        public_ip = public_ip[0]

    # At least EC2 passes only back hostname
    if not IP_RE.match(public_ip):
        from socket import gethostbyname
        public_ip = gethostbyname(public_ip)

    if confirm("Create /etc/hosts entry?"):
        from kraftwerk.etchosts import set_etchosts
        set_etchosts(args.hostname, public_ip)
    
    print u"Node %s (%s)" % (args.hostname, public_ip)
    print u"Run 'kraftwerk setup-node %s'" % args.hostname