使用 Ansible 安装 Dart 的包

Install Dart's package using Ansible

我有以下 Ansible 任务来安装 Dart:

---

# Install Dart

# Based on:
# - https://www.dartlang.org/install/linux#using-apt-get
# - https://github.com/jgrowl/ansible-dart

- name: install apt-transport-https required by Dart
  apt: pkg=apt-transport-https update_cache=yes state=latest

# Get the Google Linux package signing key.
- apt_key: url=https://dl-ssl.google.com/linux/linux_signing_key.pub state=present

# Set up the location of the stable repository.
- name: download dart source list
  get_url: url=https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list dest=/etc/apt/sources.list.d/dart_stable.list mode=0644

# Set up for the dev channel
# Before running this command, follow the instructions in
# "Set up for the stable channel".
#$ sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_unstable.list > /etc/apt/sources.list.d/dart_unstable.list'
- apt: name=dart update_cache=yes state=present

- name: Add dart and tools to PATH
  template: src=dart.sh.j2 dest=/etc/profile.d/dart.sh owner=root group=root mode=0655
  notify:
     - install stagehand

看来 Dart 安装正确。问题是当我最后通知 install stagehand 时。该处理程序如下

---

# Called after installing Dart to install Dart's package stagehand
- name: install stagehand
  shell: pub global activate stagehand

但我不断收到以下错误:

...

TASK [install stagehand] *******************************************************
fatal: [default]: FAILED! => {"changed": true, "cmd": "pub global activate stagehand", "delta": "0:00:00.001392", "end": "2017-02-13 02:03:06.679762", "failed": true, "rc": 127, "start": "2017-02-13 02:03:06.678370", "stderr": "/bin/sh: 1: pub: not found", "stdout": "", "stdout_lines": [], "warnings": []}
    to retry, use: --limit 

@/Users/X/Desktop/path_to_project/provision/ansible/playbook.retry

这很奇怪,因为如果我尝试使用 vagrant ssh 登录 Vagrant VM 并键入 pub,Dart 的打包程序管理器已安装!

由于我对 Ansible 以及我正在使用的所有其他技术都很陌生,这也可能是一个问题,因为我仍然不知道 Ansible 的确切工作原理。

编辑

这个文件(即 dart.sh.j2)理论上也应该导出 pub:

# Add vendor binaries to the path
PATH=$PATH:/usr/lib/dart/bin

编辑 2

这是 Vagrantfile(根据要求):

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"

  config.vm.network :forwarded_port, guest: 80, host: 4567

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"  
  end

  # Run Ansible from the Vagrant Host
  config.vm.provision "ansible" do |ansible|
      ansible.playbook = "provision/ansible/playbook.yml"
  end

end

您的 dart.sh 不是 non-interactive、non-login shell 会话的来源。这就是为什么当以交互方式登录和 运行 通过 SSH 编写脚本时,您会看到不同的结果。

给定文件内容,使用 pub 可执行文件的完整路径(可能您不需要 shell 模块, command 就足够了):

# Called after installing Dart to install Dart's package stagehand
- name: install stagehand
  command: /usr/lib/dart/bin/pub global activate stagehand

您的解决方案有两个问题。

第一个是,默认情况下shell命令使用non-interactive,non-login shell,所以它会完全跳过运行ning /etc/profile.d/dart.sh,因此你的 PATH 添加。

但是,如果您使用登录名 shell,它将正常工作,因为登录名 shell 确实读取 /etc/profile.d:

- hosts: all
  tasks:
    - name: install stagehand
      shell: bash -lc "pub global activate stagehand"

第二个问题是默认情况下,pub 会将所有软件包安装到 ~/.pub-cache/bin 中,这也不在您的 PATH 中(另请注意,它只会为调用用户安装它:vagrant,因此其他用户将无法使用它)。例如,可以使用 lineinfile.

更改 vagrant 用户配置文件中的 PATH

一个完整的、有效的剧本示例:

- hosts: all
  roles:
    - { role: ansible-dart, when: ansible_os_family == "Debian", become: yes }

- hosts: all
  tasks:
    - name: "Add pub cache to PATH"
      lineinfile:
        dest: /home/vagrant/.profile
        line: 'PATH=$PATH:/home/vagrant/.pub-cache/bin'

    - name: install stagehand
      shell: bash -lc "pub global activate stagehand"

您可以将其放在 provision/ansible/playbook.yml 下,然后将 ansible-dart 克隆到 provision/ansible/roles 目录中。原来的 ansible-dart 似乎有点过时了,所以我对 my fork 添加了一些小的修复,包括使用 become 代替 sudo,并安装 unzip,因为现在需要这样做。

示例运行:

$ vagrant up
(...)
PLAY ***************************************************************************

TASK [ansible-dart : include] **************************************************
included: provision/ansible/roles/ansible-dart/tasks/Debian.yml for default
(...)
PLAY ***************************************************************************

TASK [Add pub cache to PATH] ***************************************************
changed: [default]

TASK [install stagehand] *******************************************************
changed: [default]

PLAY RECAP *********************************************************************
default                    : ok=12   changed=10   unreachable=0    failed=0
$ vagrant ssh -c stagehand
Welcome to Stagehand! We collect anonymous usage statistics and crash reports in
order to improve the tool. Would you like to opt-in to
additional analytics to help us improve Stagehand [y/yes/no]?

如果您不想一直使用 bash -lc,则必须在您的剧本中手动设置 PATH 值。如果你想主要通过 ansible 管理这台计算机,并且不需要交互式终端访问,这将很有用:

- hosts: all
  environment:
    PATH: "{{ ansible_env.PATH }}:/usr/lib/dart/bin:/home/vagrant/.pub-cache/bin"
  tasks:   
    - name: install stagehand
      shell: pub global activate stagehand

显然,如果需要,您也可以混合使用这两种方法。

根据 SztupY 的回答,我设法在 Vagrant 虚拟机中 激活 Dart 的包 stagehandubuntu/trusty64.

这些是我在相应版本中使用的工具(以防有人因为类似的问题而在这个 post 中结束):

+=================+============================+=========================================================+
|      Tool       |            Version         |                         Comments                        |
+=================+============================+=========================================================+
| Ansible         |   2.2.1.0                  |  configured module search path = Default w/o overrides  |
+-----------------+----------------------------+---------------------------------------------------------+
| Vagrant         |  1.9.1                     |                                                         |
+-----------------+----------------------------+---------------------------------------------------------+
| ubuntu/trusty64 | (virtualbox, 20170202.1.0) |                                                         |
+-----------------+----------------------------+---------------------------------------------------------+
| ansible-dart    |                            |    Source: https://github.com/nbro/ansible-dart         |
+-----------------+----------------------------+---------------------------------------------------------+

我将Github项目ansible-dart的下载文件夹放在roles文件夹下,该文件夹位于provision文件夹的主文件夹下(在我的例子中我称之为provision/ansible),其中包含 playbook.yml 文件。

- name: provisioning project...

  hosts: all

  roles:
    - { role: ansible-dart, when: ansible_os_family == "Debian", become: true }

  tasks:
    - name: "add .pub-cache to PATH"
      lineinfile:
        dest: /home/vagrant/.profile
        line: 'PATH=$PATH:/home/vagrant/.pub-cache/bin'

    - name: activate Dart's package 'stagehand'
      shell: bash -lc "pub global activate stagehand"