ãã®ããã°æçš¿ãšãã®ãã¹ãŠã®ãªã³ã¯ãæåã«èªãã ããšã確èªããŠãã ããïŒïŒ httpïŒ //bitprophet.org/blog/2017/04/17/fabric-2-alpha-beta
ããã¯ãæ¢åã®ãã±ããã§ã«ããŒãããŠããªãåé¡ã«ã€ããŠã®ãã£ãŒãããã¯ãæ®ãå Žæã§ãã ãŸãã¯ä»¥äžã®å Žæãæ€çŽ¢ããŠãã ããïŒ
é¢é£ãããã®ãèŠã€ãããŸãããïŒ ä»¥äžã«ã³ã¡ã³ããæ®ããŠãã ããïŒ _é¡äŒŒããŠãããéå®ãããªã_ãã£ãŒãããã¯ãæ¢ããŠããŸãïŒ
URLã«å°ããªééãããããŸããhttpïŒ//bitprophet.org/blog/2017/04/17/fabric-2-alpha-beta/ã«ãªããŸãã
èªåã®ãŠã§ããµã€ããã©ãã ãèŠããŠãããã瀺ããŸããã ããããšãïŒ ç§ã¯èªåã®æçš¿ã§ãªã³ã¯ãã§ãã«ãŒãå®è¡ããŸããã...ãã®ãã±ããã«å¯ŸããŠã§ã¯ãããŸãã;ïŒ
ãã¡ããªãã¯2ã®å²åŠã«æ²¿ã£ãæ¹æ³ã§ãã¡ããªãã¯1ã®roledefsã·ã¹ãã ãå®è£
ããæ¹æ³ã«ã€ããŠã®ææ¡ããããŸãã ã¿ã¹ã¯ã®åCollection
ã¯ãåãåå空éã«@group
ã§è£
食ãããé¢æ°ãæã¡ãã¿ã¹ã¯ãå®è¡ã§ããå
¥åæžã¿ã®Group
ãªããžã§ã¯ããè¿ãããšãã§ããŸãã åå空éãéèŠã«ãªãããã fabfile.py
ã«deploy
Collection
$ãå«ãŸãã$ @group
ãweb
ããã³db
ãšåŒã°ããå Žåã deploy.web.execute(mytask)
ãŸãã¯fab -G deploy.web mytask
ã䜿çšããŠã web
ã°ã«ãŒãå
ã®åãã¹ãã§mytask
$ãå®è¡ã§ããŸãã ãããã®è£
食ãããé¢æ°ã¯ããã¹ããªã¹ãã®ã«ãã¯ã¢ããããŠãŒã¶ãŒã«ãã£ãŠå®è£
ãããé
ãæäœã§ããå Žåã«ãäžèŠãªAPIåŒã³åºããé²ãããã«é
延ããŠåŒã³åºãããã¡ã¢åãããŸãã
ããã¯ãã¡ããªãã¯2ã®èšèšå²åŠãšäžèŽããŠããŸããïŒ ãããããªããç§ã¯å®è£ ã§ã¹ã€ã³ã°ãããããšæããŸãã
ããã¯çŽ æŽãããã¢ã€ãã¢ã§ãã@ RedKriegïŒ ç§ã¯ãã°ã«ãŒããªããžã§ã¯ããçæããããã®ãæè¯ã®ãæ¹æ³ããCLIã§ããããåç §ããæ¹æ³ã«ã€ããŠãèªåã®ãã¬ã€ã³ã¹ããŒãã³ã°ã延æããŠããŸããããããã¯åççãªæ¹æ³ã®ããã«æããŸãã ïŒ1594ã§ããŸãã«ãå€ãã®åèªãåãåã£ãŠãããã«ããªãã®ã¢ã€ãã¢ãå«ããŸããïŒ+ãªã³ã¯ïŒã ããã§è°è«ãç¶ããŸãããããããtl; drã¯ãç§ã¯PoCPRãèŠããã§ãã
-H
åŒæ°ãååšããã«ãããããããããŒã«ã«ã§ã³ãã³ããå®è¡ããããã®æè¯ã®ã¢ãããŒãã¯äœã§ããïŒããšãã°ãããŒã«ã«ãã«ããšãªã¢ãŒããã¹ããžã®rsyncãåäžã®ã¿ã¹ã¯ã«çµåãããå Žåã¯ã©ããªããŸããïŒ
@ max-arnoldæ¥ç¶ãªããžã§ã¯ãã«ã¯ãããŒã«ã«ãã·ã³ã§.run
ã®ããã«æ©èœãã.local
å±æ§ããããŸãïŒhttpïŒ //docs.fabfile.org/en/v2/api/connection.html#fabric .connection.Connection.local
ããããŸãããç§ã¯äŸãèšèãããåªããŠãããšæããŸãïŒ
<strong i="6">@task</strong>
def build(ctx):
# should always run locally
ctx.local('uname -a')
<strong i="7">@task</strong>
def deploy(ctx):
build(ctx)
# this one should run on remote host
ctx.run('uname -a')
çµåãããã¿ã¹ã¯ã¯æ£åžžã«å®è¡ãããŸãã
fab -H host deploy
ããŒã«ã«ã¿ã¹ã¯ã®ã¿ãAttributeErrorã§å€±æããŸãïŒ 'local'ã®å±æ§ãŸãã¯æ§æããŒãèŠã€ãããŸããïŒ
fab build
åºæ¬çã«ãïŒ -H
ã®æç¡ã«ãããããïŒåŒã³åºãããæ¹æ³ã«é¢ä¿ãªããããŒã«ã«ã§äœããå®è¡ããã¿ã¹ã¯ãå¿
èŠã§ãã
å察åŽããèŠããšãäžéšã®ã³ãã³ãã¯ãªã¢ãŒãã§ã®å®è¡ã®ã¿ãç®çãšããŠããŸãã ãã¹ããååšããªãå Žåã ctx.run
ã¯ããããããŒã«ã«ã§å®è¡ããããšããŸããããã«ãããäºæããªãçµæãçããå¯èœæ§ããããŸãã
| ãŠãŒã¶ãŒãã¿ã¹ã¯ãå®è¡ãã| ã³ãã³ã/ã¿ã¹ã¯ã®äœæè
ã¯ãããå®è¡ãããããšãæãã§ããŸã| ããã¯ã©ã®ããã«æ¯ãèãã¹ãã§ããïŒ |
| --------------------- | --------------------------- --- | ---------------- |
| ããŒã«ã«| ããŒã«ã«| runïŒïŒã®åäœã¯åé¡ãããŸããïŒãã ãããªã¢ãŒãã§å®è¡ãããšäœæè
ã®æå³ã«éåããŸãïŒ|
| ããŒã«ã«| ãªã¢ãŒã| 倱æããã¯ãã§ãïŒãŸãã¯å€ããã¡ããªãã¯ã®ããã«ãã¹ãæååãèŠæ±ããŸãïŒ|
|ããŒã«ã«| ããŒã«ã«ãŸãã¯ãªã¢ãŒã| runïŒïŒã®åäœã¯åé¡ãããŸãã|
| ãªã¢ãŒã| ããŒã«ã«| åžžã«ããŒã«ã«ã§å®è¡ããå¿
èŠããããŸãããContextã«ã¯ãããä¿èšŒããlocalïŒïŒã¡ãœããããããŸããã
| ãªã¢ãŒã| ãªã¢ãŒã| runïŒïŒã®åäœã¯åé¡ãããŸããïŒãã ããããŒã«ã«åŒã³åºãäžã«åé¡ãçºçããããšãäºæ³ãããŸãïŒ|
| ãªã¢ãŒã| ããŒã«ã«ãŸãã¯ãªã¢ãŒã| runïŒïŒã®åäœã¯åé¡ãããŸãã|
@ max-arnoldããã¯ãŸãã«ïŒ98ã§ãïŒ ç§ã¯ãŸã å®å šã«ã¯è§£æ±ºããŠããŸããã ã³ã¡ã³ããšããŠããã«ããã€ãã®çŸä»£çãªèããå ¥ããŠ...ç·šéïŒãã
sudoãšççŸããŠããããã«èŠãããã®ã«æ°ã¥ããŸããã
ããã§ã connection
ã¯ãrootãšããŠèªèšŒããããªã¢ãŒããµãŒããŒã§ãã
ã«ãŒã以å€ã®å¥ã®ãŠãŒã¶ãŒãšããŠãã«ããæ¡åŒµããããšããŠããŸãïŒ
c.sudo("echo bar > ~/foo", user="builder")
ããã¯æåããŸããã/ home / builder / fooãæžã蟌ãã®ã§ã¯ãªãã代ããã«/ root / fooãæžã蟌ã¿ãŸãã
äžæ¹ãç§ãlsãå®è¡ããããšãããšã次ã®ããã«ãªããŸãã
c.sudo("ls", user="builder")
Permission denied
ãååŸããŸãã
äœããæ°åãæªãã
ãã¹ãã£ã³ãäžèšã®åž¯åå€ãå ±åãããšãã®ç§ã®æšæž¬ã§ã¯ãããã¯$ïŒ -H
sudo
ïŒã¡ãœããã§ã¯ãªãã³ãã³ãïŒåºæã®ããã§ãããšæšæž¬ããŸãããæåŸ
ã©ããã«100ïŒ
åäœããããã§ã¯ãããŸããã
ããã«ã¡ã¯ãžã§ãã
ç§ã¯ãã§ã«Python3ã§äœæ¥ããŠããã®ã§ãçŸåšfabric3
ïŒãã¡ããªãã¯1.xã®ç§»æ€ïŒã䜿çšããŠããŸãã
ãã¡ããªãã¯2ãžã®ç§»è¡ãè©Šã¿ãããªããŸããããããã«ã·ã§ãŒã¹ããããŒã«ã¶ã€ãããŸããã fabric.contrib
é¢æ°ãå€çšããŠããŸããã移è¡ããã¥ã¡ã³ãã«ã¯ãããååšããªããšæžãããŠããŸãã
確ãã«ãåçã®ã·ã§ã«ã«æ»ã£ãŠã³ãŒããè¥å€§åããããã¯ãããŸããããã¡ããªãã¯1.xã®contrib.*
ã®åé¡ã®æ°ããå€æãããšãå€ã䜿çšãããŠããããã«èŠããã®ã§ãäžè¶³ã¯ãä»ã®å€ãã®äººã
ã®ç§»äœã«ãšã£ãŠæ·±å»ãªé害ãšãªãå¯èœæ§ããããŸãã
fabric.contrib
ã«çžåœãããã®ãå«ãŸããŠãããšæããããããã¯ãŒã¯ãããžã§ã¯ããèŠã€ããŸãããããã®ã³ãŒãã¯äœå¹ŽãæŽæ°ãããŠããŸããã
fabric.contrib
ããã¡ããªãã¯2ã«ç§»æ€ããèšç»ã¯ãããŸããïŒ
ããããšãã
ã¬ããªãšã«
@ garu57ã¯ããçŸåšã®èšç»ã¯ãåºæ¬çã«ã2.0ã®è²¢ç®ããšããŠpatchwork
ã䜿çšããããšã§ãã çŸæç¹ã§ã¯Fabric1ããŒã¹ã§ãããFabric2.0.0ããªãªãŒã¹ãããåŸã«å€æŽãããŸãã æãäžè¬çã«äœ¿çšãããcontribãããã¯ããã«ç§»æ€ããããšæããŸãã
çããããã«ã¡ã¯ã
æã ç§ã®ããã°ã©ã ã¯ãªã¢ãŒãã³ãã³ããå®è¡ããŸãäŸãã°
source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./00-update-kernel.sh'
ã¹ã¯ãªããã¯æ¬¡ã®ããã«å®è¡ãããŸãã
033[0;32m[DONE]\033[0m'
+ return 0
+ alt_test_done_msg 'Prepare evironment'
+ echo -e '* Prepare evironment \033[0;32m[DONE]\033[0m'
+ exit 0
ãããã°åºåãïŒãã衚瀺ãããã¯ãã§ãã ç§ã®ã³ãŒãã«ãããšïŒ
class GenericFabric(object):
def __init__(self, host, user, key_filename=None, port=22):
connection_string = "{u}@{h}:{p}".format(u=user, h=host, p=port)
self.connection = Connection(connection_string)
self.key_filename = key_filename
#<strong i="13">@with_settings</strong>
def generic_cmd(self, command_str, timeout, fabric_timeout, **kwargs):
"""
Creating remote container from template
<strong i="14">@type</strong> command_str: str
<strong i="15">@param</strong> command_str: command for execute with VM
<strong i="16">@type</strong> timeout int or float
<strong i="17">@param</strong> timeout number of seconds for pause
<strong i="18">@type</strong> fabric_timeout int or float
<strong i="19">@param</strong> fabric_timeout number of seconds for timeout fabric run
<strong i="20">@rtype</strong>: FabricResponse
<strong i="21">@return</strong>: Return remote status of operation VM
"""
if fabric_timeout > 0:
command = self.connection.run(command_str.format(**kwargs),
timeout=fabric_timeout,
warn=True, echo=True)
else:
command = self.connection.run(command_str.format(**kwargs),
warn=True, echo=True)
print("?")
if timeout > 0:
sleep(timeout)
return FabricResponse(command)
def simple_generic_cmd(self, command_str, **kwargs):
"""
<strong i="22">@type</strong> command_str: str
<strong i="23">@param</strong> command_str: command for execute with VM
<strong i="24">@rtype</strong>: FabricResponse
<strong i="25">@return</strong>: Return remote status of operation VM
"""
return self.generic_cmd(command_str, 0.1, 0, **kwargs)
ãããããïŒããšãããã®ã¯ãããŸããã ãããã£ãŠãrunïŒïŒã«ã¶ãäžãã£ãŠããããšããå§ãããŸãã
å®éãç§ã®ããã°ã©ã ã¯å·šå€§ã§ããã«ãããã»ã¹ããã°ã©ãã³ã°ããããŸãã ã¶ãäžããããã£ããããããã«ã次ã®ã³ãŒãã§ãªã¢ãŒãã³ãã³ããå®è¡ããŠããŸãã
class TestingSystemVM(GenericFabric):
#######
<strong i="7">@signal_alarm_down</strong>
def run_rpm_test(self, command_test, package, type_of_test="base"):
"""
"""
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(self.__timeout)
returned_value = Queue()
start_time = datetime.utcnow()
directory, command_test = os.path.split(command_test)
try:
if command_test.endswith(".yml"):
directory = directory.replace("/opt/QA", self.ansible.git_qa_repo)
output = self.ansible.play_ansible(command_test,
package,
directory)
else:
vm_instance = (self.host,
self.user,
self.key_filename,
self.os_name,
self.platform,
self.arch)
running_test = Process(target=separate_process_running_test,
args=(vm_instance,
returned_value,
directory,
command_test,
package,
type_of_test))
running_test.start()
running_test.join(self.__timeout)
if running_test.is_alive():
running_test.terminate()
command_test_res = "FAIL: Timeout\n"
return command_test_res, work_time(start_time), 1
elif returned_value.empty():
command_test_res = "FAIL: Problem while getting result\n"
return command_test_res, work_time(start_time), 1
else:
output = returned_value.get()
except TimeOut:
command_test_res = "FAIL: Timeout\n"
return command_test_res, work_time(start_time), 1
if output.failed or (package.name in ("lve-utils", "lve-stats") and
"FAIL" in output.stdout):
res_output = "FAIL: " + output.stdout
else:
res_output = output.stdout
return res_output, work_time(start_time), 0 if output.succeeded else 1
def separate_process_running_test(vm_instance, return_value_queue,
directory, command_test, package,
type_of_test="base"):
"""
"""
sleep(0.5)
signal.signal(signal.SIGTERM, kill_fabric_runner)
signal.signal(signal.SIGINT, kill_fabric_runner)
(host,
user,
key_filename,
os_name,
platform,
arch) = vm_instance
child_vm_instance = TestingSystemVM(host,
user,
key_filename,
os_name,
platform,
arch,
FakeAnsible())
if command_test.endswith(".bats"):
command_test = "/usr/bin/bats --tap " + command_test
else:
command_test = os.path.join("./", command_test)
output = child_vm_instance.simple_generic_cmd(child_vm_instance._c_run_test,
envvars=child_vm_instance.env_vars,
exec_test=command_test,
dir=directory,
package=package.name,
pver=package.version,
prel=package.release,
type_test=type_of_test)
print("!")
return_value_queue.put(output)
ç§ãfabric2ã䜿çšãããšãåããã»ã¹ããèµ·åãããããã€ãã®ã³ãã³ããæã
ãã³ã°ããŸãã
æŽæ°å®éãããã¯ã³ãŒãã®ç§ã®ééãã§ããã ãããã£ãŠãfabric2ã«ã¯åãäžããå«ãŸããŠããŸãã
ã¿ãªãããããã«ã¡ã¯ã
ç§ã¯ããã€ãã®æã¡äžãå®éšãè¡ããç§ã®çµéšãå
±æããããšãã§ããŸãã
ãŸããã³ã³ãœãŒã«ããã³ãã³ããå®è¡ããŸãã
ssh [email protected] -t "source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'"
ãããŠããã¯exit = 0ã§å®å šã«ãããŠéãçµãããŸããïŒ
###
+ echo -e '* Prepare evironment \033[0;32m[DONE]\033[0m'
* Prepare evironment [DONE]
+ exit 0
Connection to 192.168.0.34 closed.
è¯ãã
次ã«ãå¥ã®ã³ãã³ããå®è¡ããŸããã
ssh [email protected] "source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'"
ãããexit = 0ã§éåžžã«éãçµäºããŸããã
###
+ echo -e '* Prepare evironment \033[0;32m[DONE]\033[0m'
+ exit 0
ãã ããã192.168.0.36ãžã®æ¥ç¶ãéããããŸãããã¯ãããŸããã ãããéèŠãã©ããã¯ããããŸããã
ãã®åŸãVMãåäœæããfabric2ïŒIPythonããïŒã«ãã£ãŠã³ãã³ããèµ·åããŸããã
In [1]: from fabric import Connection
In [2]: Connection('[email protected]').run("source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'", pty=True)
....
+ echo -e '* Prepare evironment \033[0;32m[DONE]\033[0m'
* Prepare evironment [DONE]
+ exit 0
Out[2]: <Result cmd="source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'" exited=0>
ãŸããpty = Falseã§å®è¡ããŸããã
In [1]: from fabric import Connection
In [2]: Connection('[email protected]').run("source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'", pty=False)
+ echo -e '* Prepare evironment \033[0;32m[DONE]\033[0m'
+ exit 0
Out[2]: <Result cmd="source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'" exited=0>
ããžã®æ¥ç¶ã¯ãããŸããã§ãã
第äºã«ãåããã»ã¹ããã®èµ·åãå¿ èŠãªãããã¹ã¿ã³ãã«é©ããç°å¢ã§ã¯ãªããšå€æããŸããã ããã§ãVMãåäœæãã次ã®ã³ãŒãã§ã¹ã¯ãªãããå®è¡ããŸããã
In [1]: import subprocess
In [2]: t = subprocess.Popen(""" ssh [email protected] -t "source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'" """, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True); r = t.communicate()
ãã®å®è¡ã®åºåã«ã¯ãã192.168.0.34ãžã®æ¥ç¶ãéããããŸãããããããŸããã
äžæ¹ã§
In [1]: import subprocess
In [2]: t = subprocess.Popen(""" ssh [email protected] "source /opt/centos/vars && su - -c 'cd /opt/QA/rpm_tests/p_lvemanager && ALT_TEST=base ALT_PACKAGE_NAME=lvemanager ALT_PACKAGE_VERSION=3.0 ALT_PACKAGE_RELEASE=11.el6.cloudlinux.21100.1.1505113712 ./01-prepare-environment.sh'" """, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True); r = t.communicate()
ã©ã¡ãããã³ã°ããŠããŸããã
ä»å€ããã©ãŒã¯ãããããã»ã¹ã§fabric2ã䜿çšããŠã¹ã¯ãªãããèµ·åããæžã蟌ã¿ãŸãã
æŽæ°å®éãããã¯ã³ãŒãã®ç§ã®ééãã§ããã ãããã£ãŠãfabric2ã«ã¯åãäžããå«ãŸããŠããŸããã
Transfer.put
ã®use_sudo
ãµããŒããååŸãããšããã§ãããã
ä»ã®ãšããæãç°¡åãªåé¿çã¯ãã¢ã¯ã»ã¹èš±å¯ãããå Žæã§put
ãå®è¡ããŠããã sudo mv
ãå®è¡ããããšã ãšæããŸãã
@ ned2ã¯ããã¹ãŠuse_sudo
ãget
/ put
ã§å®éã«å®è¡ã§ããããšã§ããããšãã°ãv1ã®å®è¡æ¹æ³ã§ãã ç§ã®ç¥ãéãããsudoã䜿çšããŠããã¡ã€ã«ãã¢ããããŒãããããšã¯å®éã«ã¯äžå¯èœã§ãã ïŒã«ãŒããšããŠæ¥ç¶ããªãããã§ã¯ãããŸãããããã¯æªãèãã§ãããçæ³çã«ã¯èš±å¯ãããŠããŸãããïŒ
v2ã§ããã¯ãªãŒã³ãªAPIã䜿çšããè©Šã¿ãèãããšã get
/ put
èªäœã®äžã«ãã®åäœããã³ãã«ãã代ããã«ãã©ãããŒãå®è£
ããå¯èœæ§ãã»ãšãã©ãããŸãã ãã¶ãTransfer.sudo_put
ïŒ self.put
ãšåŒã°ããïŒã®ãããªãã®ã§ãã ããããã°ããçŽç²ãªã put
ã¯æå°éã«æããããŸãã
@bitprophetãŸããFabric1ã䜿çšããéåžžã«å®å®ãã䟿å©ãªãœãããŠã§ã¢ãšãFabric2ããªãªãŒã¹ããããã®ã¢ãããŒãã«æè¬ããŸãã
v2ã§éãã§ã¿ãŸããããConnectionã§åé¡ãçºçããŸããã ãã¡ããªãã¯1ã®SSHæ§æã䜿çšããŠããŸãããæ¥ç¶ããããšãããšããã¡ããªãã¯1ãããã¹ã¯ãŒãã®å ¥åãæ±ããããŸãã ãã¡ããªãã¯2ã¯ãããå®è¡ããŠããããèªèšŒã倱æããããšã瀺ããŠå€±æããŸãã Connectionã®èªèšŒã¡ã«ããºã ã«ã€ããŠèšåããŠããv2ããã¥ã¡ã³ãã®ã©ãã«ã衚瀺ãããŸããã sudoã䜿çšãããã¹ã¯ãŒãã«ã€ããŠã®èšåããããŸãããç§ãåéã§ããã®ã¯ããšã«ããæ¥ç¶ãæåããåŸã§ãã
ç§ã®è³ªåã¯ãããã¥ã¡ã³ãã§äœããèŠéããã®ãããããšããããäžè¶³ããŠããæ©èœãªã®ãåé¡ãªã®ããšããããšã§ãã
ã³ãŒãïŒ
<strong i="10">@task</strong>
def testing(c):
with Connection('MyHostname') as cxn:
print("Connected")
cxn.run('ls -l')
ãšã©ãŒïŒ
File /lib/python3.4/site-packages/paramiko/auth_handler.py", line 223, in wait_for_response
raise e
paramiko.ssh_exception.AuthenticationException: Authentication failed.
ç§ã®SSHèšå®ïŒããã«æçš¿ããå€ã眮ãæããŸããïŒïŒ
Host MyHostname
HostName replacedhostname.co.uk
Port 22
IdentityFile ~/.ssh/id_rsa
User replaceduser
ç§ã¯ææ°ã®v2ããŒãžã§ã³ã䜿çšããŠããŸãïŒ https ïŒ//github.com/fabric/fabric/commit/fec3a22ee89900500ae731913fd33f9b56e89f46
ããŸãããã°ãããã解決ããããšã§ãåãåé¡ãæ±ããŠããä»ã®äººãå©ããããšãã§ããŸãã
ãæéãããã ãããããšãããããŸãã
@ Aiky30ããããããªãã§ã¯ãããŸããããèªèšŒé¢é£ã®äœæ¥ã¯ãŸã å¿
èŠã§ãïŒäž»ã«ãé²è¡äžã®Paramikoã®äœæ¥ãå¿
èŠãªãããèªèšŒã®äŸå€ãæ£ãã解éããã®ã¯ããã»ã©é£ãããããŸããïŒããã®å Žåã¯ãåã«Fabã§ããå¯èœæ§ããããŸãã 2ã¯IdentityFile
ã解éããŠããŸãã-ãã¹ãããŠãŒã¶ãŒãããŒãããã®ä»ã®èšå®ãååŸããŸãããIdentityFileã¯äŸç¶ãšããŠTODOã§ãã
ããã¯ãçŸåšãã¹ãã¬ãŒãºãæ±ã£ãŠããªãããšãäžå ã§ãïŒäžèšãåç §ããŠãã ãããç¹å®ã®èªèšŒã倱æããå Žåã«ãã¹ã¯ãŒããŸãã¯ãã¹ãã¬ãŒãºãå¿ èŠãã©ãããæšæž¬ããªããã°ãªããªã倧ããªFabric 1ã®å¿æ¥ä¿®çã¯é¿ãããã§ãïŒã ãããã£ãŠããã®åŸã¯ããã®ãã¡ã€ã«ã®ããã¯ã解é€ã§ããŸããããšãããšã©ãŒã«ç§»è¡ããå¯èœæ§ããããŸãã ãããŠããããã¯äž¡æ¹ãšããç§ãã»ãšãã©ã®å Žåssh-agentã䜿çšããŠããããã§ããããã¯ãå³æã®åé¿çã®æåã®ææ¡ã§ãã
ãšã¯ãããIdentityFileãšæ瀺çãªãã¹ãã¬ãŒãºæ§æã®ãµããŒãã®äž¡æ¹ããããã³ã°ãã䟡å€ããããšæããŸãããšãŒãžã§ã³ã以å€ã®ããŒãæãäžè¬çãªèªèšŒã»ããã¢ããã®1ã€ã§ããå¯èœæ§ãé«ããããããããªããšãã»ãšãã©ã®ã¢ã«ãã¡/ããŒã¿ãŠãŒã¶ãŒãé ããŠããããšãæå³ããŸãã ã ä»æ¥ãããæã¡è² ããããšãã§ãããã©ããã確èªããŸãã
ã¹ãã³ã®ããã«2.0aãåããŸããã
1ïŒãã¹ããå®éã«å®çŸ©ããŠäœ¿çšããæ¹æ³ã«ã€ããŠãå°ãè¿·ã£ãŠããŸãã èµ°ããïŒ
fab -H user<strong i="7">@host</strong>:22 some-task
ãããããã¹ãã®è©³çŽ°ïŒãŠãŒã¶ãŒããã¹ããããŒãïŒãæ¯åæž¡ããããªãå Žåã¯ã fabfile.py
ïŒ Connection
sãŸãã¯Group
ïŒã§ãã¹ããæ§æããæ¹æ³ãããããŸããã https://github.com/fabric/fabric/issues/1591#issuecomment -296343613ãæ£ããç解ããŠããã°ãçŸæç¹ã§ã¯ãµããŒããããŠããŸããïŒhttps://github.com/fabric/fabric/issues/1594ã§è¿œè·¡ãããŠããŸãïŒã ïŒïŒ
2ïŒãŸããSSHããŒãæå·åããŠïŒ ~/.ssh/id_rsa
ïŒã ssh-add
ãssh-agent
ã«ãããšããåé¡ãçºçããŸããã ssh-add -l
ãä»ããŠããŒãäžèŠ§è¡šç€ºãããšè¡šç€ºãããŸãã ã¿ã¹ã¯ãå®è¡ãããšãã«ãé©åãªãŠãŒã¶ãŒåãæå®ããŸãã
fab -H musttu<strong i="20">@host</strong> sometask
ç©äºã¯ããŸããããŸãã ããããééã£ããŠãŒã¶ãŒãããšãã°fab -H bad_user<strong i="23">@host</strong> sometask
ã䜿çšãããšã次ã®ããã«ãªããŸãã
Traceback (most recent call last):
...
File "/home/maximus/.virtualenvs/testenv/lib/python3.6/site-packages/paramiko/pkey.py", line 326, in _read_private_key
raise PasswordRequiredException('Private key file is encrypted')
paramiko.ssh_exception.PasswordRequiredException: Private key file is encrypted
ãã ããããã¯https://github.com/paramiko/paramiko/issues/387ã«è©²åœãããã¡ããªãã¯2.0ã«åºæã®ãã®ã§ã¯ãªããšæããŸãã ãããããããssh-agentããã§ã«åŸ©å·åãããããŒãæã£ãŠããå Žåã PasswordRequiredException: Private key file is encrypted
ãšã©ãŒãçºçããã®ã¯å¥åŠã«æããŸãã ç§ãæ£ããç解ããŠããã°ãç¡å¹ãªãã°ã€ã³ã®åŸã paramiko
ã¯ããŒãçŽæ¥äœ¿çšããããšã«ãã©ãŒã«ããã¯ãããã¹ãã¬ãŒãºãæäŸãããŠããªããšãã®ãšã©ãŒãã¹ããŒãããŸãã
3ïŒã¿ã€ã泚éã¿ã¹ã¯é¢æ°ãèš±å¯ãããšäŸ¿å©ã§ãïŒIDEã§ã®ãªãŒãã³ã³ããªãŒããæ¹åããããïŒã https://github.com/pyinvoke/invoke/pull/458ãæ€èšããæéããããŸãããïŒ
4ïŒãããã¯ãŒã¯ã©ã€ãã©ãªã®ã¢ã€ãã¢ã奜ãã§ãã ãã¡ããªãã¯1.xã®å Žåã httpsïŒ//github.com/sebastien/cuisine ïŒããªãæ»ãã§ããããã«èŠããŸãïŒããããå€ãã®è¿œå æ©èœãå«ãŸããŠããŸãïŒèªåã§äœ¿çšããããšã¯ãããŸããïŒã ãããã¯ãŒã¯ã䜿ã£ãŠäŒŒããããªãã®ãæ§ç¯ãããšããã¢ã€ãã¢ã¯ãããŸããïŒã¹ã³ãŒãã¯çž®å°ãããŠããŸãããChef / Ansible / SaltStackã¹ã¿ã€ã«ã®å®£èšåé¢æ°ïŒïŒ ç§ã¯åžžã«ä»ã®ããŒã«ãåŸããã«ããã£ã¬ã¯ããª/ãã«ããã¡ã€ã«YAML / DSLã¢ãããŒããå«ããæè»æ§ãé«ããæ§æã®åé·æ§ãæžãããIDEã®ãªãŒãã³ã³ããªãŒãããããã°ã容æã«ããããã«ãPythonã䜿ãç¶ããããšæã£ãŠããŸãã
5ïŒãã¡ããªãã¯2.0ã®py2.6ããã³3.2-3.3ãµããŒããåé€ããã ãã§ãã 人ã ã¯ãã å ã«é²ãã¹ãã§ã¯ãããŸãããïŒ
@ tuukkamustonen-ãã£ãŒãããã¯ãããããšãïŒ åå¿ïŒ
圹å²ã¯ç¢ºãã«ïŒ1594ã§ã«ããŒãããŠããŸãããããŠã ssh_config
ã®ãµããŒããç¬èªã®ã¬ãã«ã§ã©ã®ããã«è¡ãããé€ãã°ããã¹ãããšã®æ§æããŒã¿ã ããæã€ãšããé¢é£ããåé¡ã«ã€ããŠã¯å¥ã®ãã±ããããããšæããŸãã
ãã¡ããªãã¯ã¬ãã«ã®æ§æãssh_config
ãšã次ã«ã°ã«ãŒããŸãã¯ã©ã³ã¿ã€ã ããŒã¿ããã®ããŒã¿ãšã©ã®ããã«æ£ç¢ºã«èª¿æŽãããã決å®ããããšã¯ç°¡åã§ã¯ãããŸããã ããã¯ééããªãããã«èµ·ããå¿
èŠããããŸãã; æåã®ãã©ããã§ã¯ãªããèãæããããœãªã¥ãŒã·ã§ã³ã欲ããã ãã§ãã
ç¹°ãè¿ããŸãããã¯ããããã¯ããªããèšåããParamikoãã±ããã§ãããããªãã®æšæž¬ã¯æ£ç¢ºã§ããæªããŠãŒã¶ãŒåã®ç¶æ³ã¯åžžã«æçµçã«å€±æããŸããParamikoã¯æåŸã«çºçãããšã©ãŒã®ã¿ã远跡ãããããæåŸã«è©Šããã®ã¯ããŸããŸã§ãããããŒã®ãã£ã¹ã¯äžã®æå·åãããã³ããŒã ïŒããšãã°ããã®ããŒãå¥ã®å Žæã«ç§»åããå ŽåãæåŸã®ãšã©ãŒã¯å¥ã®ãã®ã«ãªããŸããïŒ
ãã®ãã±ããã«ã€ããŠã³ã¡ã³ãããŸããããåãå šäœçãªæ©èœã®æ¢åã®ãã±ãããšéè€ããå Žåãšéè€ããªãå ŽåããããŸãã ç§ã¯ãããã®å€ããã®ãšIIRCã«ã€ããŠã³ã¡ã³ãããŸããããããã¯ãPython 2ãæ±ããªãéããããã¯çŽ æŽãããããšã ãšæããŸããã§ãã ãã ããæ¬ èœããŠãã倧ããªæ©èœã®ã»ãšãã©ã»ã©åªå 床ã¯é«ããªãããããããŒãžã§ãããã¹ãŠã®ãã§ãã¯ããã¯ã¹ããªã³ã«ããåªããPRãå¿ èŠããã±ããã«åé¡ãããŸã:)
ã¯ããéåžžã«å€ãã§ããããŸã ç§ã®å¿ã«ããïŒ461ãåç §ããŠãã ããã æè¿ã®å€§ããªåé¡ã¯ããã®ãããªlibãInvokeãšFabricã®äž¡æ¹ã«ãŸãããããã«ã©ã®ããã«èšè¿°ãããããšããããšã§ãã å€ãã®å Žå/ã»ãšãã©ã®å Žåãåå²ãããããŒã«ã«/ãªã¢ãŒãã³ã³ããã¹ãããèªèãããªãæ±çšã®Invokeã¿ã¹ã¯ãèšè¿°ã§ããŸããããã¯ããªã¢ãŒãã·ã¹ãã ã«å¯ŸããŠå®è¡ããå Žåã«Fabricæ¥ç¶ã³ã³ããã¹ããæž¡ãããšãã§ããŸãã
ãã®ãããªãã³ã³ããã¹ãã«ãšããããªããã¿ã¹ã¯ã¯ããåŒã³åºããã©ã€ãã©ãªïŒãŸãã¯ä»ã®ãŸã åŒã³åºãåºæã®ã©ã€ãã©ãªïŒã«ååšããå¿ èŠããããŸãã ãã ããäžéšïŒããšãã°ãã·ã§ã«ã³ãã³ãã ãã§ãªãããã¡ã€ã«è»¢éã«é¢é£ãããã®ïŒã¯ãããã¡ããªãã¯å¯Ÿå¿ãã§ããå¿ èŠããããŸãã ãã®ã®ã£ãããåããæ¹æ³ãèŠã€ããããšãåé¡ã§ãã
ãlibã¯invokeã®ã¿ãå¿ èŠãšãããã¡ããªãã¯ãããŒãã«å¿ èŠãšããªãããããããã¡ããªãã¯ãã€ã³ã¹ããŒã«ããŠæ¥ç¶ã³ã³ããã¹ããæž¡ããªããšãã¿ã¹ã¯ã®ãµãã»ãããæå¥ãèšãããšããã«ãŒãããã©ãããšãã§ããŸãã 2ã€ã®ã©ã€ãã©ãªã«åå²ã§ããŸãïŒãã¡ããªãã¯æåã®ã©ã€ãã©ãªã§ã¯ãããäžè¬çãªInvokeã©ã€ãã©ãªãå¿ èŠã§ãïŒã
æè¿ã®æç¹ã§ãããã¯ééããªãã«ãŒãã«å«ãŸããŠããŸããparamiko/ paramikoïŒ1070ããã³/ãŸãã¯pyinvoke / invokeïŒ364ãåç §ããŠãã ããã Invoke 1.0ãFabric 2.0ãParamiko 3.0ïŒãŸãã¯_maybe_ã2.4 / 2.5 /äœã§ãïŒã¯ãã¹ãŠPython 2.7 /3.4以éã«ãªããŸãã
ïŒ1ïŒã«ã€ããŠïŒ
ããã¯ãã§ã«ãåç¥ã ãšæããŸããã Ansibleã®ã€ã³ãã³ããªããããã€ãã®ã¢ã€ãã¢ãå ¥æããããšããå§ãããŸãã ãŸãã¯ããã§ãªããããããŸãã ïŒïŒã
ïŒ4ïŒã«ã€ããŠïŒ
https://github.com/pyinvoke/invocationsã¯ãããã«ã€ããŠæèŠãè¿°ã¹ãæ¹æ³ã ãšæããŸãã Invocationsã¯_conventions_ãæäŸãããããã¯ãŒã¯/æçã¹ã¿ã€ã«ã®ããã±ãŒãžã®äžã«æ§ç¯ã§ããŸãããã³ã³ãã³ã·ã§ã³ïŒãªãªãŒã¹ãŸãã¯doctestã®æ¹æ³ïŒãšãŠãŒãã£ãªãã£ïŒãã¡ã€ã«ã®ã³ããŒãŸãã¯ã¢ã¯ã»ã¹èš±å¯ã®å€æŽã®æ¹æ³ïŒãæ··åšãããããšã¯ããŸããã
ããŒã«ã«ã®ã¿ããªã¢ãŒãã®ã¿ãããã³ããŒã«ã«+ãªã¢ãŒãæäœã®utilsãåãã©ã€ãã©ãªïŒãããã¯ãŒã¯ïŒã«é 眮ããŠãåé¡ã¯ãããŸããã ã©ã®æäœãã©ã®ã¢ãŒãããµããŒããããã¯ãããã¥ã¡ã³ããšããŠïŒdocstringãšããŠã泚éããèªåçæããããªã©ïŒåãçµãããšãã§ããŸãã
ããã¯ãããžãã¯ã2ã€ä»¥äžã®ããã±ãŒãžã«åå²ãããããå¿«é©ã§ãã æåã«ãåŒã³åºãå°çšãããã±ãŒãžã«æäœãè¿œå ãïŒããã«ããªã¢ãŒãã®ã¿ãæäœãããå¯èœæ§ããããŸãïŒãåŸã§ãªã¢ãŒããµãŒããŒã§ãæ©èœããããã«ãµããŒããè¿œå ãããšã©ããªãã§ããããã ã³ãŒãã移åãã³ããŒããŸãã¯æ¡åŒµããŸããïŒ ã©ã¡ãã®å Žåããããã¯ããå€ãã®äœæ¥ã§ããããŠãŒã¶ãŒã¯å¥ã®ã€ã³ããŒããªã©ãå¿ èŠãšãããããå°ãé¢åã«èãããŸãã
ãããPyPiã§äœ¿çšã§ããããã«ååã«æŽç·Žãããã«ã¯ã©ãããã°ããã§ããïŒ
@haydenflinnerããã¯æ¥é±ã2é±éã§èµ·ãã£ãŠããŸã!! ïŒç®çã¯ã5æ10æ¥ã§ããPyConã«é£è¡æ©ã«ä¹ãåã«ãªãªãŒã¹ããããšã§ããïŒ
ããšãã°ãä»é±äœæ¥ããŠããæè¿æŽæ°ãããã¢ããã°ã¬ãŒãããã¥ã¡ã³ããã芧ãã ããïŒhttpïŒ //docs.fabfile.org/en/v2/upgrading.html
å®éã2.0.0以éã®å®éã®å®éã®ãã±ããããŸããªãåãå ¥ããã®ã§ãä»ãããã®ãã±ãããéããããšãã§ããŸãð
泚æããŠãã ãããããªããæããªããããªãã¯ãŸã ããã«ã³ã¡ã³ãããããšãã§ããŸãã ãããžã§ã¯ã管çã®æºåã®ãã¹ãŠã«å ããŠããªãªãŒã¹åã«å°ãªããšãããã€ãã®æ©èœäœæ¥ãå®äºãããããšæã£ãŠããããšã«æ³šæããŠãã ããã
ä»æ¥ã¯fabricv2ãèŠãŸããããç³ãèš³ãããŸãããã䜿çšããããšãã§ããŸããã
ã¿ã¹ã¯ã¯åŒæ°ãåããŸãããæ§æãå€æŽãããŸããã http://docs.pyinvoke.org/en/1.1/concepts/invoking-tasks.html#task-command-line-argumentsãåç §ããŠãã ãã
@dgarstangèªç±ãªåŽååãäžããŠããã人ã ã«å¯ŸããŠãããäžç«çãŸãã¯å ±æçãªå£èª¿ããšãããšãæ€èšããããšããå§ãããŸãã ãã èšã£ãŠãã ããð
@task(hosts=xxx)
ã䜿çšããæ©èœãè¿œå ãããŸããïŒreïŒ3ïŒ --hosts
ãšåéã«ã¿ã¹ã¯ããšã®è°è«ã§ãããã®ããã«äžãããšããç¹ã§ãããã¯ç§ããã€ãè¿œå ãããããããªããã®ã§ãããããã䟡å€ããããã©ããã«ã€ããŠåŒãè£ãããŠããŸããã¿ã¹ã¯ããšã®--help
ãšåæ§ã§ã
æãåèã«ãªãã³ã¡ã³ã
@haydenflinnerããã¯æ¥é±ã2é±éã§èµ·ãã£ãŠããŸã!! ïŒç®çã¯ã5æ10æ¥ã§ããPyConã«é£è¡æ©ã«ä¹ãåã«ãªãªãŒã¹ããããšã§ããïŒ
ããšãã°ãä»é±äœæ¥ããŠããæè¿æŽæ°ãããã¢ããã°ã¬ãŒãããã¥ã¡ã³ããã芧ãã ããïŒhttpïŒ //docs.fabfile.org/en/v2/upgrading.html
å®éã2.0.0以éã®å®éã®å®éã®ãã±ããããŸããªãåãå ¥ããã®ã§ãä»ãããã®ãã±ãããéããããšãã§ããŸãð