├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── Vagrantfile ├── ansible.cfg ├── defaults └── main.yml ├── meta └── main.yml ├── tasks ├── binary.yml ├── main.yml ├── package.yml ├── source.yml └── update_path.yml ├── test.yml ├── tests ├── idempotence_check.sh └── requirements.yml ├── vagrant-inventory └── vars └── main.yml /.gitignore: -------------------------------------------------------------------------------- 1 | test.retry 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | virtualenv: 5 | system_site_packages: true 6 | env: 7 | - ROLE_OPTIONS="nodejs_install_method=source" 8 | - ROLE_OPTIONS="nodejs_install_method=package" 9 | - ROLE_OPTIONS="nodejs_install_method=binary" 10 | install: 11 | - sudo apt-get update -qq 12 | - sudo apt-get install python-apt python-pycurl 13 | - pip install -U ansible urllib3 pyOpenSSL pyasn1 ndg-httpsclient 14 | - ansible-galaxy install -r tests/requirements.yml 15 | script: 16 | - echo localhost > inventory 17 | # Syntax check 18 | - ansible-playbook -i inventory test.yml --syntax-check 19 | # Play test 20 | - travis_wait 30 ansible-playbook -i inventory test.yml --connection=local --become -e "$ROLE_OPTIONS" -e "ansible_python_interpreter=`which python`" 21 | # Idempotence test 22 | - ansible-playbook -i inventory test.yml --connection=local --become -e "$ROLE_OPTIONS" -e "ansible_python_interpreter=`which python`" | tee idempotence_out 23 | - ./tests/idempotence_check.sh idempotence_out 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2014 Pieterjan Vandaele 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ANXS - nodejs [![Build Status](https://travis-ci.org/ANXS/nodejs.png?branch=master)](https://travis-ci.org/ANXS/nodejs) 2 | 3 | Ansible role for installing nodejs, from package or by building it from source. 4 | 5 | 6 | #### Requirements & Dependencies 7 | - Tested on Ansible 2.3.2 or higher. 8 | - Depends on ANXS.build-essential when using install_method of "source" 9 | 10 | #### Variables 11 | 12 | ```yaml 13 | nodejs_version: "0.10.26" # nodejs version to install. 14 | nodejs_install_method: "source" # "package" or "source" or "binary" 15 | ``` 16 | 17 | For "unstable" node versions (0.11), you may wish to use "binary" if you don't want to compile from source: 18 | 19 | ```yaml 20 | nodejs_version: "0.11.13" # nodejs version to install. 21 | nodejs_install_method: "binary" # "source" or "binary" (package is not available for 0.11) 22 | ``` 23 | 24 | #### Testing 25 | This project comes with a Vagrantfile, this is a fast and easy way to test changes to the role, fire it up with `vagrant up` 26 | 27 | See [vagrant docs](https://docs.vagrantup.com/v2/) for getting setup with vagrant 28 | 29 | Once your VM is up, you can reprovision it using either `vagrant provision`, or `ansible-playbook tests/playbook.yml -i vagrant-inventory` 30 | 31 | If you want to toy with the test play, see [tests/playbook.yml](./tests/playbook.yml), and change the variables in [tests/vars.yml](./tests/vars.yml) 32 | 33 | If you are contributing, please first test your changes within the vagrant environment, (using the targeted distribution), and if possible, ensure your change is covered in the tests found in [.travis.yml](./.travis.yml) 34 | 35 | #### Thanks to 36 | - [Nicolas Bazire](https://github.com/nicbaz) 37 | - [Luís Couto](https://github.com/Couto) 38 | - [Stephan Hochhaus](https://github.com/yauh) 39 | - [Nathan Palmer](https://github.com/nathanpalmer) 40 | - [Manuel Tiago Pereira](https://github.com/mtpereira) 41 | - [Umair Siddique](https://github.com/umairsiddique) 42 | 43 | 44 | #### Testing 45 | This project comes with a VagrantFile, this is a fast and easy way to test changes to the role, fire it up with `vagrant up` 46 | 47 | See [vagrant docs](https://docs.vagrantup.com/v2/) for getting setup with vagrant 48 | 49 | 50 | #### License 51 | 52 | Licensed under the MIT License. See the LICENSE file for details. 53 | 54 | 55 | #### Feedback, bug-reports, requests, ... 56 | 57 | Are [welcome](https://github.com/ANXS/nodejs/issues)! 58 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | nodejs_install_method = ENV.key?('NODEJS_INSTALL_METHOD') ? ENV['NODEJS_INSTALL_METHOD'] : 'source' 5 | 6 | Vagrant.configure('2') do |config| 7 | # Ensure we use our vagrant private key 8 | config.ssh.insert_key = false 9 | config.ssh.private_key_path = '~/.vagrant.d/insecure_private_key' 10 | 11 | config.vm.define 'anxs' do |machine| 12 | machine.vm.box = "hashicorp/trusty64" 13 | 14 | machine.vm.network :private_network, ip: '192.168.88.17' 15 | machine.vm.hostname = 'anxs.local' 16 | machine.vm.provision 'ansible' do |ansible| 17 | ansible.playbook = 'test.yml' 18 | ansible.become = true 19 | ansible.inventory_path = 'vagrant-inventory' 20 | ansible.host_key_checking = false 21 | ansible.extra_vars = { 22 | nodejs_install_method: nodejs_install_method 23 | } 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | roles_path = ../ 3 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nodejs_arch: "{{ansible_architecture}}" 3 | nodejs_install_method: "source" 4 | nodejs_version: "9.5.0" 5 | nodejs_directory: "/usr/local/nodejs" 6 | nodejs_source_url: "https://nodejs.org/dist/v{{nodejs_version}}/node-v{{nodejs_version}}.tar.gz" 7 | nodejs_source_prefix: "{{nodejs_directory}}/node-v{{nodejs_version}}" 8 | # possible achitectures: darwin-x64, darwin-x86, linux-x64, linux-x86, sunos-x64, sunos-x86 9 | nodejs_binary_url: "https://nodejs.org/dist/v{{nodejs_version}}/node-v{{nodejs_version}}-{{ansible_system | lower}}-x{{ansible_userspace_bits |replace('32', '86')}}.tar.gz" 10 | nodejs_system_paths: true 11 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: pjan vandaele 4 | company: ANXS 5 | description: "Install nodejs, from package, build from source or download binary tarball" 6 | min_ansible_version: 2.3.2 7 | license: MIT 8 | platforms: 9 | - name: Ubuntu 10 | versions: 11 | - all 12 | categories: 13 | - system 14 | - development 15 | 16 | dependencies: 17 | - role: ANXS.build-essential 18 | when: > 19 | nodejs_install_method is defined and 20 | nodejs_install_method == "source" and 21 | ansible_os_family == 'Debian' 22 | -------------------------------------------------------------------------------- /tasks/binary.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Download the node.js binary for your distribution" 3 | get_url: 4 | url: "{{nodejs_binary_url}}" 5 | dest: "/tmp/node-v{{nodejs_version}}.tar.gz" 6 | 7 | - name: "Create node.js directory" 8 | file: 9 | path: "/usr/local/nodejs" 10 | state: "directory" 11 | 12 | - name: "Unpack the node.js package" 13 | unarchive: 14 | src : "/tmp/node-v{{nodejs_version}}.tar.gz" 15 | dest : "/usr/local/nodejs" 16 | copy : no 17 | 18 | - name: "Update the symbolic link to the node.js install" 19 | file: 20 | path: "{{nodejs_directory}}/default" 21 | src: "{{nodejs_binary_prefix}}" 22 | state: "link" 23 | force: yes 24 | 25 | - include: update_path.yml 26 | 27 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include: package.yml 3 | when: nodejs_install_method == "package" 4 | - name: Check if the node version is already installed 5 | command: "{{nodejs_binary_prefix}}/bin/node --version" 6 | ignore_errors: yes 7 | failed_when: no 8 | register: nodejs_binary_version 9 | changed_when: nodejs_binary_version.rc != 0 or nodejs_binary_version.stdout.find(nodejs_version) < 0 10 | when: nodejs_install_method == "binary" 11 | - name: Check if the node version is already installed 12 | command: "{{nodejs_directory}}/node-v{{nodejs_version}}/bin/node --version" 13 | ignore_errors: yes 14 | failed_when: no 15 | register: nodejs_source_version 16 | changed_when: nodejs_source_version.rc != 0 or nodejs_source_version.stdout.find(nodejs_version) < 0 17 | when: nodejs_install_method == "source" 18 | - include: source.yml 19 | when: nodejs_install_method == "source" and nodejs_source_version.changed 20 | - include: binary.yml 21 | when: nodejs_install_method == "binary" and nodejs_binary_version.changed 22 | -------------------------------------------------------------------------------- /tasks/package.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Make sure the ansible required dependencies are installed" 3 | apt: 4 | pkg: python-pycurl 5 | state: present 6 | - name: "add signing key" 7 | apt_key: 8 | url: "{{nodejs_apt_key_url}}" 9 | id: "{{nodejs_apt_key}}" 10 | state: present 11 | - name: "add sources.list entry" 12 | lineinfile: 13 | dest: /etc/apt/sources.list.d/nodesource.list 14 | create: yes 15 | line: "{{ item }}" 16 | state: present 17 | with_items: 18 | - "deb {{nodejs_apt_url}} {{ansible_lsb.codename}} main" 19 | - "deb-src {{nodejs_apt_url}} {{ansible_lsb.codename}} main" 20 | - name: "Install the node.js package" 21 | apt: 22 | package: "nodejs" 23 | update_cache: yes 24 | state: present 25 | -------------------------------------------------------------------------------- /tasks/source.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Make sure that the directory to hold the node.js binaries exists" 3 | file: 4 | path: "{{nodejs_directory}}" 5 | state: directory 6 | recurse: yes 7 | mode: 0755 8 | - name: "Download the node.js source" 9 | get_url: 10 | url: "{{nodejs_source_url}}" 11 | dest: "/tmp/node-v{{nodejs_version}}.tar.gz" 12 | - name: "Unpack the node.js source" 13 | unarchive: 14 | copy: no 15 | src: "/tmp/node-v{{nodejs_version}}.tar.gz" 16 | dest: "/tmp" 17 | - name: "Get the number of processors (Linux)" 18 | command: nproc 19 | register: cpu_count_linux 20 | when: ansible_system == 'Linux' 21 | changed_when: False 22 | - name: "Get the number of processors (Darwin)" 23 | command: sysctl -n hw.ncpu 24 | register: cpu_count_darwin 25 | when: ansible_os_family == 'Darwin' 26 | changed_when: False 27 | - name: "Set number of processors (Linux)" 28 | set_fact: 29 | cpu_count: "{{cpu_count_linux}}" 30 | when: ansible_system == 'Linux' 31 | changed_when: False 32 | - name: "Set number of processors (Darwin)" 33 | set_fact: 34 | cpu_count: "{{cpu_count_darwin}}" 35 | when: ansible_system == 'Darwin' 36 | - name: "Check for artifact directory" 37 | stat: 38 | path: "/tmp/node-v{{nodejs_version}}/out/Release" 39 | register: node_artifact_check 40 | - name: "Build node.js from source" 41 | shell: > 42 | cd /tmp/node-v{{nodejs_version}} && 43 | ./configure --prefix={{nodejs_source_prefix}} && 44 | make -j {{cpu_count.stdout}} && 45 | make install 46 | when: not node_artifact_check.stat.exists 47 | - name: "Update the symbolic link to the node.js install" 48 | file: 49 | path: "{{nodejs_directory}}/default" 50 | src: "{{nodejs_source_prefix}}" 51 | state: link 52 | force: yes 53 | - include: update_path.yml 54 | -------------------------------------------------------------------------------- /tasks/update_path.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: "Add the node installation path to the system path" 3 | lineinfile: 4 | dest: /etc/profile 5 | regexp: '^NODE_HOME={{ nodejs_directory }}/default' 6 | line: 'NODE_HOME={{ nodejs_directory }}/default' 7 | state: present 8 | when: nodejs_system_paths 9 | - name: "Add the node binary path to the system path" 10 | lineinfile: 11 | dest: /etc/profile 12 | regexp: '^PATH=.*NODE_HOME.*' 13 | line: 'PATH=$PATH:$NODE_HOME/bin' 14 | state: present 15 | when: nodejs_system_paths 16 | - name: "Inform the system where the binaries are located and set as the default" 17 | alternatives: 18 | name: "{{ item }}" 19 | path: "{{ nodejs_directory }}/default/bin/{{ item }}" 20 | link: "/usr/bin/{{ item }}" 21 | with_items: 22 | - node 23 | - npm 24 | when: nodejs_system_paths 25 | -------------------------------------------------------------------------------- /test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - hosts: all 4 | remote_user: root 5 | become: yes 6 | vars_files: 7 | - "defaults/main.yml" 8 | - "vars/main.yml" 9 | roles: 10 | - 'ANXS.build-essential' 11 | tasks: 12 | - include: "tasks/main.yml" 13 | -------------------------------------------------------------------------------- /tests/idempotence_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Process the output of the given file (should contain a plays stdout/err) 4 | # If we pass, return with 0 else return with 1, and print useful output 5 | 6 | _file="$1" 7 | 8 | # Assert filename has been passed 9 | [ $# -eq 0 ] && { echo "Usage: $0 filename"; exit 1; } 10 | 11 | # Assert file exists 12 | [ ! -f "$_file" ] && { echo "$0: $_file file not found."; exit 2; } 13 | 14 | # Make sure nothing has changed or failed 15 | grep -q 'changed=0.*failed=0' $_file 16 | 17 | # Success condition 18 | if [ $? -eq 0 ]; then 19 | echo 'Idempotence test: pass' 20 | exit 21 | 22 | # Failure condition, extract useful information and exit 23 | else 24 | echo 'Idempotence test: fail' 25 | echo '' 26 | grep --color=auto -B1 -A1 "\(changed\|failed\):" $_file 27 | exit 1 28 | fi 29 | -------------------------------------------------------------------------------- /tests/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - role: ANXS.build-essential -------------------------------------------------------------------------------- /vagrant-inventory: -------------------------------------------------------------------------------- 1 | [anxs] 2 | anxs.local ansible_ssh_host=192.168.88.17 ansible_ssh_port=22 ansible_ssh_user=vagrant ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 3 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | nodejs_apt_key_url: "https://keyserver.ubuntu.com/pks/lookup?op=get&fingerprint=on&search=0x1655A0AB68576280" 3 | nodejs_apt_key: "68576280" 4 | nodejs_binary_prefix: "{{nodejs_directory}}/node-v{{nodejs_version}}-{{ansible_system|lower}}-x{{ansible_userspace_bits|replace('32', '86')}}" 5 | nodejs_major_version: "{{nodejs_version.split('.')[0]}}" 6 | nodejs_apt_url: "https://deb.nodesource.com/node_{{nodejs_major_version}}.x" --------------------------------------------------------------------------------