Ansible 在 CentOS 7 上安装 JsReport

Ansible install JsReport on CentOS 7

我很难编写用于在 CentOS 7 上安装 JsReport 的 ansible 脚本。 我正在尝试翻译这些操作: https://jsreport.net/learn/centos

进入ansible脚本。

到目前为止我尝试的是:

- hosts: localhost
  tasks:
  - name: install wget
    yum:
      name: wget
      state: latest      
  - name: download nvm
    get_url: url=https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh  dest=/opt/nvm-install.sh 
  - name: Changing perm of "/opt/nvm-install.sh", adding "+x"
    file: dest=/opt/nvm-install.sh mode=a+x
  - name: Execute the script
    command: sh /opt/nvm-install.sh
  - name: Changing perm of "~/.nvm/nvm.sh", adding "+x"
    file: dest=~/.nvm/nvm.sh mode=a+x   

  - name: Make nvm command work in current terminal, Install node and set version, npm install jsreport-cli 
    shell: |
      source ~/.nvm/nvm.sh
      nvm install 8.11.3 
      npm install jsreport-cli -g
      mkdir jsreportapp
      jsreportapp
      jsreport init
      jsreport configure


  - name: download install-google-chrome.sh
    get_url: url=https://intoli.com/install-google-chrome.sh  dest=/opt/install-google-chrome.sh
  - name: Changing perm of "/opt/install-google-chrome.sh", adding "+x"
    file: dest=/opt/install-google-chrome.sh mode=a+x   
  - name: Execute the script
    command: sh /opt/install-google-chrome.sh

通常我使用以下命令启动 ansible 脚本:

sudo ansible-playbook install_jsreport.yml

我不确定在这里使用 sudo 是一个好的做法,还是我必须在这里使用 shell

在上面的脚本中出现以下错误:

fatal: [localhost]: FAILED! => {"changed": true, "cmd": "source ~/.nvm/nvm.sh\n nvm install 8.11.3\n npm install jsreport-cli -g\n mkdir jsreportapp\n jsreportapp\n jsreport init\n jsreport configure", "delta": "0:01:03.627957", "end": "2019-04-19 15:22:26.374742", "msg": "non-zero return code", "rc": -2, "start": "2019-04-19 15:21:22.746785", "stderr": "v8.11.3 is already installed.\nmkdir: cannot create directory ‘jsreportapp’: File exists\n/bin/sh: line 4: jsreportapp: command not found\nUnexpected error happened: Command failed: npm i -S jsreport\nsh: node: command not found\nnpm WARN pdfjs-dist@2.0.489 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.\nnpm WARN worker-loader@1.1.1 requires a peer of webpack@^2.0.0 || ^3.0.0 || ^4.0.0 but none is installed. You must install peer dependencies yourself.\nnpm WARN jsreport-server@ No description\nnpm WARN jsreport-server@ No repository field.\nnpm WARN jsreport-server@ No license field.\nnpm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.8 (node_modules/fsevents):\nnpm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.8: wanted {\"os\":\"darwin\",\"arch\":\"any\"} (current: {\"os\":\"linux\",\"arch\":\"x64\"})\n\nnpm ERR! file sh\nnpm ERR! code ELIFECYCLE\nnpm ERR! errno ENOENT\nnpm ERR! syscall spawn\nnpm ERR! puppeteer@1.12.2 install: node install.js\nnpm ERR! spawn ENOENT\nnpm ERR! \nnpm ERR! Failed at the puppeteer@1.12.2 install script.\nnpm ERR! This is probably not a problem with npm. There is likely additional logging output above.\n\nnpm ERR! A complete log of this run can be found in:\nnpm ERR!
/root/.npm/_logs/2019-04-19T13_22_24_770Z-debug.log\n (1). \ncaused by error (1) -> meta = {\"killed\":false,\"code\":1,\"signal\":null,\"cmd\":\"npm i -S jsreport\"}, stack = Error: \n at ChildProcess.exithandler (child_process.js:275:12)\n at emitTwo (events.js:126:13)\n at ChildProcess.emit (events.js:214:7)\n at maybeClose (internal/child_process.js:925:16)\n at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)", "stderr_lines": ["v8.11.3 is already installed.", "mkdir: cannot create directory ‘jsreportapp’: File exists", "/bin/sh: line 4: jsreportapp: command not found", "Unexpected error happened: Command failed: npm i -S jsreport", "sh: node: command not found", "npm WARN pdfjs-dist@2.0.489 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.", "npm WARN worker-loader@1.1.1 requires a peer of webpack@^2.0.0 || ^3.0.0 || ^4.0.0 but none is installed. You must install peer dependencies yourself.", "npm WARN jsreport-server@ No description", "npm WARN jsreport-server@ No repository field.", "npm WARN jsreport-server@ No license field.", "npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.8 (node_modules/fsevents):", "npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.8: wanted {\"os\":\"darwin\",\"arch\":\"any\"} (current: {\"os\":\"linux\",\"arch\":\"x64\"})", "", "npm ERR! file sh", "npm ERR! code ELIFECYCLE", "npm ERR! errno ENOENT", "npm ERR! syscall spawn", "npm ERR! puppeteer@1.12.2 install: node install.js", "npm ERR! spawn ENOENT", "npm ERR! ", "npm ERR! Failed at the puppeteer@1.12.2 install script.", "npm ERR! This is probably not a problem with npm. There is likely additional logging output above.", "", "npm ERR! A complete log of this run can be found in:", "npm ERR! /root/.npm/_logs/2019-04-19T13_22_24_770Z-debug.log", " (1). ", "caused by error (1) -> meta = {\"killed\":false,\"code\":1,\"signal\":null,\"cmd\":\"npm i -S jsreport\"}, stack = Error: ", " at ChildProcess.exithandler (child_process.js:275:12)", " at emitTwo (events.js:126:13)", "
at ChildProcess.emit (events.js:214:7)", " at maybeClose (internal/child_process.js:925:16)", " at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)"], "stdout": "Now using node v8.11.3 (npm v5.6.0)\n/root/.nvm/versions/node/v8.11.3/bin/jsreport -> /root/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/cli.js\n+ jsreport-cli@2.0.6\nadded 333 packages in 16.187s\njsreport installation not found, installing jsreport latest version now, wait a moment...\n? Do you want to enable web server? (Y/n) \u001b[42D\u001b[42C", "stdout_lines": ["Now using node v8.11.3 (npm v5.6.0)", "/root/.nvm/versions/node/v8.11.3/bin/jsreport -> /root/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/cli.js", "+ jsreport-cli@2.0.6", "added 333 packages in 16.187s", "jsreport installation not found, installing jsreport latest version now, wait a moment...", "? Do you want to enable web server? (Y/n) \u001b[42D\u001b[42C"]}

编辑(关于 larsks 的回答):

TASK [init jsreportapp directory] ************************************************************************************************************* fatal: [localhost]: FAILED! => {"changed": true, "cmd": ". ~/.nvm/nvm.sh\n jsreport init", "delta": "0:00:46.367234", "end": "2019-04-23 10:12:46.142142", "msg": "non-zero return code", "rc": 1, "start": "2019-04-23 10:11:59.774908", "stderr": "Unexpected error happened: Command failed: npm i -S jsreport\nsh: node: command not found\nnpm WARN pdfjs-dist@2.0.489 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.\nnpm WARN worker-loader@1.1.1 requires a peer of webpack@^2.0.0 || ^3.0.0 || ^4.0.0 but none is installed. You must install peer dependencies yourself.\nnpm WARN jsreport-server@ No description\nnpm WARN jsreport-server@ No repository field.\nnpm WARN jsreport-server@ No license field.\nnpm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.8 (node_modules/fsevents):\nnpm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.8: wanted {\"os\":\"darwin\",\"arch\":\"any\"} (current: {\"os\":\"linux\",\"arch\":\"x64\"})\n\nnpm ERR! file sh\nnpm ERR! code ELIFECYCLE\nnpm ERR! errno ENOENT\nnpm ERR! syscall spawn\nnpm ERR! puppeteer@1.12.2 install: node install.js\nnpm ERR! spawn ENOENT\nnpm ERR! \nnpm ERR! Failed at the puppeteer@1.12.2 install script.\nnpm ERR! This is probably not a problem with npm. There is likely additional logging output above.\n\nnpm ERR! A complete log of this run can be found in:\nnpm ERR!
/root/.npm/_logs/2019-04-23T08_12_46_089Z-debug.log\n (1). \ncaused by error (1) -> meta = {\"killed\":false,\"code\":1,\"signal\":null,\"cmd\":\"npm i -S jsreport\"}, stack = Error: \n at ChildProcess.exithandler (child_process.js:275:12)\n at emitTwo (events.js:126:13)\n at ChildProcess.emit (events.js:214:7)\n at maybeClose (internal/child_process.js:925:16)\n at Socket.stream.socket.on (internal/child_process.js:346:11)\n at emitOne (events.js:116:13)\n at Socket.emit (events.js:211:7)\n at Pipe._handle.close [as _onclose] (net.js:557:12)", "stderr_lines": ["Unexpected error happened: Command failed: npm i -S jsreport", "sh: node: command not found", "npm WARN pdfjs-dist@2.0.489 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.", "npm WARN worker-loader@1.1.1 requires a peer of webpack@^2.0.0 || ^3.0.0 || ^4.0.0 but none is installed. You must install peer dependencies yourself.", "npm WARN jsreport-server@ No description", "npm WARN jsreport-server@ No repository field.", "npm WARN jsreport-server@ No license field.", "npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.8 (node_modules/fsevents):", "npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.8: wanted {\"os\":\"darwin\",\"arch\":\"any\"} (current: {\"os\":\"linux\",\"arch\":\"x64\"})", "", "npm ERR! file sh", "npm ERR! code ELIFECYCLE", "npm ERR! errno ENOENT", "npm ERR! syscall spawn", "npm ERR! puppeteer@1.12.2 install: node install.js", "npm ERR! spawn ENOENT", "npm ERR! ", "npm ERR! Failed at the puppeteer@1.12.2 install script.", "npm ERR! This is probably not a problem with npm. There is likely additional logging output above.", "", "npm ERR! A complete log of this run can be found in:", "npm ERR! /root/.npm/_logs/2019-04-23T08_12_46_089Z-debug.log", " (1). ", "caused by error (1) -> meta = {\"killed\":false,\"code\":1,\"signal\":null,\"cmd\":\"npm i -S jsreport\"}, stack = Error: ", " at ChildProcess.exithandler (child_process.js:275:12)", " at emitTwo (events.js:126:13)", "
at ChildProcess.emit (events.js:214:7)", " at maybeClose (internal/child_process.js:925:16)", " at Socket.stream.socket.on (internal/child_process.js:346:11)", " at emitOne (events.js:116:13)", " at Socket.emit (events.js:211:7)", " at Pipe._handle.close [as _onclose] (net.js:557:12)"], "stdout": "jsreport installation not found, installing jsreport latest version now, wait a moment...", "stdout_lines": ["jsreport installation not found, installing jsreport latest version now, wait a moment..."]}

EDIT2:

删除 temp 并在本地主机上执行这些命令后:

sudo chmod 777 -R jsReport/
npm install puppeteer jsreport-chrome-pdf

然后 运行使用 sudo 连接你的剧本,它没有错误地工作。

编辑 3:

添加:

- name: install puppeteer 
  shell: |
    . ~/.nvm/nvm.sh
    npm install puppeteer  -g
  args:
    creates: "~/.nvm/versions/node/v{{ node_version }}/lib/node_modules/puppeteer "        

给出以下错误:

TASK [install puppeteer] ********************************************************************************************************************************************************************************************** fatal: [localhost]: FAILED! => {"changed": true, "cmd": ". ~/.nvm/nvm.sh\n npm install puppeteer -g", "delta": "0:00:04.178220", "end": "2019-04-23 11:39:44.413525", "msg": "non-zero return code", "rc": 1, "start": "2019-04-23 11:39:40.235305", "stderr": "sh: node: command not found\nnpm ERR! file sh\nnpm ERR! code ELIFECYCLE\nnpm ERR! errno ENOENT\nnpm ERR! syscall spawn\nnpm ERR! puppeteer@1.14.0 install: node install.js\nnpm ERR! spawn ENOENT\nnpm ERR! \nnpm ERR! Failed at the puppeteer@1.14.0 install script.\nnpm ERR! This is probably not a problem with npm. There is likely additional logging output above.\n\nnpm ERR! A complete log of this run can be found in:\nnpm ERR!
/root/.npm/_logs/2019-04-23T09_39_44_391Z-debug.log", "stderr_lines": ["sh: node: command not found", "npm ERR! file sh", "npm ERR! code ELIFECYCLE", "npm ERR! errno ENOENT", "npm ERR! syscall spawn", "npm ERR! puppeteer@1.14.0 install: node install.js", "npm ERR! spawn ENOENT", "npm ERR! ", "npm ERR! Failed at the puppeteer@1.14.0 install script.", "npm ERR! This is probably not a problem with npm. There is likely additional logging output above.", "", "npm ERR! A complete log of this run can be found in:", "npm ERR!
/root/.npm/_logs/2019-04-23T09_39_44_391Z-debug.log"], "stdout": "\n> puppeteer@1.14.0 install /root/.nvm/versions/node/v8.11.3/lib/node_modules/puppeteer\n> node install.js", "stdout_lines": ["", "> puppeteer@1.14.0 install /root/.nvm/versions/node/v8.11.3/lib/node_modules/puppeteer", "> node install.js"]}

编辑4:

我试过这样的事情:

---
- hosts: localhost
  vars:
    node_version: 8.11.3
    nvm_version: 0.33.11

  tasks:

    - name: Add the user 'jsreport'
      user:
        name: jsreport
        system: true  

    - name: install wget
      yum:
        name: wget
        state: latest
      become: true
      become_user: jsreport   

    - name: download nvm
      get_url:
        url: "https://raw.githubusercontent.com/creationix/nvm/v{{ nvm_version }}/install.sh"
        dest: /opt/nvm-install.sh
      become: true
      become_user: jsreport    

    - name: Changing perm of "/opt/nvm-install.sh", adding "+x"
      file:
        dest: /opt/nvm-install.sh
        mode: "a+x"
      become: true
      become_user: jsreport  

    - name: Execute the script
      command: /opt/nvm-install.sh
      args:
        creates: ~/.nvm/nvm.sh
      become: true
      become_user: jsreport  

    - name: Changing perm of "~/.nvm/nvm.sh", adding "+x"
      file:
        dest: ~/.nvm/nvm.sh
        mode: "a+x"
      become: true
      become_user: jsreport  

    - name: install node
      shell: |
        . ~/.nvm/nvm.sh
        nvm install {{ node_version }}
      args:
        creates: "~/.nvm/versions/node/v{{ node_version }}"
      become: true
      become_user: jsreport  

    - name: install jsreport-cli
      shell: |
        . ~/.nvm/nvm.sh
        npm install jsreport-cli -g
      args:
        creates: "~/.nvm/versions/node/v{{ node_version }}/lib/node_modules/jsreport-cli"
      become: true
      become_user: jsreport  


    - name: install jsreport-chrome-pdf
      shell: |
        . ~/.nvm/nvm.sh
        npm install jsreport-chrome-pdf -g
      args:
        creates: "~/.nvm/versions/node/v{{ node_version }}/lib/node_modules/jsreport-chrome-pdf"       
      become: true
      become_user: jsreport  


    - name: install puppeteer 
      shell: |
        . ~/.nvm/nvm.sh
        npm install puppeteer  -g
      become: true
      become_user: jsreport  
      args:
        creates: "~.nvm/versions/node/v{{ node_version }}/lib/node_modules/puppeteer "    

    - name: create jsreportapp directory
      file:
        path: ./jsreportapp
        state: directory
      become: true
      become_user: jsreport  


    - name: init jsreportapp directory
      shell: |
        . ~/.nvm/nvm.sh
        jsreport init
      args:
        chdir: ./jsreportapp
        creates: ./package-lock.json
      become: true
      become_user: jsreport  

之后当我在用户 jsreport 我运行jsreport configure命令 然后我编辑了这个配置来设置:

"chrome": { "launchOptions": { "args": ["--no-sandbox"] } }

然后我 运行 jsreport start 并得到错误提示:

Couldn't find a jsreport installation necessary to check if the command is available, if the command is a valid one try to install jsreport first. (1). caused by error (1) -> stack = Error: at Promise (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/lib/instanceHandler.js:55:21) at new Promise () at Object.find (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/lib/instanceHandler.js:47:10) at getInstance (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/lib/commander.js:768:10) at exports.handler (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/lib/commands/start.js:56:5) at Commander.executeCommand (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/lib/commander.js:389:28) at Object.handler (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/lib/commander.js:559:16) at Object.self.runCommand (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/node_modules/yargs/lib/command.js:170:22) at parseArgs (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/node_modules/yargs/yargs.js:920:28) at Object.Yargs.self.parse (/home/jsreport/.nvm/versions/node/v8.11.3/lib/node_modules/jsreport-cli/node_modules/yargs/yargs.js:499:18)

您的剧本在以下阶段失败

    shell: |
      source ~/.nvm/nvm.sh
      nvm install 8.11.3 
      npm install jsreport-cli -g
      mkdir jsreportapp
      jsreportapp
      jsreport init
      jsreport configure

您可以将其进一步分解为多个任务。

这是您应该首先尝试的 https://github.com/geerlingguy/ansible-role-nodejs

另请查看本指南以了解 node 模块安装 https://docs.ansible.com/ansible/latest/modules/npm_module.html

这里的根本问题是 jsreport configure 命令是交互式的。如果您手动 运行 它,您会看到:

$ jsreport configure
? Do you want to enable web server? (Y/n)     

但是如果你 运行 该命令没有附加终端(这是 Ansible 运行 的方式),它将失败并返回非零退出代码:

[root@365f191cdad1 ~]# jsreport configure < /dev/null 
? Do you want to enable web server? (Y/n) 
[root@365f191cdad1 ~]# echo $?
130

因为这是您的 shell 脚本中的最后一个命令,所以它成为您的 shell 脚本的退出代码。由于您的 shell 脚本以非零错误退出,Ansible 认为任务失败,并中止剧本。

如果您要删除对 jsreport configure 的调用,您的剧本将 几乎 有效,除非您的脚本中似乎有错字。你有:

  mkdir jsreportapp
  jsreportapp

我认为你缺少 cd 那里:

  mkdir jsreportapp
  cd jsreportapp

换句话说,这运行没有错误:

- hosts: localhost
  tasks:
  - name: install wget
    yum:
      name: wget
      state: latest      
  - name: download nvm
    get_url: url=https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh  dest=/opt/nvm-install.sh 
  - name: Changing perm of "/opt/nvm-install.sh", adding "+x"
    file: dest=/opt/nvm-install.sh mode=a+x
  - name: Execute the script
    command: sh /opt/nvm-install.sh
  - name: Changing perm of "~/.nvm/nvm.sh", adding "+x"
    file: dest=~/.nvm/nvm.sh mode=a+x   
  - name: Make nvm command work in current terminal, Install node and set version, npm install jsreport-cli 
    shell: |
      source ~/.nvm/nvm.sh
      nvm install 8.11.3 
      npm install jsreport-cli -g
      mkdir jsreportapp
      cd jsreportapp
      jsreport init

但是这里还有很多值得修复的地方。首先,您从 mkdir jsreportapp 收到一个错误,如果该目录已经存在,该错误将失败。您可以改为调用 mkdir -p,但最好将其移动到一个单独的任务中,然后按照 OmPrakashP 的建议拆分您的最终任务:

- name: install node
  shell: |
    . ~/.nvm/nvm.sh
    nvm install 8.11.3

- name: install jsreport-cli
  shell: |
    . ~/.nvm/nvm.sh
    npm install jsreport-cli -g

- name: create jsreportapp directory
  file:
    path: ./jsreportapp
    state: directory

- name: init jsreportapp directory
  shell: |
    . ~/.nvm/nvm.sh
    jsreport init
  args:
    chdir: ./jsreportapp

而不是 运行ning jsreport configure,这是一个交互式命令,考虑只使用 Ansible copy 任务复制适当的 jsreport.config.json,或者使用模板化它template 模块,如果你希望能够动态设置内容作为剧本的一部分 运行。

我的最终剧本——包括一些小的风格变化(始终对模块选项使用 yaml 语法,而不是 key=value)和一些幂等性变化(避免重新 运行 安装任务等)- - 看起来像这样:

---
- hosts: localhost
  vars:
    node_version: 8.11.3
    nvm_version: 0.33.11

  tasks:

    - name: install wget
      become: true
      yum:
        name: wget
        state: latest

    - name: download nvm
      get_url:
        url: https://raw.githubusercontent.com/creationix/nvm/v{{ nvm_version }}/install.sh
        dest: ~/nvm-install.sh

    - name: Changing perm of "/opt/nvm-install.sh", adding "+x"
      file:
        dest: ~/nvm-install.sh
        mode: "a+x"

    - name: Execute the script
      command: ~/nvm-install.sh
      args:
        creates: ~/.nvm/nvm.sh

    - name: Changing perm of "~/.nvm/nvm.sh", adding "+x"
      file:
        dest: ~/.nvm/nvm.sh
        mode: "a+x"

    - name: install node
      shell: |
        . ~/.nvm/nvm.sh
        nvm install {{ node_version }}
      args:
        creates: "~/.nvm/versions/node/v{{ node_version }}"

    - name: install jsreport-cli
      shell: |
        . ~/.nvm/nvm.sh
        npm install jsreport-cli -g
      args:
        creates: "~/.nvm/versions/node/v{{ node_version }}/lib/node_modules/jsreport-cli"

    - name: create jsreportapp directory
      file:
        path: ./jsreportapp
        state: directory

    - name: init jsreportapp directory
      shell: |
        . ~/.nvm/nvm.sh
        jsreport init
      args:
        chdir: ./jsreportapp
        creates: ./package-lock.json

您可以在 this repository 中找到上述剧本。

更新

我已经编辑了 playbook,因此它 运行 可以作为非 root 用户成功使用。这涉及 (a) 添加 become: truewget 安装任务和 (b) 安装 nvm-install.sh 到当前用户主目录而不是 /opt.

您可以在这里以非 root 用户身份成功看到此 运行ning:

并且运行第二次成功:

如您所见,您报告的错误不会突然出现,并且可能与您的环境有关。您可能想尝试从新系统开始。

在 运行ning jsreport start 之前,请记住您需要在 ~/.nvm/nvm.sh 脚本中获取源代码。如果你这样做它似乎工作成功: