【问题标题】:The most clear and concise way to describe SSH commands in .gitlab-ci.yml.gitlab-ci.yml 中描述 SSH 命令的最清晰简洁的方式
【发布时间】:2019-06-30 10:47:51
【问题描述】:

通常我在.gitlab-ci.yml 中做以下工作,通过 SSH 在远程服务器上执行命令:

# The job
deploy:
  script:
    # I've omitted the SSH setup here
    - |
      ssh gitlab@example.com "
        # Makes the server print the executed commands to stdout. Otherwise only the command output is printed. Required for monitoring and debug.
        set -x &&

        # Executes some commands
        cd /var/www/example &&
        command1 &&
        command2 &&
        command3 &&
        command4 &&
        command5
      "

它可以正常工作,但是 YAML 代码看起来太复杂了:

  • set -x 命令与其说是有用的代码,不如说是一个样板。普通 CI 命令不需要它,因为 GitLab CI 会自动打印它们。
  • 每行上的&& 也是样板文件。当其中一个命令失败时,它们会使执行停止。否则下一个命令将在一个失败时执行(与普通作业命令相反)。
  • 所有 SSH 命令都是单个 YAML 字符串,因此编辑器不会突出显示 cmets 和命令,因此代码难以阅读。

有没有更清晰便捷的方式在远程机器上通过 SSH 执行多个命令而没有上述缺点?

我不想使用像 Ansible 这样的外部部署工具来保持 CD 配置尽可能简单(欢迎使用默认 POSIX/Linux 命令)。我也考虑过在单独的ssh 调用中运行每个命令,但我担心它可能会因为多个 SSH 连接建立而增加作业执行时间(但我不确定):

deploy:
  script:
    - ssh gitlab@example.com "cd /var/www/example"
    - ssh gitlab@example.com "command1"
    - ssh gitlab@example.com "command2"
    # ...

【问题讨论】:

    标签: linux shell ssh gitlab-ci continuous-deployment


    【解决方案1】:

    更简洁明了的方法是使用set -e。当其中一个命令失败时,它会使整个脚本失败。它让你不要在每一行都使用&&

    # The job
    deploy:
      script:
        # I've omitted the SSH setup here
        - |
          ssh gitlab@example.com "
            # Makes the server print the executed commands to stdout. Makes the execution stop when one of the commands fails.
            set -x -e
    
            # Executes some commands
            cd /var/www/example
            command1
            command2
            command3
            command4
            command5
    
            # Even complex commands
            if [ -f ./.env ]
              then command6
              else
                echo 'Environment is not set up'
                exit 1
            fi
          "
    

    【讨论】:

      【解决方案2】:

      将您的命令保存在单独的文件中remote.sh,不带set -x&&

      #!/usr/bin/env bash
      # Executes some commands
      cd /var/www/example
      command1
      command2
      command3
      command4
      command5
      

      并使用eval 在远程服务器上运行它们:

      deploy:
        script:
          - ssh gitlab@example.com "eval '$(cat ./remote.sh)'"
      

      这种方法将使 YAML 保持简单和干净,并满足您的所有要求。

      【讨论】:

      • 另外,如果需要,您可以在本地使用 shell 脚本
      • 感谢您的回答,它启用了 sh 语法高亮。但不幸的是,它有不足之处。不打印执行的命令(仍然需要set -x)并且当来自remote.sh 的命令失败时执行不会停止(仍然需要&&)。我也不能在remote.sh 中使用',因为它会干扰CI 命令文本。
      • '问题可以通过运行ssh gitlab@example.com "bash -" < ./remote.shcat ./remote.sh | ssh gitlab@example.com "bash -"来解决
      猜你喜欢
      • 2010-12-04
      • 2012-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多