I am having hard time writing ansible script for installing JsReport on CentOS 7. I am trying to translate these operations: https://jsreport.net/learn/centos
into ansible script.
What i tried so far is:
- 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
Usually i start the ansible scripts with follow command:
sudo ansible-playbook install_jsreport.yml
I am not sure is that a good practice to use sudo
here, or do i have to use shell
here?
In the script above i get following error:
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 [email protected] requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.\nnpm WARN [email protected] 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: [email protected] (node_modules/fsevents):\nnpm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: 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! [email protected] install:
node install.js
\nnpm ERR! spawn ENOENT\nnpm ERR! \nnpm ERR! Failed at the [email protected] 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 [email protected] requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.", "npm WARN [email protected] 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: [email protected] (node_modules/fsevents):", "npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: 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! [email protected] install:node install.js
", "npm ERR! spawn ENOENT", "npm ERR! ", "npm ERR! Failed at the [email protected] 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+ [email protected]\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", "+ [email protected]", "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"]}
EDIT (regarding larsks answer):
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 [email protected] requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.\nnpm WARN [email protected] 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: [email protected] (node_modules/fsevents):\nnpm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: 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! [email protected] install:
node install.js
\nnpm ERR! spawn ENOENT\nnpm ERR! \nnpm ERR! Failed at the [email protected] 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 [email protected] requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.", "npm WARN [email protected] 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: [email protected] (node_modules/fsevents):", "npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: 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! [email protected] install:node install.js
", "npm ERR! spawn ENOENT", "npm ERR! ", "npm ERR! Failed at the [email protected] 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:
After deleting the temp
and making these commands on localhost:
sudo chmod 777 -R jsReport/
npm install puppeteer jsreport-chrome-pdf
And afterwards running your playbook with sudo it worked without error.
Edit 3:
Adding:
- name: install puppeteer
shell: |
. ~/.nvm/nvm.sh
npm install puppeteer -g
args:
creates: "~/.nvm/versions/node/v{{ node_version }}/lib/node_modules/puppeteer "
gives following error:
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! [email protected] install:
node install.js
\nnpm ERR! spawn ENOENT\nnpm ERR! \nnpm ERR! Failed at the [email protected] 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! [email protected] install:node install.js
", "npm ERR! spawn ENOENT", "npm ERR! ", "npm ERR! Failed at the [email protected] 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> [email protected] install /root/.nvm/versions/node/v8.11.3/lib/node_modules/puppeteer\n> node install.js", "stdout_lines": ["", "> [email protected] install /root/.nvm/versions/node/v8.11.3/lib/node_modules/puppeteer", "> node install.js"]}
EDIT4:
I tried something like this:
---
- 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
afterwards when i am on user jsreport
I run jsreport configure
command
Then i edited this config to set:
"chrome": { "launchOptions": { "args": ["--no-sandbox"] } }
Then i run jsreport start
and get error saying:
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)
The fundamental problem here is that the jsreport configure
command is interactive. If you were to run it manually, you would see:
$ jsreport configure
? Do you want to enable web server? (Y/n)
But if you run that command without an attached terminal (which is how it is run by Ansible), it will fail with a non-zero exit code:
[root@365f191cdad1 ~]# jsreport configure < /dev/null
? Do you want to enable web server? (Y/n)
[root@365f191cdad1 ~]# echo $?
130
Since this is the last command in your shell script, it becomes the exit code of your shell script. Since your shell script exits with a non-zero error, Ansible considers the task failed, and aborts the playbook.
If you were to remove the call to jsreport configure
, you playbook would almost work, except there appears to be a typo in your script. You have:
mkdir jsreportapp
jsreportapp
I think you're missing a cd
there:
mkdir jsreportapp
cd jsreportapp
In other words, this runs without errors:
- 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
But there are still a number of things here worth fixing. First, you're getting an error from mkdir jsreportapp
, which fails if the directory already exists. You could call mkdir -p
instead, but it's probably better to move this into a separate task, and then split up your final task as suggested by 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
Rather than running jsreport configure
, which is an interactive command, consider just copying in the appropriate jsreport.config.json
using an Ansible copy
task, or templating it using the template
module if you want to be able to set things dynamically as part of the playbook run.
My final playbook -- including some minor stylistic changes (always use yaml syntax for module options, rather than key=value) and some idempotency changes (avoid re-running installation tasks, etc) -- looks like this:
---
- 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
You can find the above playbook in this repository.
Update
I've edited the playbook so that it runs successfully as a non-root user. This involved (a) adding become: true
to the wget
install task and (b) installing nvm-install.sh
into the current user home directory rather than /opt
.
You can see this running successfully as a non-root user here:
And running successfully a second time:
As you can see, the errors you're reporting don't crop up, and likely have something to do with your environment. You may want to try starting on a fresh system.
Before running jsreport start
, remember that you need to source in the ~/.nvm/nvm.sh
script. If you do that it seems to work successfully: