Fabric 3询问一次sudo密码

时间:2018-09-27 15:13:41

标签: python fabric

我正在使用Fabric来自动化一些部署工作。下面是我使用的代码示例:

run(f"sudo -H -u www-data bash -c 'rm -r project_name' ")
run(f"sudo -H -u www-data bash -c '/opt/www-data/project-name/bin/pip install -r requirements.txt' ")

run("sudo systemctl stop gunicorn")
run("sudo systemctl start gunicorn")

每次运行每一行代码时,终端都会要求我输入用户密码,有没有办法我只能输入一次密码?

编辑: 我使用的是python3,脚本的本质是在其他用户而非我自己的用户上运行命令。

更新:

我通过使用带有“ -I”参数的fabric实现了这一目标。

fabric -I deploy

4 个答案:

答案 0 :(得分:0)

使用run并不是实现此目的的理想方法。

fabric.operations.sudo(*args, **kwargs)是可以用来实现您正在尝试的东西的。 请注意sudo:)

答案 1 :(得分:0)

每个run()调用都是一个单独的shell,与sudo()调用一样。 sudo凭据是针对每个shell的,因此它们每次都消失了。

一种快速而肮脏的方法是将所有命令集中到一个sudo调用中。

一种更好的方法是在目标主机上具有sudoers file,并为每个用户提供运行特定命令所需的特权,而无需输入密码。

答案 2 :(得分:0)

您可以创建如下所示的fab脚本,然后遍历要运行命令的主机列表,因为可以在脚本本身中传递wdd用户名和密码,从而避免密码调用:

class LoginForm extends Component {
  constructor(props) {
    super(props)
  }

  renderButton() {
    if(this.props.loading) {
      return <Spinner size="large" />
    }

    return (
      <Button onPress={this.handlePress}>
        Login
      </Button>
    )
  }

  renderError() {
    if(this.props.error) {
      return (
        <View style={{ backgroundColor: 'white', }}>
          <Text style={{ color: 'red', alignSelf: 'center' }}> 
            { this.props.error } 
          </Text>
        </View>
      )
    }
  }

  handlePress() {
    const { email, password } = this.props
    this.props.loginUser({ email, password })
  }

  render() {
    const { email, updateInputField, password } = this.props

    return (
      <View>
        <Card>

          {/*
            E-Mail
          */}
          <CardSection>
            <Input
              value={email}
              onChangeText={value => updateInputField('email', value)}
              label="Email"
              autoCorrect={false}
              placeholder="example@gmail.com"
            />
          </CardSection>

          {/*
            Password
          */}
          <CardSection>
            <Input
              value={password}
              onChangeText={value => updateInputField('password', value)}
              label="Password"
              autoCorrect={false}
              secureTextEntry
            />
          </CardSection>

          { this.renderError() }

          <CardSection>
            { this.renderButton() }
          </CardSection>

        </Card>
      </View>
    )
  }
}

const mapStateToProps = ({ auth }) => {
  const { email, password, loading, error } = auth
  return { email, password, loading, error }
}

export default connect(
  mapStateToProps,
  {
    updateInputField,
    loginUser
  }
  )(LoginForm)

示例hostfile.txt:

# testCheck.py
#!/usr/bin/python2.7
import sys
from fabric.api import *
env.skip_bad_hosts=True
env.command_timeout=160
env.user = 'user_name'
env.shell = "/bin/sh -c"
env.warn_only = True
env.password = 'user_password'
def readhost():
    env.hosts = [line.strip() for line in sys.stdin.readlines()]

def hosts():
  with settings(warn_only=True):

      output=sudo("ls -l /myfolder",shell=False)


# cat hostfile.txt| | /usr/local/bin/fab readhost -f testCheck.py hosts -P -z 5

OR supplying password at command line
# cat hostfile.txt | /usr/local/bin/fab readhost -f testCheck.py --password=your_pass hosts -P -z 5


--> argument "-P" refers to  parallel execution method
--> argument "-z" refres to the number of concurrent processes to use in parallel mode

希望这会有所帮助。

答案 3 :(得分:0)

如果使用的是ssh键,则设置结构环境变量key_filename

env.key_filename='/path/to/key.pem'

# set the following as well
env.user='username'
env.host='hostaddr'

它只会询问您一次密码。
看看有关this的问题,该问题与在使用Fabric时避免输入任何sudo密码有关。