通过 ssh 密钥转发进行身份验证时克隆 git 存储库的最佳方法
Best way to clone a git repository when authenticating via ssh key forwarding
先决条件:
- 主机 & git 身份验证通过 ssh 密钥进行
- ssh 密钥转发已启用
- 我们团队的每个用户都使用专用用户帐户 - 无法通过无头用户帐户登录
现在我们要从 git 存储库部署应用程序。这应该很简单,但事实并非如此。
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Restart app
githost 是我们 .ssh/config[=71 中的一个条目=]
以上任务有效。但是存储库(当然)被克隆为执行剧本的用户。我们需要的是:
- 所有文件都应归无头用户所有,我们称他为
zaphod
- 只允许
zaphod
读取 文件。我们说的是 0600/0700 权限。
以下任务将无法执行,因为使用 become
我们将丢失转发的 ssh 密钥,因此 git 身份验证将失败:
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Restart app
become: yes
become_user: zaphod
以下变体将首先调用一个处理程序,该处理程序在(重新)启动应用程序之前更改结帐的所有权:
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Fix ownership
- Restart app
这一次有效。但是,如果您 运行 剧本第二次 git 任务失败,因为 运行 剧本的用户没有修改克隆的权限。
我们有一个非常丑陋的解决方案:
- 克隆到 /tmp/foo
- 修复 /tmp/foo
的所有权
rm -rf /some/location
mv /tmp/foo /some/location
- 终于(重新)启动应用程序
问题是这会:
- 每次执行剧本时触发重启
- Ansible 摘要显示 5 个已更改的任务,尽管什么也没发生——除了一开始不需要的重启
我在这里有点挑剔,但我只想在某些事情真的发生变化时改变状态,所以在一个完美的世界中,甚至 git 任务也不会有改变的状态。为此,我看不到解决方案。因为我们要求克隆的文件只能由 zaphod
访问 - 但 zaphod
自己无法克隆 repo。所以必须有一些操纵是某种形式导致变化。
有什么可以以干净的方式改进它的建议吗?我不想再添加 20 个临时副本、临时更改权限、手动比较文件等等的任务...
当然,自定义编写的模块能够处理所有这些 - 但我更感兴趣的是不需要 2 天的开发和实战测试。 ;-)
看起来您正在尝试通过简单地克隆包含您需要的内容的存储库来部署 application/webpage,而不是需要能够将任何更改从该服务器推送回存储库。
如果是这种情况,那么您可以完成 git archive
the repo into a tarball or something and then use unarchive
的本地任务,将生成的存档复制到目标机器并解压缩。 unarchive
将允许您设置权限和所有权。
所以你的剧本可能是这样的:
- name: locally clone repo
git:
repo: githost:org/repo.git
dest: /some/tmp/location
version: HEAD
force: yes
delegate_to: localhost
changed_when: false #
- name: archive app repo
command: git archive --format zip --output /path/to/archive master
chdir: /some/tmp/location
delegate_to: localhost
changed_when: false
- name: unarchive app repo
unarchive:
src: /path/to/archive
dest: /some/location
owner: zaphod
mode: 0700
creates: /some/location
notify:
- Restart app
基于@ydaetskcoR 的回答,以下版本也适用:
- name: locally clone repo
git:
repo: githost:org/repo.git
dest: /some/tmp/location
version: HEAD
force: yes
delegate_to: localhost
- name: archive app repo
archive:
path: /some/tmp/location
dest: /some/tmp/archive.tgz
delegate_to: localhost
- name: unarchive app repo
unarchive:
src: /some/tmp/archive.tgz
dest: /some/remote/location
owner: zaphod
mode: 0700
notify:
- Restart app
先决条件:
- 主机 & git 身份验证通过 ssh 密钥进行
- ssh 密钥转发已启用
- 我们团队的每个用户都使用专用用户帐户 - 无法通过无头用户帐户登录
现在我们要从 git 存储库部署应用程序。这应该很简单,但事实并非如此。
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Restart app
githost 是我们 .ssh/config[=71 中的一个条目=]
以上任务有效。但是存储库(当然)被克隆为执行剧本的用户。我们需要的是:
- 所有文件都应归无头用户所有,我们称他为
zaphod
- 只允许
zaphod
读取 文件。我们说的是 0600/0700 权限。
以下任务将无法执行,因为使用 become
我们将丢失转发的 ssh 密钥,因此 git 身份验证将失败:
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Restart app
become: yes
become_user: zaphod
以下变体将首先调用一个处理程序,该处理程序在(重新)启动应用程序之前更改结帐的所有权:
- name: Clone app repo
git:
repo: githost:org/repo.git
dest: /some/location
version: HEAD
force: yes
ssh_opts: -o StrictHostKeyChecking=no
notify:
- Fix ownership
- Restart app
这一次有效。但是,如果您 运行 剧本第二次 git 任务失败,因为 运行 剧本的用户没有修改克隆的权限。
我们有一个非常丑陋的解决方案:
- 克隆到 /tmp/foo
- 修复 /tmp/foo 的所有权
rm -rf /some/location
mv /tmp/foo /some/location
- 终于(重新)启动应用程序
问题是这会:
- 每次执行剧本时触发重启
- Ansible 摘要显示 5 个已更改的任务,尽管什么也没发生——除了一开始不需要的重启
我在这里有点挑剔,但我只想在某些事情真的发生变化时改变状态,所以在一个完美的世界中,甚至 git 任务也不会有改变的状态。为此,我看不到解决方案。因为我们要求克隆的文件只能由 zaphod
访问 - 但 zaphod
自己无法克隆 repo。所以必须有一些操纵是某种形式导致变化。
有什么可以以干净的方式改进它的建议吗?我不想再添加 20 个临时副本、临时更改权限、手动比较文件等等的任务...
当然,自定义编写的模块能够处理所有这些 - 但我更感兴趣的是不需要 2 天的开发和实战测试。 ;-)
看起来您正在尝试通过简单地克隆包含您需要的内容的存储库来部署 application/webpage,而不是需要能够将任何更改从该服务器推送回存储库。
如果是这种情况,那么您可以完成 git archive
the repo into a tarball or something and then use unarchive
的本地任务,将生成的存档复制到目标机器并解压缩。 unarchive
将允许您设置权限和所有权。
所以你的剧本可能是这样的:
- name: locally clone repo
git:
repo: githost:org/repo.git
dest: /some/tmp/location
version: HEAD
force: yes
delegate_to: localhost
changed_when: false #
- name: archive app repo
command: git archive --format zip --output /path/to/archive master
chdir: /some/tmp/location
delegate_to: localhost
changed_when: false
- name: unarchive app repo
unarchive:
src: /path/to/archive
dest: /some/location
owner: zaphod
mode: 0700
creates: /some/location
notify:
- Restart app
基于@ydaetskcoR 的回答,以下版本也适用:
- name: locally clone repo
git:
repo: githost:org/repo.git
dest: /some/tmp/location
version: HEAD
force: yes
delegate_to: localhost
- name: archive app repo
archive:
path: /some/tmp/location
dest: /some/tmp/archive.tgz
delegate_to: localhost
- name: unarchive app repo
unarchive:
src: /some/tmp/archive.tgz
dest: /some/remote/location
owner: zaphod
mode: 0700
notify:
- Restart app