Fabric: рдХрдкрдбрд╝рд╛ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЛ рд╕реНрдерд╛рдиреАрдп рд╢реЗрд▓ рдореЗрдВ рдирд╣реАрдВ рднреЗрдЬрддрд╛ рд╣реИ, рдЬреИрд╕реЗ Invoke does

рдХреЛ рдирд┐рд░реНрдорд┐рдд 11 рдордИ 2018  ┬╖  14рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: fabric/fabric

рдЗрд╕ рдХрд╛рд░реНрдп рдкрд░рд┐рднрд╛рд╖рд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ, рджреЛрдиреЛрдВ fabfile.py рдФрд░ tasks.py рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬреЗ рдЧрдП:

from invoke import task

<strong i="8">@task</strong>
def make(c):
    c.run('env')

fab make рдЖрдЙрдЯрдкреБрдЯ:

PWD=/tmp
SHLVL=1
_=/usr/bin/env

inv make рдЖрдЙрдЯрдкреБрдЯ:

LC_ALL=en_US.UTF-8
NVM_DIR=/home/justinas/.nvm
LC_MEASUREMENT=en_US.UTF-8
LC_PAPER=en_US.UTF-8
LC_MONETARY=en_US.UTF-8
<...> (lots of stuff in my environment)

рдореИрдВ рд╢реБрд░реВ рдореЗрдВ рдпрд╣ рдкрд╛рдпрд╛ рдЬрдм fpm рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ PATH рдЪрд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рд╣реИрдВ:

from invoke import task

<strong i="22">@task</strong>
def make(c):
    c.run('fpm -s dir -t rpm -C dist --name somename .')

рдпрд╣ рдЖрд╣реНрд╡рд╛рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлреИрдм рдХреЗ рд╕рд╛рде рдирд╣реАрдВред

justinas<strong i="26">@js</strong>:/tmp$ fab make
{:timestamp=>"2018-05-11T13:11:26.218874+0300", :message=>"Need executable 'rpmbuild' to convert dir to rpm", :level=>:error}
justinas<strong i="27">@js</strong>:/tmp$ inv make
{:timestamp=>"2018-05-11T13:11:29.967762+0300", :message=>"Created package", :path=>"somename-1.0-1.x86_64.rpm"}
Bug Connection Needs investigation run()

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВ рдмрд╕ рдЗрд╕ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛ред рдореИрдВ c.run('make build') рдХрд░ рд░рд╣рд╛ рдерд╛ рдФрд░ рдореЗрд░реЗ рдХрд┐рд╕реА рднреА ENV рдиреЗ (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ GOPATH рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рдирд┐рд░реНрдорд╛рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЧрдпрд╛ рдерд╛) рдЦреАрдВрдЪ рд▓рд┐рдпрд╛ред replace_env=False рдЬреЛрдбрд╝рдирд╛ рдЗрд╕реЗ рдареАрдХ рдХрд░рддрд╛ рд╣реИред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореИрдВ рдбреЙрдХреНрд╕ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рджреЗрдЦрддрд╛ рд╣реВрдВ:

run.replace_env: рд╕рд╣реА, рдЧрд▓рдд рдХреЗ рдмрдЬрд╛рдп, рддрд╛рдХрд┐ рджреВрд░рд╕реНрде рдХрдорд╛рдВрдб 'рд╕реНрд╡рдЪреНрдЫ', рдЦрд╛рд▓реА рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде рдЪрд▓реЗрдВ, рдмрдЬрд╛рдп рд╡рд░реНрддрдорд╛рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ 'рдкрд░реНрдпрд╛рд╡рд░рдг рдХреА рдПрдХ рдкреНрд░рддрд┐ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВред

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рд╕реНрдерд╛рдиреАрдп рдХрдорд╛рдВрдб рдЪрд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ред

рд╕рднреА 14 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВрдиреЗ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рд╡рд░реНрдгрди рдЦреЛрдЬрд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдХрдорд╛рдВрдб рдЪрд▓рд╛рдиреЗ рдкрд░ рдЗрд╕рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ

рдпрд╣ рд░рд┐рдореЛрдЯ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдХрдорд╛рдВрдб рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИ:

$ env | wc -l
      41
$ ssh testdeploy01.ec2.st-av.net env | wc -l
      14
$ ssh testdeploy01.ec2.st-av.net grep Env /etc/ssh/sshd_config
AcceptEnv LANG LC_*
         Specifies what environment variables sent by the client will be copied into
         the session's environ(7).  See SendEnv in ssh_config(5) for how to configure
         the client.  The TERM environment variable is always sent whenever the
         client requests a pseudo-terminal as it is required by the protocol.  Vari-
         ables are specified by name, which may contain the wildcard characters `*'
         and `?'.  Multiple environment variables may be separated by whitespace or
         spread across multiple AcceptEnv directives.  Be warned that some environ-
         ment variables could be used to bypass restricted user environments.  For
         this reason, care should be taken in the use of this directive.  The default
         is not to accept any environment variables.

рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдкреВрд░реЗ рд╕реНрдерд╛рдиреАрдп рдкрд░рд┐рд╡реЗрд╢ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рдХреЗ рдФрд░ рджреВрд╕рд░реА рддрд░рдл рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдХреЗ рд╕рднреА рдкрд░реНрдпрд╛рд╡рд░рдг рдЪрд░ рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд╛рдлреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рджреВрд░рд╕реНрде рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд▓рд┐рдП рдЙрдЪрд┐рдд рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рд╕рдВрдШрд░реНрд╖ рдХрд░реЗрдВрдЧреЗ, рдЬреИрд╕реЗ PATH , GOPATH (рдпрджрд┐ рдЖрдк рдЧреЛ рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ), TMPDIR , HOME , SSH_AUTH_SOCK , ...

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдореИрдВ рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореИрдВрдиреЗ рдПрдХ TODO рдЯрд┐рдкреНрдкрдгреА рдХреА рднреА рдЦреЛрдЬ рдХреА

рдЖрд╣, рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдБ, рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ

@ рдЕрдиреНрдпрд╛рдп рдореИрдВ рд╕реНрдерд╛рдиреАрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╣реНрд╡рд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реБрдЖ, рдореИрдВ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЖрдпрд╛рдд рдХрд░рддрд╛ рд╣реВрдВ:

from invoke import run as local

<strong i="7">@task</strong>
def test(c):
    local('ls')

рдпрд╣ # 1752 рдХрд╛ рдПрдХ рдкрд╣рд▓реВ рд╣реИ - рдЖрд╢рдп local рд▓рд┐рдП рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ Invoke рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдирд╛ рдФрд░ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рдирд╛, рдФрд░ SSH рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП run рд▓рд┐рдП рдФрд░ env рдХреЛ рддреНрдпрд╛рдЧрдирд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрднреА рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдЪрд▓рд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдареАрдХ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдирд╣реАрдВ рд╣реИрдВ - рдпрд╣ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ рдПрдХ рдмрдЧ рд╣реИред рд╣рдо рдЬрд▓реНрдж рд╣реА рдЗрд╕реЗ рдареАрдХ рдХрд░ рджреЗрдВрдЧреЗред

рдЬрд╡рд╛рдм рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рдореИрдВ рдмрд╕ рдПрдХ рд╣реА рдореБрджреНрджреЗ рдкрд░ рдЯрдХрд░рд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдореИрдВ рд╕рд┐рд░реНрдл рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рд╡рд╛рддрд╛рд╡рд░рдг рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЦрд╛рд░рд┐рдЬ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рд╢рд╛рдпрдж рдЖрдк рдЗрд╕ рдмрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реЛрдВред

рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛:

<strong i="8">@task</strong>
def test(c):
    c.run('echo $ENV', env={'ENV': 'production'}) # no output

рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рдпрд╣ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдорд┐рд▓рд╛ (рдмрд╣реБрдд рд╕рд╛рдл рдирд╣реАрдВ) рдЬрд┐рд╕рдХрд╛ рдореИрдВ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ:

<strong i="12">@task</strong>
def test(c):
    with c.prefix('ENV=production'):
        c.run('echo $ENV') # prints "production"

рд╣рд╛рдБ, рдЙрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!

рдЖрдк run('...', preserve_env=True) рдХреЛ рдЕрднреА рддрдХ IIRC рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред

preserve_env рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред рд╢рд╛рдпрдж рдЖрдк replace_env=False рдЬрд┐рдХреНрд░ рдХрд░ рд░рд╣реЗ рдереЗ?
рдпрд╣ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдкрд░реНрдпрд╛рд╡рд░рдг рдЕрднреА рднреА рдЦрд╛рд░рд┐рдЬ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рдкреБрдирд╢реНрдЪ: рдореБрдЭреЗ рджреВрд░рд╕реНрде рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд╛рддрд╛рд╡рд░рдг рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╕реНрдерд╛рдиреАрдп рдирд╣реАрдВред

рд╣рд╛рдБ, рдореЗрд░рд╛ рдорддрд▓рдм рдерд╛ replace_env рдФрд░ рдпрд╣ рдЕрдЬреАрдм рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЬрдм рдореИрдВ рд╕реНрдерд╛рдиреАрдп / рджреВрд░рд╕реНрде (# 1752) рдХреЗ рдмреАрдЪ рдХреЗ рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЗрдЦреВрдВрдЧрд╛

рдореИрдВ рдмрд╕ рдЗрд╕ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛ред рдореИрдВ c.run('make build') рдХрд░ рд░рд╣рд╛ рдерд╛ рдФрд░ рдореЗрд░реЗ рдХрд┐рд╕реА рднреА ENV рдиреЗ (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ GOPATH рдЬрд┐рд╕рдХреЗ рдХрд╛рд░рдг рдирд┐рд░реНрдорд╛рдг рд╡рд┐рдлрд▓ рд╣реЛ рдЧрдпрд╛ рдерд╛) рдЦреАрдВрдЪ рд▓рд┐рдпрд╛ред replace_env=False рдЬреЛрдбрд╝рдирд╛ рдЗрд╕реЗ рдареАрдХ рдХрд░рддрд╛ рд╣реИред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдореИрдВ рдбреЙрдХреНрд╕ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рджреЗрдЦрддрд╛ рд╣реВрдВ:

run.replace_env: рд╕рд╣реА, рдЧрд▓рдд рдХреЗ рдмрдЬрд╛рдп, рддрд╛рдХрд┐ рджреВрд░рд╕реНрде рдХрдорд╛рдВрдб 'рд╕реНрд╡рдЪреНрдЫ', рдЦрд╛рд▓реА рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде рдЪрд▓реЗрдВ, рдмрдЬрд╛рдп рд╡рд░реНрддрдорд╛рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ 'рдкрд░реНрдпрд╛рд╡рд░рдг рдХреА рдПрдХ рдкреНрд░рддрд┐ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВред

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдерд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдПрдХ рд╕реНрдерд╛рдиреАрдп рдХрдорд╛рдВрдб рдЪрд▓рд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛ред

рд╕реНрдерд╛рдиреАрдп рдХрдорд╛рдВрдб рдЪрд▓рд╛рддреЗ рд╕рдордп рд╕рдорд╕реНрдпрд╛ рдЕрднреА рднреА рд╣реИред @bitprophet

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