Beispiel #1
0
def rollback_vm(vm_id):
    """ Rollback and restart the virtual machine """
    auth = prox_auth(os.environ.get("PROXMOX_HOST"),
                     os.environ.get("PROXMOX_USER"),
                     os.environ.get("PROXMOX_PASS"))
    proxmox = pyproxmox(auth)

    # Rollback the machine and wait until the machine is stopped
    print "Initiating rollback to state['%s']" % os.environ.get(
        "PROXMOX_ROLLBACK_STATE")
    rollback_upid = proxmox.rollbackVirtualMachine(
        "proxmox", vm_id, os.environ.get("PROXMOX_ROLLBACK_STATE"))['data']
    status = proxmox.getNodeTaskStatusByUPID("proxmox",
                                             rollback_upid)['data']['status']
    while status == u"running":
        time.sleep(1)
        status = proxmox.getNodeTaskStatusByUPID(
            "proxmox", rollback_upid)['data']['status']
        print "Waiting for machine to shutdown"

    # Start the machine again and wait until it is running again
    print "Rollback complete, restarting machine"
    proxmox.startVirtualMachine("proxmox", vm_id)
    status = proxmox.getVirtualStatus("proxmox", vm_id)['data']['status']
    while status == u"stopped":
        time.sleep(1)
        status = proxmox.getVirtualStatus("proxmox", vm_id)['data']['status']
        print "Waiting for machine to come online"
Beispiel #2
0
import sys
sys.path.append("../src")
from pyproxmox import prox_auth,pyproxmox

a = prox_auth('pnode01','apiuser@pve', 'apipasswd')

b = pyproxmox(a)

status = b.getClusterStatus()

print(status)
Beispiel #3
0
def gimme_prox_cox():
    """Return a proxmox connection"""

    return pyproxmox.pyproxmox(pyproxmox.prox_auth(env.server_ip, 'gestion_api@pam', env.gestion_password))
Beispiel #4
0
 def login(self):
     """Connect to the proxmox cluster"""
     prox_auth = pyproxmox.prox_auth(self.url, self.username, self.password)
     pve_conn = pyproxmox.pyproxmox(prox_auth)
     self.conn = pve_conn
Beispiel #5
0
def gimme_prox_cox():
    """Return a proxmox connection"""

    return pyproxmox.pyproxmox(pyproxmox.prox_auth(env.server_ip, 'gestion_api@pam', env.gestion_password))
