본문 바로가기
Tools

Jobs for you

by wycho 2020. 10. 22.

tmux-cssh 와 같이 여러 서버에 명령을 내릴 때, 서버에 접속하지 않고 명령을 보내서 실행이 되도록 Fabric 라이브러리를 사용하여 만들었다. 프로그램을 설치하거나, 공통 스토리지의 마운트, 작업을 실행할 때 유용하게 사용할 수 있다. Connection에서 host="root@192.168.0.xx" 로 넣어주면 root로도 명령을 내릴 수 있다.

 

사용방법은 간단하다. 실행 파일 뒤쪽에 명령어를 넣어주면 하나의 명령어로 인식하기 때문에 띄어쓰기도 가능다. Pipeline ( | )으로 이어지는 명령어는 " " 안에 넣어준다.

$ j4u.py your command
$ j4u.py "cat read.txt | wc -l"

 

$ cat j4y.py
#! /usr/bin/env python3

from fabric import Connection
import sys
import parmap

def connect_server(ip,cmd):
    result=Connection(host="user@192.168.0."+str(ip), connect_kwargs={"password": "PASSWORD"}).run(cmd, hide=True)
    msg = "{0.connection.host} {0.stdout}".format(result).rstrip()

    return msg

def main(ip,cmd):
    try:
        msg=connect_server(ip,cmd)
    except:
        msg=None
        #msg='ERROR: 192.168.0.'+str(ip)
    return msg
    
if __name__=='__main__':
    cmd=' '.join(sys.argv[1:])
    server=range(11,31)

    if cmd=='run':
        cmd='ps -e|grep python3.6|wc -l'
    elif cmd=='pk':
        cmd='pkill python3.6'
    elif cmd=='cmd':
        cmd='ps -C python3.6 -o %cpu,%mem,cmd --sort=-%cpu'
    elif cmd=='hdd1':
        cmd='df|grep hdd1'
        
    msgs=parmap.map(main,server,cmd,pm_pbar=False,pm_processes=len(server))

    msgs=filter(None,msgs)
    
    msg='\n'.join(msgs)
    print(msg)

j4u.py
0.00MB

 

비균등한 작업 수로 명령을 내려야 할 때 사용하는 방법도 있다. 작업 수는 exponentially 증가한다.

#! /usr/bin/env python3

from fabric import Connection
import sys
import parmap
import time
from math import exp
from math import log
import re

def frange(start, stop, numelements):
    """range function for floats"""
    incr = (stop - start) / numelements
    return (start + x * incr for x in range(numelements))

def exprange(start, stop, numelements):
    """exponential range - each element is a fixed factor bigger than the previous"""
    return (exp(x) for x in frange(log(start), log(stop), numelements))

def natural_sort(l):
    convert = lambda text: int(text) if text.isdigit() else text.lower()
    alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]

    return sorted(l, key = alphanum_key)

def connect_server(ip,cmd):
    result=Connection(host="user@192.168.0."+str(ip), connect_kwargs={"password": "PASSWORD"}).run(cmd, hide=True)
    msg = "{0.connection.host} {0.stdout}".format(result).rstrip()

    return msg

def allocation(ip,cmd):
    try:
        msg=connect_server(ip,cmd)
    except:
        msg=None
    return msg

def main(arng,interval):
    front='for i in {'+str(arng[1])+'..'+str(arng[2])+'};'
    main='program -i inputFile -pos ${i}'
    cmd=front+'do echo \"'+main+'\"; done |parallel -j 1 {}'

    msg=allocation(arng[0],cmd)

    return msg

if __name__=='__main__':
    ini=11
    server=range(int(ini),61)
    head=rng[0]

    totalJob=272

    a=[]
    cl=len(server)
    limit=cl+1
    n=0
    while len(a) != limit:
        a=set(['%.0f' % x for x in exprange(1,totalJob,cl)])
        a=['0']+natural_sort(a)+[str(totalJob)]

        if len(a) < limit:
            cl = cl + 1
        elif len(a) > limit:
            cl = cl - 1
        n+=1
    print(n)

    arng=[]
    for i in range(len(a)-1):
        arng.append([rng[i],int(a[i]),int(a[i+1])-1])
    print(arng)

    start=time.time()
    msgs=parmap.map(main,arng,interval,pm_pbar=False,pm_processes=len(rng))

    print('\n\033[92mElapsed time :',time.time()-start,'sec.\033[0m\n')

 

$ job50.py
19
[[11, 0, 0], [12, 1, 1], [13, 2, 2], [14, 3, 3], [15, 4, 4], [16, 5, 5], [17, 6, 6], [18, 7, 7], [19, 8, 8], [20, 9, 9], [21, 10, 10], [22, 11, 11], [23, 12, 12], [24, 13, 13], [25, 14, 14], [26, 15, 15], [27, 16, 17], [28, 18, 18], [29, 19, 20], [30, 21, 22], [31, 23, 24], [32, 25, 26], [33, 27, 28], [34, 29, 31], [35, 32, 34], [36, 35, 37], [37, 38, 40], [38, 41, 43], [39, 44, 47], [40, 48, 51], [41, 52, 56], [42, 57, 61], [43, 62, 66], [44, 67, 72], [45, 73, 78], [46, 79, 85], [47, 86, 92], [48, 93, 100], [49, 101, 109], [50, 110, 118], [51, 119, 129], [52, 130, 140], [53, 141, 152], [54, 153, 165], [55, 166, 179], [56, 180, 195], [57, 196, 211], [58, 212, 230], [59, 231, 249], [60, 250, 271]]

 

'Tools' 카테고리의 다른 글

VisiData  (0) 2020.11.20
Find connection  (0) 2020.11.04
tmux-cssh  (0) 2020.10.22
TabView  (0) 2020.10.08
Monitoring jobs  (0) 2020.09.23

댓글