Beispiel #6
0
def main():

    uselxc = True
    usegui = False
    user = getpass.getuser()

    if not args.subcommand:
        print('usage: prox <command> [options] host1 host2 host3')
        print('       Please run "prox --help"')
        return False

    if args.subcommand == 'assist':
        if 'DISPLAY' in os.environ.keys() or sys.platform == 'win32':
            usegui = True

    if args.debug:
        print('Debugging ....')
        print(args, l)

    if args.subcommand in ['straaange', 'oppptions']:
        prn("This feature is not yet implemented.", usegui)
        return False

    # check/create ssh keys & agent
    check_ssh_agent()
    check_ssh_auth(user)

    # getting login and password
    #user='******'
    pwd = os.getenv('proxpw', '')
    #pwd=''
    if pwd == '':
        pwd = os.getenv('PROXPW', '')
        if pwd == '':
            pwd = getpwd("Password for '%s':" % user, usegui)
            if pwd == '':
                return False
    loginname = user + '@' + REALM

    #### TESTING ###############
    #ssh_exec(user, pwd, commands=['ls -l', 'pwd', 'ps'], 'rhino1')
    #runlist_exec(pwd, 'boner3')
    #return False

    ###### END TESTING ##############

    # ******************************************************************

    if args.subcommand in ['ssh', 'connect']:
        ret = subprocess.run("ssh -i %s/.ssh/id_rsa_prox %s" %
                             (homedir, args.hosts[0]),
                             shell=True)
        return True

    # ******************************************************************

    a = pyproxmox.prox_auth(PROXHOST, loginname, pwd, True)
    if a.ticket is None:
        prn('Could not get an authentication ticket. Wrong password?', usegui)
        return False
    p = pyproxmox.pyproxmox(a)

    pool = p.getPools()['data'][0]['poolid']
    nodelist = p.getNodes()['data']
    nodes = []
    hosttempl = {}
    templlist = []
    ourmachines = {}

    for n in nodelist:
        node = n['node']
        nodes.append(node)
        # get list of containers and VMs
        conts = p.getContainers(node)['data']
        for c in conts:
            descr = ''
            if args.subcommand in ['list', 'ls', 'show']:
                if args.contacts:
                    descr = parse_contact(p, node, c['vmid'])
            ourmachines[int(c['vmid'])] = [
                c['vmid'], c['name'], c['type'], c['status'], node,
                int(c['maxmem']) / 1024 / 1024 / 1024, c['cpus'],
                int(c['maxdisk']) / 1024 / 1024 / 1024, descr
            ]
        if args.subcommand in ['list', 'ls', 'show']:
            if args.all == True:
                vms = p.getNodeVirtualIndex(node)['data']
                for v in vms:
                    # get VM templates
                    # if v['name'].startswith('templ') or
                    # v['name'].endswith('template'): # check for vm names
                    if v['template'] == 1:
                        hosttempl[v['name']] = [node, v['vmid']]
                        templlist.append(v['name'])
                    else:
                        ourmachines[int(v['vmid'])] = [
                            v['vmid'], v['name'], 'kvm', v['status'], node, '',
                            '', '', ''
                        ]

    # list of machine ids we want to take action on
    vmids = None
    if not args.subcommand in ['list', 'ls', 'show']:
        vmids = getvmids(ourmachines, args.hosts)

    print('')

    if args.subcommand in [
            'list', 'ls', 'show'
    ] or (args.subcommand in ['start', 'stop', 'destroy'] and not vmids):
        prn(' {0: <5} {1: <20} {2: <5} {3: <9} {4: <8} {5: <5} {6: <3} {7: <5} {8: <10}'
            .format('vmid', 'name', 'type', 'status', 'node', 'mem', 'cpu',
                    'disk', ''))
        prn(' {0: <5} {1: <20} {2: <5} {3: <9} {4: <8} {5: <5} {6: <3} {7: <5} {8: <10}'
            .format('----', '--------------------', '----', '--------',
                    '-------', '-----', '---', '-----', ''))

        for k, v in sorted(ourmachines.items()):
            prn(' {0: <5} {1: <20} {2: <5} {3: <9} {4: <8} {5: <5} {6: <3} {7: <5} {8: <10}'
                .format(*v))

    # ******************************************************************

    if args.subcommand in ['assist', 'gui']:
        if not usegui:
            print('running "prox assist" command which will guide you '
                  'through a number of choices, however no GUI is available')
            return False

        chce = []
        msg = ("Running 'prox assist'! Please select from the list "
               "below or 'Cancel' and run 'prox --help' for other options. "
               "Example: 'prox new mybox1 mybox2 mybox3' will create "
               "3 Linux machines.")
        chce = easygui.choicebox(msg, __app__, [
            'New linux machine', 'New docker host', 'New virtual machine',
            'List machines', 'Start machine', 'Stop machine', 'Modify machine',
            'Destroy machine'
        ])

        if not chce:
            return False

        if chce.startswith('New '):
            args.subcommand = 'new'
            if chce != "New linux machine":
                uselxc = False
            else:
                msg = ("Please select the size of your machine. "
                       "Memory sizes are in MB, unless you add G "
                       "(e.g. 1G). Disk sizes are always in GB\n."
                       "Please start small, you can always resize.")
                title = "Configuring Machine Size"
                fieldNames = ["Memory", "# Cores", "Disk Size"]
                fieldValues = ['512M', '2', '4G']
                fieldValues = easygui.multenterbox(msg, title, fieldNames,
                                                   fieldValues)
                if fieldValues:
                    args.mem, args.cores, args.disk = fieldValues
                else:
                    return False

        elif chce.startswith('List '):
            args.subcommand = 'list'
        elif chce.startswith('Start '):
            args.subcommand = 'start'
        elif chce.startswith('Stop '):
            args.subcommand = 'stop'
        elif chce.startswith('Modify '):
            args.subcommand = 'modify'
        elif chce.startswith('Destroy '):
            args.subcommand = 'destroy'
        else:
            args.subcommand = 'assist'

    # *********************************************************
    # setting some variables for LXC containers only
    if args.subcommand in ['new', 'create', 'modify', 'mod', 'assist', 'gui']:
        if "G" in args.mem.upper():
            lxcmem = int(re.sub("[^0-9^.]", "", args.mem)) * 1024
        else:
            lxcmem = int(re.sub("[^0-9^.]", "", args.mem))
        lxccores = int(re.sub("[^0-9^.]", "", args.cores))
        lxcdisk = int(re.sub("[^0-9^.]", "", args.disk))

    # ******************************************************************

    if args.subcommand in ['start', 'run']:

        if not vmids:
            vmids.append(input('\nenter vmid to start:'))
            if vmids[-1] == '':
                prn('vmid is required', usegui)
                return False

        start_machines(p, ourmachines, vmids, usegui=False)

        pingwait(ourmachines[vmids[0]][1], 1)

    # ******************************************************************

    if args.subcommand in ['stop', 'shutdown']:
        if not vmids:
            vmids.append(input('\nnot found, enter vmid to stop:'))
            if vmids[-1] == '':
                prn("no vmid entered", usegui)
                return False
        for vmid in vmids:
            machine = ourmachines[vmid]
            if machine[3] == 'stopped':
                prn('Machine "%s" is already stopped!' % machine[1], usegui)
                continue
            if machine[2] == 'kvm':
                ret = p.stopVirtualMachine(machine[4], vmid)['data']
                if ret:
                    print(ret)
                else:
                    prn("host with id %s not yet stopped!" % vmid, usegui)
                for i in range(15):
                    time.sleep(1)
                    ret = p.getVirtualStatus(machine[4], vmid)['data']
                    prn('Machine {0: <4}: {1}, cpu: {2:.0%} '.format(
                        vmid, ret['status'], ret['cpu']))
                    if ret['status'] == 'stopped':
                        break
            else:
                ret = p.stopLXCContainer(machine[4], vmid)['data']
                print(ret)

    # ******************************************************************

    if args.subcommand in ['modify', 'mod']:
        if not vmids:
            vmids.append(input('\nnot found, enter vmid to modify:'))
            if vmids[-1] == '':
                prn("no vmid entered", usegui)
                return False
        for vmid in vmids:
            machine = ourmachines[vmid]
            if machine[2] == 'kvm':
                #ret = p.stopVirtualMachine(machine[4], vmid)['data']
                prn("currently cannot modify virtual machines.", usegui)
            else:
                #ret = p.stopLXCContainer(machine[4], vmid)['data']
                ret = p.getContainerConfig(machine[4], vmid)['data']
                rootstr = ret['rootfs']
                post_data = {}
                post_data['cpulimit'] = lxccores
                post_data['memory'] = lxcmem
                if machine[3] == 'stopped':
                    post_data['rootfs'] = re.sub(r",size=[0-9]+G",
                                                 ",size=%sG" % lxcdisk,
                                                 rootstr)
                    #volume=proxazfs:subvol-126-disk-1,size=30G
                else:
                    post_data2 = {}
                    post_data2['disk'] = 'rootfs'
                    post_data2['size'] = '%sG' % lxcdisk
                    ret = p.resizeLXCContainer(machine[4], vmid,
                                               post_data2)['data']
                    print('resize:', ret)
                ret = p.setLXCContainerOptions(machine[4], vmid,
                                               post_data)['data']
                if iserr(ret, 500):
                    prn('Error 50X, could not modify machine', usegui)
                else:
                    if ret == 0:
                        ret = p.getContainerConfig(machine[4], vmid)['data']
                        print('Machine reconfigured. New settings '
                              'cores: %s, mem: %s MB, rootfs: %s ' %
                              (ret['cpulimit'], ret['memory'], ret['rootfs']))
                    else:
                        print(ret)

    # ******************************************************************

    if args.subcommand in ['destroy', 'delete']:
        if not vmids:
            vmids.append(input('\nnot found, enter vmid to destroy:'))
            if vmids[-1] == '':
                return False
        for vmid in vmids:
            if not int(vmid) in ourmachines:
                prn('machine with id %s does not exist' % vmid)
                return False
            machine = ourmachines[vmid]
            if machine[3] != 'stopped':
                print(
                    'Machine "%s" needs to be stopped before it can be destroyed!'
                    % machine[1])
                continue
            if machine[2] == 'kvm':
                ret = p.deleteVirtualMachine(machine[4], vmid)['data']
                print(ret)
            else:
                ret = p.deleteLXCContainer(machine[4], vmid)['data']
                print(ret)

            hip = '127.0.0.1'
            try:
                hip = socket.gethostbyname(machine[1])
            except:
                pass
            ret = subprocess.run("ssh-keygen -R %s,%s > /dev/null 2>&1" %
                                 (machine[1], hip),
                                 shell=True)

    # ******************************************************************

    if args.subcommand in ['new', 'create', 'make']:

        myhosts = args.hosts
        if len(myhosts) == 0:
            msg = ("enter the hostname(s) you want to deploy (separated by "
                   "space, no domain name): ")
            myhosts = def_input(msg, usegui)
            myhosts = myhosts.split(' ')

        if not myhosts or myhosts == '':
            prn('hostname(s) are required', usegui)
            return False

        desc = 'testing'
        if len(args.hosts) == 0:
            msg = ("What is the description/purpose of the system(s)? (e.g. "
                   "testing, development, other")
            desc = def_input(msg, 'testing', usegui)

        storage = STORLOC
        if len(args.hosts) == 0:
            if yn_choice(
                    "Do you want to use local storage on host (for better performance) ?"
            ) == 'n':
                storage = STORNET

        newhostids = []

        ###############   TEST SECTION ############################

        ############################################################

        # deploy a container
        if uselxc:
            newcontid = 0
            for h in myhosts:
                mynode = random.choice(nodes)
                print('installing container on node "%s" !!! ' % mynode)
                oldcontid = newcontid
                for i in range(10):
                    newcontid = p.getClusterVmNextId()['data']
                    if oldcontid != newcontid:
                        break
                    time.sleep(1)
                prn('creating host %s with ID %s in pool %s' %
                    (h, newcontid, pool))

                post_data = {
                    'ostemplate': LXCTEMPLATE,
                    'cpulimit': lxccores,
                    'memory': lxcmem,
                    'rootfs': lxcdisk,
                    'vmid': newcontid,
                    'description': build_notes(user, pool, desc),
                    'hostname': h,
                    'password': pwd,
                    'storage': storage,
                    'pool': pool,
                    'net0': 'name=eth0,bridge=vmbr0,ip=dhcp'
                }

                ret = p.createLXCContainer(mynode, post_data)['data']
                print('    ...%s' % ret)

                newhostids.append(int(newcontid))
                ourmachines[int(newcontid)] = [
                    newcontid, h, 'lxc', 'stopped', mynode
                ]

            #if yn_choice("Do you want to start the machine(s) now?"):
            start_machines(p, ourmachines, newhostids, usegui=False)

            pingwait(myhosts[-1], 1)

            # basic bootstrapping
            idrsapub = ''
            if os.path.exists('%s/.ssh/id_rsa_prox.pub' % homedir):
                idrsapub = '%s/.ssh/id_rsa_prox.pub' % homedir
            for h in myhosts:
                # placing ssh public keys on each machine
                if idrsapub != '':
                    ssh_exec('root', pwd, [
                        'mkdir -p .ssh',
                    ], h)
                    sftp_put('root', pwd, idrsapub, '.ssh/id_rsa_prox.pub', h)
                    ssh_exec('root', pwd, [
                        'cat .ssh/id_rsa_prox.pub >> .ssh/authorized_keys',
                    ], h)
                # create homedirs at login time
                ssh_exec('root', pwd, [
                    'echo "session required pam_mkhomedir.so skel=/etc/skel/ umask=0022" >> /etc/pam.d/common-account',
                ], h)
                # add my user to /etc/sudoers.d, use a zz_ prefix to overwrite previous settings
                ssh_exec('root', pwd, [
                    'echo "%s ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/zz_%s'
                    % (user, user),
                    'chmod 440 /etc/sudoers.d/%s' % user
                ], h)
                # remove some packages
                #ssh_exec('root', pwd, ['apt-get remove -y apache2', 'apt-get autoremove'], h)

                # clean out old host keys
                hip = '127.0.0.1'
                try:
                    hip = socket.gethostbyname(h)
                except:
                    pass
                ret = subprocess.run("ssh-keygen -R %s,%s > /dev/null 2>&1" %
                                     (h, hip),
                                     shell=True)

                # add the host keys to my local known_hosts
                ret = subprocess.run(
                    "ssh-keyscan -t rsa %s >> %s/.ssh/known_hosts 2>/dev/null"
                    % (h, homedir),
                    shell=True)

            # potentially running chef knife
            loginuser = '******'
            dobootstrap = False
            if args.bootstrap:
                dobootstrap = True
            elif args.nobootstrap:
                dobootstrap = False
            else:
                if yn_choice(
                        "\nDo you want to install the SciComp base config (e.g. user login) ?"
                ):
                    dobootstrap = True
            if dobootstrap:
                loginuser = ''
                ret = easy_par(run_chef_knife, myhosts)
                # bootstrapping for user
                if idrsapub != '':
                    for h in myhosts:
                        ssh_exec(user, pwd, [
                            'mkdir -p .ssh',
                        ], h)
                        sftp_put(user, pwd, idrsapub, '.ssh/id_rsa_prox.pub',
                                 h)
                        ssh_exec(user, pwd, [
                            'cat .ssh/id_rsa_prox.pub >> .ssh/authorized_keys',
                        ], h)
            else:
                run_chef_knife('hostname')

            if args.runlist != '':
                func = functools.partial(runlist_exec, pwd)
                ret = easy_par(func, myhosts)

            prn("**** login: ssh %s%s" % (loginuser, myhosts[0]))
            ret = subprocess.run("ssh %s%s" % (loginuser, myhosts[0]),
                                 shell=True)

        else:

            # deploy a KVM VM from Image

            myimage = args.image
            if myimage == '':
                if not usegui:
                    msg = "Please enter a template name"
                    myimage = def_input(msg, ','.join(templlist))
                else:
                    msg = ("Please enter a template name or just hit enter "
                           "to select from a list:")
                    myimage = easygui.choicebox(msg, __app__,
                                                ','.join(templlist))

            if myimage == ','.join(templlist) and usegui:
                myimage = easygui.choicebox(
                    'You must select a image or template name', __app__,
                    templlist)

            if not myimage or myimage == ','.join(templlist) or myimage == '':
                prn('image is required')
                return False

            notes = build_notes(user, pool)
            for h in myhosts:
                newvmid = p.getClusterVmNextId()['data']
                prn('creating host %s with VM ID %s in pool %s' %
                    (h, newvmid, pool))
                post_data = {
                    'newid': newvmid,
                    'name': h,
                    'description': notes,
                    'pool': pool
                }
                ret = p.cloneVirtualMachine(hosttempl[myimage][0],
                                            hosttempl[myimage][1],
                                            post_data)['data']
                print('    ...' + ret)
                newhostids.append(newvmid)

            if yn_choice("Do you want to start the machine(s) now?"):
                for n in newhostids:
                    print('Starting host %s ..' % n)
                    ret = p.startVirtualMachine(hosttempl[myimage][0],
                                                n)['data']
                    print('    ...' + ret)

                pingwait(myhosts[0], 7)
            else:
                prn('Please start the host with "prox start <hostname>"',
                    usegui)

    print('')
    return os.path.dirname(os.path.realpath(sys.argv[0]))


try:
    user, pwd = open(getScriptPath() + '/creds').readline().strip().split("|")
except:
    print('Could not open creds file %s.' % getScriptPath() + '/creds')
    print('Format of creds file: username@DOMAIN|password (all in one line)')
    sys.exit()

#proxmox = ProxmoxAPI(PROXHOST, user=user, password=pwd, verify_ssl=False)

hostname = socket.gethostname()
newhost = hostname

a = pyproxmox.prox_auth(PROXHOST, user, pwd, False)
p = pyproxmox.pyproxmox(a)

mymacs = getmacs()

nodes = []
nodelist = p.getNodes()['data']
for n in nodelist:
    nodes.append(n['node'])

for node in nodes:
    vms = p.getNodeVirtualIndex(node)['data']
    for v in vms:
        j = p.getVirtualConfig(node, v['vmid'])
        mac = j['data']['net0'].split('=')[1].split(',')[0]
        if mac.upper() in mymacs:
Beispiel #8
0
    else:
        user = options.user

    if options.password == '':
        message = 'No Password given, use -p'
        nagiosExit(nagios.unknown, str(message))
    else:
        password = options.password

    if options.host == '':
        message = 'No host given, use -s'
        nagiosExit(nagios.unknown, str(message))
    else:
        host = options.host

auth = prox_auth(host, user, password)
prox = pyproxmox(auth)

# status = prox.getClusterStatus()
# print status
# config = prox.getClusterConfig()
# print config
# nextid = prox.getClusterVmNextId()
# print nextid

schedule = prox.getClusterBackupSchedule()
printdebug("Schedule(s):")
printdebug(str(schedule))
resources = prox.getClusterResources()

backup_all = False
Beispiel #9
0
def main():

    uselxc = True
    usegui = False
    user = getpass.getuser()
    
    if not args.subcommand:
        print('usage: prox <command> [options] host1 host2 host3') 
        print('       Please run "prox --help"')
        return False
    
    if args.subcommand == 'assist':
        if 'DISPLAY' in os.environ.keys() or sys.platform == 'win32':
            usegui = True
    
    if args.debug:
        print('Debugging ....')                                                  
        print(args, l)

    if args.subcommand in ['straaange', 'oppptions']:
        prn("This feature is not yet implemented.", usegui)
        return False

    # check/create ssh keys & agent
    check_ssh_agent()
    check_ssh_auth(user)    

    # getting login and password 
    #user='******'
    pwd = os.getenv('proxpw', '')
    #pwd=''    
    if pwd == '':
        pwd = os.getenv('PROXPW', '')
        if pwd == '':
            pwd = getpwd("Password for '%s':" % user, usegui)
            if pwd == '':
                return False
    loginname = user + '@' + REALM
    
    #### TESTING ###############
    #ssh_exec(user, pwd, commands=['ls -l', 'pwd', 'ps'], 'rhino1')
    #runlist_exec(pwd, 'boner3')
    #return False
    
    
    ###### END TESTING ##############
    
    # ******************************************************************

    if args.subcommand in ['ssh', 'connect']:
        ret = subprocess.run("ssh -i %s/.ssh/id_rsa_prox %s"
            % (homedir, args.hosts[0]), shell=True)
        return True
    
    # ******************************************************************
    
    a = pyproxmox.prox_auth(PROXHOST, loginname, pwd, True)
    if a.ticket is None:
        prn('Could not get an authentication ticket. Wrong password?', usegui)
        return False
    p = pyproxmox.pyproxmox(a)

    pool = p.getPools()['data'][0]['poolid']
    nodelist = p.getNodes()['data']
    nodes = []
    hosttempl = {}
    templlist = []
    ourmachines = {}

    for n in nodelist:
        node = n['node']
        nodes.append(node)
        # get list of containers and VMs
        conts = p.getContainers(node)['data']            
        for c in conts:            
            descr = ''
            if args.subcommand in ['list', 'ls', 'show']:
                if args.contacts:
                    descr = parse_contact(p,node,c['vmid'])                    
            ourmachines[int(c['vmid'])] = [c['vmid'], c[
                'name'], c['type'], c['status'], node, int(c['maxmem'])/
                1024/1024/1024, c['cpus'], int(c['maxdisk'])/1024/1024/1024, 
                descr]
        if args.subcommand in ['list', 'ls', 'show']:
            if args.all == True:
                vms = p.getNodeVirtualIndex(node)['data']
                for v in vms:
                    # get VM templates
                    # if v['name'].startswith('templ') or
                    # v['name'].endswith('template'): # check for vm names
                    if v['template'] == 1:
                        hosttempl[v['name']] = [node, v['vmid']]
                        templlist.append(v['name'])
                    else:
                        ourmachines[int(v['vmid'])] = [v['vmid'], v[
                            'name'], 'kvm', v['status'], node, '', '', '', '']

    # list of machine ids we want to take action on
    vmids = None
    if not args.subcommand in ['list', 'ls', 'show']:         
        vmids = getvmids(ourmachines, args.hosts)

    print('')
        
    if args.subcommand in ['list', 'ls', 'show'] or (
        args.subcommand in [
            'start',
            'stop',
            'destroy'] and not vmids):                
        prn(' {0: <5} {1: <20} {2: <5} {3: <9} {4: <8} {5: <5} {6: <3} {7: <5} {8: <10}'.format(
            'vmid', 'name', 'type', 'status', 'node' , 'mem', 'cpu', 'disk', ''))
        prn(' {0: <5} {1: <20} {2: <5} {3: <9} {4: <8} {5: <5} {6: <3} {7: <5} {8: <10}'.format(
            '----', '--------------------', '----', '--------', '-------', '-----', '---', '-----', ''))

        for k, v in sorted(ourmachines.items()):
            prn(' {0: <5} {1: <20} {2: <5} {3: <9} {4: <8} {5: <5} {6: <3} {7: <5} {8: <10}'.format(*v))
        
    # ******************************************************************

    if args.subcommand in ['assist', 'gui']:
        if not usegui:
            print('running "prox assist" command which will guide you '
              'through a number of choices, however no GUI is available')
            return False
            
        chce = []
        msg = ("Running 'prox assist'! Please select from the list "
               "below or 'Cancel' and run 'prox --help' for other options. "
               "Example: 'prox new mybox1 mybox2 mybox3' will create "
               "3 Linux machines.")
        chce = easygui.choicebox(msg, __app__,['New linux machine', 
        'New docker host', 'New virtual machine', 'List machines', 
        'Start machine', 'Stop machine', 'Modify machine', 
        'Destroy machine'])
        
        if not chce:
            return False
        
        if chce.startswith('New '):
            args.subcommand = 'new'
            if chce != "New linux machine":
                uselxc = False
            else:                    
                msg = ("Please select the size of your machine. "
                       "Memory sizes are in MB, unless you add G "
                       "(e.g. 1G). Disk sizes are always in GB\n."
                       "Please start small, you can always resize."
                       )
                title = "Configuring Machine Size"
                fieldNames = ["Memory", "# Cores", "Disk Size"]
                fieldValues = ['512M', '2', '4G']
                fieldValues = easygui.multenterbox(msg, title,
                        fieldNames, fieldValues)
                if fieldValues:
                    args.mem, args.cores, args.disk = fieldValues
                else:
                    return False
                                    
        elif chce.startswith('List '):
            args.subcommand = 'list'
        elif chce.startswith('Start '):
            args.subcommand = 'start'                
        elif chce.startswith('Stop '):
            args.subcommand = 'stop'
        elif chce.startswith('Modify '):
            args.subcommand = 'modify'
        elif chce.startswith('Destroy '):
            args.subcommand = 'destroy'                
        else:
            args.subcommand = 'assist'
                                    

    # *********************************************************
    # setting some variables for LXC containers only    
    if args.subcommand in ['new', 'create', 'modify', 'mod', 'assist', 'gui']:    
        if "G" in args.mem.upper():
            lxcmem = int(re.sub("[^0-9^.]", "", args.mem))*1024
        else:
            lxcmem = int(re.sub("[^0-9^.]", "", args.mem))
        lxccores = int(re.sub("[^0-9^.]", "", args.cores))
        lxcdisk = int(re.sub("[^0-9^.]", "", args.disk))    
            
    # ******************************************************************

    if args.subcommand in ['start', 'run']:

        if not vmids:
            vmids.append(input('\nenter vmid to start:'))
            if vmids[-1] == '':
                prn('vmid is required', usegui)
                return False

        start_machines(p, ourmachines, vmids, usegui=False)

        pingwait(ourmachines[vmids[0]][1],1)

    # ******************************************************************

    if args.subcommand in ['stop', 'shutdown']:
        if not vmids:
            vmids.append(input('\nnot found, enter vmid to stop:'))
            if vmids[-1] == '':
                prn("no vmid entered", usegui)
                return False
        for vmid in vmids:
            machine = ourmachines[vmid]
            if machine[3] == 'stopped':
                prn('Machine "%s" is already stopped!' % machine[1], usegui)
                continue
            if machine[2] == 'kvm':
                ret = p.stopVirtualMachine(machine[4], vmid)['data']
                if ret:
                    print(ret)
                else:
                    prn("host with id %s not yet stopped!" % vmid, usegui)
                for i in range(15):
                    time.sleep(1)
                    ret = p.getVirtualStatus(machine[4], vmid)['data']
                    prn(
                        'Machine {0: <4}: {1}, cpu: {2:.0%} '.format(
                            vmid, ret['status'], ret['cpu']))
                    if ret['status'] == 'stopped':
                        break
            else:
                ret = p.stopLXCContainer(machine[4], vmid)['data']                
                print(ret)

    # ******************************************************************

    if args.subcommand in ['modify', 'mod']:
        if not vmids:
            vmids.append(input('\nnot found, enter vmid to modify:'))
            if vmids[-1] == '':
                prn("no vmid entered", usegui)
                return False
        for vmid in vmids:
            machine = ourmachines[vmid]
            if machine[2] == 'kvm':
                #ret = p.stopVirtualMachine(machine[4], vmid)['data']
                prn("currently cannot modify virtual machines.", usegui)
            else:
                #ret = p.stopLXCContainer(machine[4], vmid)['data']
                ret = p.getContainerConfig(machine[4], vmid)['data']
                rootstr=ret['rootfs']
                post_data = {}
                post_data['cpulimit'] = lxccores
                post_data['memory'] = lxcmem
                if machine[3] == 'stopped':
                    post_data['rootfs'] = re.sub(r",size=[0-9]+G", ",size=%sG" 
                                                 % lxcdisk, rootstr)
                         #volume=proxazfs:subvol-126-disk-1,size=30G
                else:
                    post_data2 = {}
                    post_data2['disk'] = 'rootfs'
                    post_data2['size'] = '%sG' % lxcdisk
                    ret = p.resizeLXCContainer(machine[4], vmid, 
                                                post_data2)['data']
                    print('resize:',ret)
                ret = p.setLXCContainerOptions(machine[4], vmid, 
                                                 post_data)['data']
                if iserr(ret,500):
                    prn ('Error 50X, could not modify machine', usegui)
                else:
                    if ret == 0:
                        ret = p.getContainerConfig(machine[4], vmid)['data']
                        print ('Machine reconfigured. New settings '
                               'cores: %s, mem: %s MB, rootfs: %s ' 
                               % (ret['cpulimit'], ret['memory'], 
                                 ret['rootfs'])
                                )                        
                    else:
                        print(ret)
                
    # ******************************************************************

    if args.subcommand in ['destroy', 'delete']:
        if not vmids:
            vmids.append(input('\nnot found, enter vmid to destroy:'))
            if vmids[-1] == '':
                return False
        for vmid in vmids:
            if not int(vmid) in ourmachines:
                prn('machine with id %s does not exist' % vmid)
                return False
            machine = ourmachines[vmid]
            if machine[3] != 'stopped':
                print(
                'Machine "%s" needs to be stopped before it can be destroyed!' %
                    machine[1])
                continue
            if machine[2] == 'kvm':
                ret = p.deleteVirtualMachine(machine[4], vmid)['data']
                print(ret)
            else:
                ret = p.deleteLXCContainer(machine[4], vmid)['data']
                print(ret)
                
            hip = '127.0.0.1'
            try:
                hip = socket.gethostbyname(machine[1])
            except:
                pass                
            ret = subprocess.run("ssh-keygen -R %s,%s > /dev/null 2>&1" 
                 % (machine[1], hip), shell=True)                
                 
    # ******************************************************************

    if args.subcommand in ['new', 'create', 'make']:

        myhosts = args.hosts
        if len(myhosts) == 0:
            msg=("enter the hostname(s) you want to deploy (separated by "
                  "space, no domain name): ")
            myhosts = def_input(msg, usegui)
            myhosts = myhosts.split(' ')

        if not myhosts or myhosts == '':
            prn('hostname(s) are required', usegui)
            return False

        desc = 'testing'
        if len(args.hosts) == 0:
            msg=("What is the description/purpose of the system(s)? (e.g. "
                 "testing, development, other")
            desc = def_input(msg, 'testing', usegui)

        storage = STORLOC
        if len(args.hosts) == 0:
            if yn_choice(
                "Do you want to use local storage on host (for better performance) ?") == 'n':
                storage = STORNET

        newhostids = []
                
        ###############   TEST SECTION ############################
        
        ############################################################
                
        # deploy a container
        if uselxc:
            newcontid = 0
            for h in myhosts:
                mynode = random.choice(nodes)
                print('installing container on node "%s" !!! ' % mynode)
                oldcontid = newcontid
                for i in range(10):
                    newcontid = p.getClusterVmNextId()['data']
                    if oldcontid != newcontid:
                        break
                    time.sleep(1)
                prn(
                    'creating host %s with ID %s in pool %s' %
                    (h, newcontid, pool))

                post_data = {
                    'ostemplate': LXCTEMPLATE,
                    'cpulimit': lxccores,
                    'memory': lxcmem,
                    'rootfs': lxcdisk,
                    'vmid': newcontid,
                    'description': build_notes(user, pool, desc),
                    'hostname': h,
                    'password': pwd,
                    'storage': storage,
                    'pool': pool,
                    'net0': 'name=eth0,bridge=vmbr0,ip=dhcp'}

                ret = p.createLXCContainer(mynode, post_data)['data']
                print('    ...%s' % ret)

                newhostids.append(int(newcontid))
                ourmachines[int(newcontid)] = [newcontid, h, 'lxc', 
                            'stopped', mynode]
                
            #if yn_choice("Do you want to start the machine(s) now?"):
            start_machines(p, ourmachines, newhostids, usegui=False)                        
                
            pingwait(myhosts[-1],1)
                        
            # basic bootstrapping 
            idrsapub = ''
            if os.path.exists('%s/.ssh/id_rsa_prox.pub' % homedir):
                idrsapub = '%s/.ssh/id_rsa_prox.pub' % homedir            
            for h in myhosts:
                # placing ssh public keys on each machine    
                if idrsapub != '':
                    ssh_exec('root', pwd, ['mkdir -p .ssh',], h)
                    sftp_put('root', pwd, idrsapub, '.ssh/id_rsa_prox.pub', h)
                    ssh_exec('root', pwd, ['cat .ssh/id_rsa_prox.pub >> .ssh/authorized_keys',], h)
                # create homedirs at login time
                ssh_exec('root', pwd, ['echo "session required pam_mkhomedir.so skel=/etc/skel/ umask=0022" >> /etc/pam.d/common-account',], h)
                # add my user to /etc/sudoers.d, use a zz_ prefix to overwrite previous settings
                ssh_exec('root', pwd, ['echo "%s ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/zz_%s'
                    % (user, user), 'chmod 440 /etc/sudoers.d/%s' % user], h)
                # remove some packages 
                #ssh_exec('root', pwd, ['apt-get remove -y apache2', 'apt-get autoremove'], h)
                                
                # clean out old host keys
                hip = '127.0.0.1'
                try:
                    hip = socket.gethostbyname(h)            
                except:
                    pass
                ret = subprocess.run("ssh-keygen -R %s,%s > /dev/null 2>&1" 
                 % (h, hip), shell=True)
                
                # add the host keys to my local known_hosts
                ret = subprocess.run("ssh-keyscan -t rsa %s >> %s/.ssh/known_hosts 2>/dev/null" 
                 % (h, homedir), shell=True)
            
            # potentially running chef knife
            loginuser='******'
            dobootstrap = False
            if args.bootstrap:
                dobootstrap = True
            elif args.nobootstrap:
                dobootstrap = False
            else:
                if yn_choice("\nDo you want to install the SciComp base config (e.g. user login) ?"):
                    dobootstrap = True
            if dobootstrap:                    
                loginuser=''
                ret = easy_par(run_chef_knife, myhosts)
                # bootstrapping for user
                if idrsapub != '':
                    for h in myhosts:
                        ssh_exec(user, pwd, ['mkdir -p .ssh',], h)
                        sftp_put(user, pwd, idrsapub, '.ssh/id_rsa_prox.pub', h)
                        ssh_exec(user, pwd, ['cat .ssh/id_rsa_prox.pub >> .ssh/authorized_keys',], h)                
            else:
                run_chef_knife('hostname')

            if args.runlist != '':
                func = functools.partial(runlist_exec, pwd)
                ret = easy_par(func, myhosts)
            
            prn("**** login: ssh %s%s" % (loginuser,myhosts[0]))
            ret = subprocess.run("ssh %s%s"
                 % (loginuser, myhosts[0]), shell=True)
                                     
        else:
            
            # deploy a KVM VM from Image

            myimage = args.image
            if myimage == '':
                if not usegui:
                    msg="Please enter a template name"
                    myimage = def_input(msg, ','.join(templlist))
                else:
                    msg=("Please enter a template name or just hit enter "
                         "to select from a list:")
                    myimage = easygui.choicebox(msg, __app__,
                    ','.join(templlist))

            if myimage == ','.join(templlist) and usegui:
                myimage = easygui.choicebox(
                    'You must select a image or template name', __app__, templlist)

            if not myimage or myimage == ','.join(templlist) or myimage == '':
                prn('image is required')
                return False

            notes = build_notes(user, pool)
            for h in myhosts:
                newvmid = p.getClusterVmNextId()['data']
                prn(
                    'creating host %s with VM ID %s in pool %s' %
                    (h, newvmid, pool))
                post_data = {
                    'newid': newvmid, 
                    'name': h, 
                    'description': notes,
                    'pool': pool
                    }
                ret = p.cloneVirtualMachine(
                    hosttempl[myimage][0],
                    hosttempl[myimage][1],
                    post_data)['data']
                print('    ...' + ret)
                newhostids.append(newvmid)

            if yn_choice("Do you want to start the machine(s) now?"):
                for n in newhostids:
                    print('Starting host %s ..' % n)
                    ret = p.startVirtualMachine(
                        hosttempl[myimage][0], n)['data']
                    print('    ...' + ret)

                pingwait(myhosts[0],7)
            else:
                prn('Please start the host with "prox start <hostname>"', usegui)
                                
    print('')
Beispiel #10
0
 def login(self):
     """Connect to the proxmox cluster"""
     prox_auth = pyproxmox.prox_auth(self.url, self.username, self.password)
     pve_conn = pyproxmox.pyproxmox(prox_auth)
     self.conn = pve_conn
Beispiel #11
0
def getScriptPath():
    return os.path.dirname(os.path.realpath(sys.argv[0]))

try:
    user, pwd = open(getScriptPath()+'/creds').readline().strip().split("|")
except:
    print('Could not open creds file %s.' % getScriptPath()+'/creds')
    print('Format of creds file: username@DOMAIN|password (all in one line)')
    sys.exit()

#proxmox = ProxmoxAPI(PROXHOST, user=user, password=pwd, verify_ssl=False)
    
hostname=socket.gethostname()
newhost=hostname

a = pyproxmox.prox_auth(PROXHOST, user, pwd,False)
p = pyproxmox.pyproxmox(a)

mymacs = getmacs()

nodes = []
nodelist=p.getNodes()['data']
for n in nodelist:
    nodes.append(n['node'])

for node in nodes:
    vms = p.getNodeVirtualIndex(node)['data']
    for v in vms:
        j = p.getVirtualConfig(node,v['vmid'])
        mac=j['data']['net0'].split('=')[1].split(',')[0]
        if mac.upper() in mymacs:
"""


import sys
import pprint
import json
sys.path.append("../src")
from pyproxmox import prox_auth,pyproxmox



# Blacklist some VM you don't want to shutdown
# vmblacklist = []
vmblacklist = ['134','158','133']

a = prox_auth('proxmoxnode','pveadmin@pve', 'pveadmin')
# If the authentication did not generate a ticket, the process failed.
if not a.ticket: 
    sys.exit(1)
b = pyproxmox(a)

nodes = b.getNodes()
# Browse the JSON output
for node in nodes['data']:
    pprint.pprint("====== "+node['node']+" ======")
    vmindex = b.getNodeVirtualIndex(node['node'])
    for vm in vmindex['data']:
        if vm['status'] == 'running' :
            print("%s :: %s" % (vm['vmid'],node['node']))
            if  vm['vmid'] not in vmblacklist :
                print("Shutting down VM %s" % (vm['vmid']))