Git Product home page Git Product logo

rbenv's Introduction

rbenv

Role for installing rbenv.

Role ready status

Build Status

Requirements

none

Role Variables

Default variables are:

rbenv:
  env: system
  version: v1.0.0
  default_ruby: 2.4.2
  rubies:
    - version: 2.4.2

rbenv_clean_up: false

rbenv_repo: "https://github.com/rbenv/rbenv.git"

rbenv_plugins:
  - { name: "rbenv-vars",
      repo: "https://github.com/rbenv/rbenv-vars.git",
      version: "master" }

  - { name: "ruby-build",
      repo: "https://github.com/rbenv/ruby-build.git",
      version: "master" }

  - { name: "rbenv-default-gems",
      repo: "https://github.com/rbenv/rbenv-default-gems.git",
      version: "master" }

  - { name: "rbenv-installer",
      repo: "https://github.com/rbenv/rbenv-installer.git",
      version: "master" }

  - { name: "rbenv-update",
      repo: "https://github.com/rkh/rbenv-update.git",
      version: "master" }

  - { name: "rbenv-whatis",
      repo: "https://github.com/rkh/rbenv-whatis.git",
      version: "master" }

  - { name: "rbenv-use",
      repo: "https://github.com/rkh/rbenv-use.git",
      version: "master" }

rbenv_root: "{% if rbenv.env == 'system' %}/usr/local/rbenv{% else %}$HOME/.rbenv{% endif %}"

rbenv_users: []

rbenv_extra_depends: []

Variables to control a system installation (these are not set by default):

rbenv_owner: 'deploy'
rbenv_group: 'deploy'

Description:

  • rbenv.env - Type of rbenv installation. Allows 'system' or 'user' values
  • rbenv.version - Version of rbenv to install (tag from rbenv releases page)
  • rbenv.default_ruby - Which ruby version to be set as global rbenv ruby.
  • rbenv.rubies - Versions of ruby to install. This is an array of hashes. E.g. [ { version: 2.4.2, env: { RUBY_CONFIGURE_OPTS="--enable-shared" } } ]
  • rbenv_clean_up - Delete all ruby versions not listed above. Default value is false
  • rbenv_repo - Repository with source code of rbenv to install
  • rbenv_plugins - Array of Hashes with information about plugins to install
  • rbenv_root - Install path
  • rbenv_users - Array of usernames for multiuser install. User must be present in the system
  • rbenv_extra_depends - Array of extra system packages to install before compiling rubies
  • default_gems_file - This is Rbenv's plugin rbenv-default-gems. Sets the path to a default-gems file of your choice (don't set it if you want to use the default file files/default-gems)
  • rbenv_owner - The user owning rbenv_root when rbenv.env is system
  • rbenv_group - The group owning rbenv_root when rbenv.env is system
  • rbenv_tmpdir - A temporary directory path used for artifacts when installing rubies. Defaults to system's $TMPDIR
  • rbenv_set_vars - Set default vars GEM_PATH=$GEM_PATH:$HOME/.gems for 'user' env. Default value is true

Example:

- hosts: web
  gather_facts: true # https://github.com/zzet/ansible-rbenv-role/issues/37
  vars:
    rbenv:
      env: user
      version: v0.4.0
      default_ruby: 2.0.0-p353
      rubies:
      - version: 2.0.0-p353
      - version: 2.2.4
        env:
          RUBY_CONFIGURE_OPTS: "--enable-shared"
      - version: 2.3.4
        env:
          RUBY_CONFIGURE_OPTS: "--enable-shared --with-jemalloc"
    rbenv_extra_depends:
      - libjemalloc1
      - libjemalloc-dev
  roles:
    - role: zzet.rbenv
      rbenv_users:
        - user

Dependencies

none

License

MIT

Author Information

Andrew Kumanyaev

rbenv's People

Contributors

antstorm avatar bew avatar bonds avatar dunn avatar glaszig avatar hqm42 avatar j-swift avatar k-nii0211 avatar leonelgalan avatar leopku avatar massat avatar matthiaswinkelmann avatar mkllnk avatar msaladna avatar nick-f avatar onigra avatar ringe avatar rtlechow avatar s01ipsist avatar sasakix avatar shalomb avatar teadur avatar tleguern avatar tricknotes avatar trinitronx avatar undergreen avatar westonplatter avatar wfaler avatar wjessop avatar zzet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rbenv's Issues

Error when running

I am getting the following error when running zzet.rbenv:

TASK: [zzet.rbenv | homebrew_tap tap=homebrew/dupes state=present] ************
fatal: [default] => error while evaluating conditional: rbenv.ruby_version <= 1.9.3-p0

It seems that I cannot override the ruby_version variable as well. Maybe I'm doing something wrong.

Parent role default is ignored when this role is put as a dependency.

Due to seemingly unintended behavior in ansible, when "include env vars" in tasks/main.yml is run, the default values set in a role that depends on this one are not yet loaded. Thus rbenv.env will be set to this role's default of 'system', and the vars/system.yml loads and sets rbenv_root.

In the following tasks the defaults from the parent role ARE loaded, but they will not overwrite values set in vars/, i.e. rbenv_root, and thus the tasks fail if the parent role was set to env 'user'.

to reproduce:

roles/reproduce/defaults/main.yml


---
rbenv:
  env: user
  version: v1.0.0
  ruby_version: 2.3.0

roles/reproduce/meta/main.yml


---
dependencies:
  - role: zzet.rbenv

Then in any playbook replace role: zzet.rbenv with role: reproduce (without specifying the rbenv.env variable outside of roles/reproduce/defaults/)

Placing any task such as - include: apt_build_depends.yml above - name: include env vars in roles/zzet.rbenv will for some reason change this behavior, and defaults will load as expected. Hence my comment on unintended behavior from ansibles side

possible solutions include moving the include env vars statement downwards, or removing it entirely. To my eyes the feature seems duplicated on line 18 of zzet.rbenv/defaults/main.yml where it can be overridden properly.

alias support

I'd love your opinion on this...

I like to have a symlink in ~/.rbenv/versions/2.1 to ~/.rbenv/versions/2.1.2
this way I can use the major.minor version on my projects .ruby-version and leave the patch behind.

So, what I mention on #35 was something like this

ruby_aliases:
   2.0.0: 2.0.0-p648
   2.1: 2.1.5
   2.2: 2.2.1

Build fails on Ubuntu 18 Bionic Beaver

When I run the playbook on Bionic Beaver installing Ruby 2.1.5 I get a fatal error at the build step. The error output shows this:

Downloading ruby-2.1.5.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.5.tar.bz2
Installing ruby-2.1.5...
WARNING: ruby-2.1.5 is past its end of life and is now unsupported.
It no longer receives bug fixes or critical security updates.
BUILD FAILED (Ubuntu 18.04 using ruby-build 20190320)
Inspect or clean up the working tree at /tmp/ruby-build.20190326160938.15756
Results logged to /tmp/ruby-build.20190326160938.15756.log
Last 10 log lines:
make[1]: *** [ext/openssl/all] Error 2
make[1]: *** Waiting for unfinished jobs....
compiling callback-7.c
compiling callback-8.c
installing default callback libraries
linking shared-object dl/callback.so
make[2]: Leaving directory '/tmp/ruby-build.20190326160938.15756/ruby-2.1.5/ext/dl/callback'
make[1]: Leaving directory '/tmp/ruby-build.20190326160938.15756/ruby-2.1.5'
uncommon.mk:180: recipe for target 'build-ext' failed

[DEPRECATION WARNING]: always_run is deprecated

Just came across this warning:

[DEPRECATION WARNING]: always_run is deprecated. Use check_mode = no instead..
This feature will be removed in version 2.4. Deprecation 
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

zzet.rbenv version: 2.2.6

Bundler doesn't installed

There is bundler in default_gems, but I have got error "The program 'bundle' is currently not installed".

ruby cleanup fails

It seems ruby_installed doesnot get populated:

my playbook:

  • hosts: rbenv
    gather_facts: true # #37
    vars:
    rbenv_clean_up: True
    rbenv:
    env: user
    version: v1.1.0
    default_ruby: 2.3.7
    rubies:
    - version: 2.3.7
    - version: 2.4.4
    env:
    RUBY_CONFIGURE_OPTS: "--enable-shared"

    roles:

    • role: rbenv
      rbenv_users:
      • user1
      • user2
      • user3
      • user4

TASK [rbenv : check which old rubies to remove for select users] *********************************************************************************************************************************
fatal: [staging.infra.tld.ee]: FAILED! => {"msg": "'ruby_installed' is undefined"}
...ignoring

TASK [rbenv : remove old rubies] *****************************************************************************************************************************************************************
fatal: [staging.infra.tld.ee]: FAILED! => {"msg": "'dict object' has no attribute 'results'"}
...ignoring

When `env: user` error on all "... for selected users" tasks.

In role's dependencies:

  - role: zzet.rbenv
    rbenv:
      env: user
      version: v0.4.0
      ruby_version: 2.1.5
    rbenv_users:
      - deploy

Output:

TASK: [zzet.rbenv | checkout rbenv_repo for selected users] *******************
<127.0.0.1> ESTABLISH CONNECTION FOR USER: vagrant
<127.0.0.1> REMOTE_MODULE git repo=git://github.com/sstephenson/rbenv.git dest=~/.rbenv version=v0.4.0 accept_hostkey=true
<127.0.0.1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/leonelgalan/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o', 'Port=2222', '-o', 'IdentityFile="/Users/leonelgalan/Documents/workspace/packing_tape-ansible/.vagrant/machines/default/virtualbox/private_key"', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '127.0.0.1', "/bin/sh -c 'mkdir -p /tmp/ansible-tmp-1421272658.78-243411545053983 && chmod a+rx /tmp/ansible-tmp-1421272658.78-243411545053983 && echo /tmp/ansible-tmp-1421272658.78-243411545053983'"]
<127.0.0.1> PUT /var/folders/78/6351j8t926367p66t59zs71m0000gn/T/tmpNflMvD TO /tmp/ansible-tmp-1421272658.78-243411545053983/git
<127.0.0.1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/leonelgalan/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o', 'Port=2222', '-o', 'IdentityFile="/Users/leonelgalan/Documents/workspace/packing_tape-ansible/.vagrant/machines/default/virtualbox/private_key"', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '127.0.0.1', u"/bin/sh -c 'chmod a+r /tmp/ansible-tmp-1421272658.78-243411545053983/git'"]
<127.0.0.1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/leonelgalan/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o', 'Port=2222', '-o', 'IdentityFile="/Users/leonelgalan/Documents/workspace/packing_tape-ansible/.vagrant/machines/default/virtualbox/private_key"', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '127.0.0.1', u'/bin/sh -c \'sudo -k && sudo -H -S -p "[sudo via ansible, key=ietdtlzfvkwhgzhaaogtlnbtkloqceqo] password: " -u {{ item.name }} /bin/sh -c \'"\'"\'echo SUDO-SUCCESS-ietdtlzfvkwhgzhaaogtlnbtkloqceqo; LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 /usr/bin/python /tmp/ansible-tmp-1421272658.78-243411545053983/git\'"\'"\'\'']
<127.0.0.1> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'ControlMaster=auto', '-o', 'ControlPersist=60s', '-o', 'ControlPath=/Users/leonelgalan/.ansible/cp/ansible-ssh-%h-%p-%r', '-o', 'StrictHostKeyChecking=no', '-o', 'Port=2222', '-o', 'IdentityFile="/Users/leonelgalan/Documents/workspace/packing_tape-ansible/.vagrant/machines/default/virtualbox/private_key"', '-o', 'KbdInteractiveAuthentication=no', '-o', 'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o', 'PasswordAuthentication=no', '-o', 'User=vagrant', '-o', 'ConnectTimeout=10', '127.0.0.1', "/bin/sh -c 'rm -rf /tmp/ansible-tmp-1421272658.78-243411545053983/ >/dev/null 2>&1'"]
failed: [default] => (item=deploy) => {"failed": true, "item": "deploy", "parsed": false}
invalid output was: sudo: unknown user: {{
sudo: unable to initialize policy plugin
OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
debug1: Reading configuration data /etc/ssh_config
debug1: /etc/ssh_config line 20: Applying options for *
debug1: /etc/ssh_config line 102: Applying options for *
debug1: auto-mux: Trying existing master
debug2: fd 3 setting O_NONBLOCK
debug2: mux_client_hello_exchange: master version 4
debug3: mux_client_forwards: request forwardings: 0 local, 0 remote
debug3: mux_client_request_session: entering
debug3: mux_client_request_alive: entering
debug3: mux_client_request_alive: done pid = 38295
debug3: mux_client_request_session: session request sent
debug1: mux_client_request_session: master session id: 2
debug3: mux_client_read_packet: read header failed: Broken pipe
debug2: Received exit status from master 1
Shared connection to 127.0.0.1 closed.

...ignoring

SSHing into the machine and doing sudo su deploy works as expected.

Purpose of handler

What's the purpose of rehash rbenv? Rehash is called manually from tasks/main.yml:151 or tasks/main.yml:182

It it notifies the handler instead, we could install gems (env: system so now default gems plugin available) and rbenv rehash would happen at the very end.

recurse option requires state to be 'directory'

Issue:
By running a provision command, I get the following exception:

TASK [ansible-deployer : add rigths to rbenv] **********************************
fatal: [mainserver]: FAILED! => {"changed": false, "failed": true, "msg": "recurse option requires state to be 'directory'", "path": "/usr/local/rbenv", "state": "absent"}

Environment:
Server: Ubuntu 16.10

โฏ ansible --version
ansible 2.0.1.0
โฏ ansible-galaxy info zzet.rbenv
Role: zzet.rbenv
        description: rbenv
        active: True
        commit: 3cb88f156abcb082471a6a60c1bb713b892e09fb
        commit_message: Darwin doesn't have a root group either. (#66)
        commit_url: https://github.com/zzet/ansible-rbenv-role/commit/3cb88f156abcb082471a6a60c1bb713b892e09fb

Solution:
Create dir /usr/local/rbenv on the server manually

always reports "changed"

Running an Ansible playbook multiple times should ideally result in something like:

web1.example.com : ok=55 changed=0 unreachable=0 failed=0

This role is showing

web1.example.com : ok=53 changed=2 unreachable=0 failed=0

More details:

TASK [rbenv : install plugins for selected users] ********************************************************************************************
changed: [web1.example.com] => (item=[u'test', {u'repo': u'https://github.com/rbenv/ruby-build.git', u'version': u'master', u'name': u'ruby-build'}])

TASK [rbenv : install ruby {{ item[1].version }} for select users] ***************************************************************************
changed: [web1.example.com] => (item=[u'test', {u'version': u'2.4.1'}])

Ruby version 2.2.0 failing on checkout

When I run the rbenv role on my box, which has rbenv already installed by this galaxy role, I get this error.

failed: [104.236.6.108] => (item={'repo': 'git://github.com/sstephenson/ruby-build.git', 'version': '2.2.0', 'name': 'ruby-build'}) => {"failed": true, "item": {"name": "ruby-build", "repo": "git://github.com/sstephenson/ruby-build.git", "version": "2.2.0"}}
msg: Failed to checkout 2.2.0

I think this is because the latest version of ruby-build is not being cloned down.

ruby -v: always display system ruby

Hey Guys,

I use:


---
  - name: Configure Server
    hosts: <MY SERVER IP>
    user: ubuntu
    sudo: True

   vars:
      rbenv:
        env: user
        version: v0.4.0
        ruby_version: 2.1.5
   roles:
      - role: zzet.rbenv
        rbenv_users:
          - qae

All works fine, but when I ssh to server after provisioning:

$ rbenv versions
  system
* 2.1.5 (set by /home/qae/.rbenv/version)

$ rbenv version
2.1.5 (set by /home/qae/.rbenv/version)

$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]

So, looks like it still uses system ruby
Not sure if' it's bug, just decided to ask.
Maybe someone had same issue?

Some info:

  1. I use latest version,
    Before provision I did:
$ ansible-galaxy remove zzet.rbenv
$ ansible-galaxy install zzet.rbenv
  1. in my /home/qae/.bashrc
export PATH=$GEM_HOME/bin:$PATH
export GEM_HOME=/home/qae/.gem

if [ -d "$HOME/.rbenv" ]; then
  export PATH=$HOME/.rbenv/bin:$PATH;
  export RBENV_ROOT=$HOME/.rbenv;
  eval "$(rbenv init -)";
fi

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

if [ -f /etc/bash_completion ] && ! shopt -oq posix; then
    . /etc/bash_completion
fi
  1. which ruby
$ which ruby
/usr/bin/ruby

Thanks ๐Ÿป

grep not finding ruby version

Hey,

So tasks are failing on a grep of the rbenv versions, and can't seem to find 2.2.2, my desired version. Of course '2.2.2' shows up in the version list so this doesn't make much sense. I got these first on a system install, then on a user install:

TASK: [zzet.rbenv | check ruby {{ rbenv.ruby_version }} installed for system] *** 

failed: [ansible] => {"changed": false, "cmd": "$SHELL -lc \"rbenv versions | grep 2.2.2\"", "delta": "0:00:00.071108", "end": "2015-12-29 19:19:48.077976", "rc": 1, "start": "2015-12-29 19:19:48.006868", "stdout_lines": [], "warnings": []}
...ignoring

also thrown on:

TASK: [zzet.rbenv | install ruby {{ rbenv.ruby_version }} for select users] *** 

failed: [ansible] => (item=[{u'cmd': u'$SHELL -lc "rbenv versions | grep 2.2.2"', u'end': u'2015-12-29 19:35:57.621104', u'stderr': u'', u'stdout': u'', u'changed': False, u'rc': 1, 'item': 'deploy', u'warnings': [], u'delta': u'0:00:00.073502', 'invocation': {'module_name': u'shell', 'module_complex_args': {}, 'module_args': u'$SHELL -lc "rbenv versions | grep 2.2.2"'}, 'stdout_lines': [], u'start': u'2015-12-29 19:35:57.547602'}, 'deploy']) => {"changed": true, "cmd": "$SHELL -lc \"rbenv install 2.2.2\"", "delta": "0:00:00.083065", "end": "2015-12-29 19:35:58.340299", "item": [{"changed": false, "cmd": "$SHELL -lc \"rbenv versions | grep 2.2.2\"", "delta": "0:00:00.073502", "end": "2015-12-29 19:35:57.621104", "invocation": {"module_args": "$SHELL -lc \"rbenv versions | grep 2.2.2\"", "module_complex_args": {}, "module_name": "shell"}, "item": "deploy", "rc": 1, "start": "2015-12-29 19:35:57.547602", "stderr": "", "stdout": "", "stdout_lines": [], "warnings": []}, "deploy"], "rc": 2, "start": "2015-12-29 19:35:58.257234", "warnings": []}
stderr: ruby-build: definition not found: 2.2.2

The following versions contain `2.2.2' in the name:
  rbx-2.2.2

See all available versions with `rbenv install --list'.

If the version you need is missing, try upgrading ruby-build:

  cd /home/deploy/.rbenv/plugins/ruby-build && git pull
...ignoring

and

TASK: [zzet.rbenv | check if user ruby version is {{ rbenv.ruby_version }}] *** 

failed: [ansible] => (item=deploy) => {"changed": false, "cmd": "$SHELL -lc \"rbenv version | cut -d ' ' -f 1 | grep -Fx '2.2.2'\"", "delta": "0:00:00.055444", "end": "2015-12-29 19:35:59.077912", "item": "deploy", "rc": 1, "start": "2015-12-29 19:35:59.022468", "stdout_lines": [], "warnings": []}

Thanks for any help!

Request: Do not use nested variables

Now everyone that wants to customise a single option, they have to define the full hash.

With the defaults like:

  rbenv:
    env: system
    version: v1.0.0
    default_ruby: 2.3.3

Just setting the default_ruby requires me to define the full hash, e.g.:

- role: rbenv
  rbenv:
    env: system
    version: v1.0.0
    default_ruby: 2.1.6

And now since 3.0.0 the rubies properties is added, which requires me to add that to my playbook configuration (or add a version constraint).

There a way to get this working by setting hash_behaviour, but this isn't recommended:

We generally recommend not using this setting unless you think you have an absolute need for it, and playbooks in the official examples repos do not use this setting:

So I suggest to change it to plain variables:

  rbenv_env: system
  rbenv_version: v1.0.0
  rbenv_default_ruby: 2.3.3
  rbenv_rubies:
    - version: 2.3.3

rbenv cannot build ruby 2.2.3 with default settings

The branch of ruby-build specified does not include 2.2.3. The following playbook.yml worked for me. It sets ruby-build to use the master branch.

---
- hosts: all
  vars:
    rbenv:
      env: user
      version: v0.4.0
      ruby_version: 2.2.3
    rbenv_plugins:
      - { name: "ruby-build",
          repo: "https://github.com/sstephenson/ruby-build.git",
          version: "master" }

Please provide more examples?

Can you provide some more examples? For example, how do I simply install a specific version of ruby system-wide? I tried this and got an error:

- hosts: whatever
  vars:
    rbenv:
      default_ruby: 2.3.1
      rubies:
      - version: 2.3.1
      
  roles:
    - role: zzet.rbenv

Result:

TASK [zzet.rbenv : include env vars] *******************************************
fatal: [monitor.medstack.net]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'dict object' has no attribute 'env'\n\nThe error appears to have been in '/Users/simon/sandbox/medstack/deployment/ansible/galaxy/zzet.rbenv/tasks/main.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: include env vars\n ^ here\n"}

Examples for other common configurations would also be welcome.

Multiuser install triggers a "sudo: password is required"

My context is to install RBENV for the well-known user Jenkins. This account is not a sudoer. And during the run launch with the sudoer account vagrant, the become triggers an error message "sudo: a password is required".

Maybe I miss the point how to implement the role (see below).

My playbook:

- name: Jenkins Slave Mobile
  hosts: sandbox-jenkins-slave-mobile
  vars:
    rbenv:
      env: user
      version: v1.0.0
      default_ruby: 2.3.3
      rubies:
      - version: 2.3.3
  roles:
    - role: ansible-rbenv-role
      rbenv_users:
      - jenkins
TASK [ansible-rbenv-role : checkout rbenv_repo for selected users] *********************************************************************************************************************
failed: [sandbox-jenkins-slave-mobile] (item=jenkins) => {"failed": true, "item": "jenkins", "module_stderr": "Shared connection to 127.0.0.1 closed.\r\n", "module_stdout": "sudo: a password is required\r\n", "msg": "MODULE FAILURE", "rc": 1}

Ruby is not installed for select users for some skip reason

The last version 3.3.0 introduce the breaking change below. The ruby is not installed for select users for some skip reason.

May I suggest to have a look to the conditional - item[0].item[0] == item[1]

TASK [ansible-rbenv-role : install ruby {{ item[2].version }} for select users] ***
skipping: [sandbox-jenkins-slave-mobile] => (item=[{'_ansible_parsed': True, 'stderr_lines': [], '_ansible_item_result': True, u'end': u'2017-05-30 15:37:23.633252', '_ansible_no_log': False, u'stdout': u'', u'cmd': u'$SHELL -lc "~/.rbenv/bin/rbenv versions --bare"', u'rc': 0, 'item': u'jenkins', u'delta': u'0:00:00.050433', u'stderr': u'', u'changed': False, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'_raw_params': u'$SHELL -lc "~/.rbenv/bin/rbenv versions --bare"', u'removes': None, u'creates': None, u'chdir': None}}, 'stdout_lines': [], 'failed_when_result': False, u'start': u'2017-05-30 15:37:23.582819', 'failed': False}, u'jenkins', {u'version': u'2.3.3'}])  => {"changed": false, "item": [{"_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": false, "cmd": "$SHELL -lc \"~/.rbenv/bin/rbenv versions --bare\"", "delta": "0:00:00.050433", "end": "2017-05-30 15:37:23.633252", "failed": false, "failed_when_result": false, "invocation": {"module_args": {"_raw_params": "$SHELL -lc \"~/.rbenv/bin/rbenv versions --bare\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}}, "item": "jenkins", "rc": 0, "start": "2017-05-30 15:37:23.582819", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}, "jenkins", {"version": "2.3.3"}], "skip_reason": "Conditional result was False", "skipped": true}

TASK [ansible-rbenv-role : check which old rubies to remove for select users] ***
skipping: [sandbox-jenkins-slave-mobile] => {"changed": false, "skip_reason": "Conditional result was False", "skipped": true}

TASK [ansible-rbenv-role : remove old rubies] **********************************
skipping: [sandbox-jenkins-slave-mobile] => {"changed": false, "skip_reason": "Conditional result was False", "skipped": true}

TASK [ansible-rbenv-role : check if user ruby version is 2.3.3] ****************
ok: [sandbox-jenkins-slave-mobile] => (item=jenkins) => {"changed": false, "cmd": "$SHELL -lc \"~/.rbenv/bin/rbenv version | cut -d ' ' -f 1 | grep -Fx '2.3.3'\"", "delta": "0:00:00.061391", "end": "2017-05-30 15:37:24.030104", "failed": false, "failed_when_result": false, "item": "jenkins", "rc": 1, "start": "2017-05-30 15:37:23.968713", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

TASK [ansible-rbenv-role : set ruby 2.3.3 for select users] ********************
...ignoring
failed: [sandbox-jenkins-slave-mobile] (item=[{'_ansible_parsed': True, 'stderr_lines': [], '_ansible_item_result': True, u'end': u'2017-05-30 15:37:24.030104', '_ansible_no_log': False, u'stdout': u'', u'cmd': u'$SHELL -lc "~/.rbenv/bin/rbenv version | cut -d \' \' -f 1 | grep -Fx \'2.3.3\'"', u'rc': 1, 'item': u'jenkins', u'delta': u'0:00:00.061391', u'stderr': u'', u'changed': False, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'_raw_params': u'$SHELL -lc "~/.rbenv/bin/rbenv version | cut -d \' \' -f 1 | grep -Fx \'2.3.3\'"', u'removes': None, u'creates': None, u'chdir': None}}, 'stdout_lines': [], 'failed_when_result': False, u'start': u'2017-05-30 15:37:23.968713', 'failed': False}, u'jenkins']) => {"changed": true, "cmd": "$SHELL -lc \"~/.rbenv/bin/rbenv global 2.3.3 && rbenv rehash\"", "delta": "0:00:00.055041", "end": "2017-05-30 15:37:24.366349", "failed": true, "item": [{"_ansible_item_result": true, "_ansible_no_log": false, "_ansible_parsed": true, "changed": false, "cmd": "$SHELL -lc \"~/.rbenv/bin/rbenv version | cut -d ' ' -f 1 | grep -Fx '2.3.3'\"", "delta": "0:00:00.061391", "end": "2017-05-30 15:37:24.030104", "failed": false, "failed_when_result": false, "invocation": {"module_args": {"_raw_params": "$SHELL -lc \"~/.rbenv/bin/rbenv version | cut -d ' ' -f 1 | grep -Fx '2.3.3'\"", "_uses_shell": true, "chdir": null, "creates": null, "executable": null, "removes": null, "warn": true}}, "item": "jenkins", "rc": 1, "start": "2017-05-30 15:37:23.968713", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}, "jenkins"], "rc": 1, "start": "2017-05-30 15:37:24.311308", "stderr": "rbenv: version `2.3.3' not installed", "stderr_lines": ["rbenv: version `2.3.3' not installed"], "stdout": "", "stdout_lines": []}

My playbook:

- name: Jenkins Slave Mobile
  hosts: sandbox-jenkins-slave-mobile
  vars:
    rbenv:
      env: user
      version: v1.0.0
      default_ruby: 2.3.3
      rubies:
      - version: 2.3.3
  roles:
    - role: ansible-rbenv-role
      rbenv_users:
      - jenkins

My ansible:

ansible 2.3.0.0
  configured module search path = Default w/o overrides
  python version = 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]

Shims aren't loaded for noninteractive shells on ubuntu 12.04

Non interactive

> ssh mymachine 'echo $PATH'                                                                                                                                       
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Interactive

> ssh mymachine
mymachine$: echo $PATH
/usr/local/rbenv/shims:/usr/local/rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Any tips on fixing this? Basically anything following rbenv role in my playbook that relies on correct ruby version (like the gem role) fails.

No idempotency on "install ruby versions for system"

A role does not have idempotency which is essential feature of Ansible.
Following task always shows changed:

TASK [zzet.rbenv : install ruby versions for system] *********************************************************************************************************
changed: [dev-02] => (item={u'version': u'2.5.1'})

Role variables:

    rbenv:
      env: system
      version: v1.1.1
      default_ruby: 2.5.1
      rubies:
        - version: 2.5.1

Missing python bindings

I got this error while trying to use this with CentOS 6.6:

TASK: [ruby | add rbenv initialization to profile system-wide] **************** 
failed: [192.168.33.11] => {"failed": true}
msg: Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!

FATAL: all hosts have already failed -- aborting

Adding libselinux-python to the yum dependencies fixed it.

Permission denied while install rbenv system wise

Hi Andrew,
Thanks for the rbenv role, it save me time to setup rbenv in the VMs, however, I ran into a issue when I use the rbenv role. In my playbook, I want to setup a system wise rbenv and have other roles that don't need to run under 'root' user.

At first, I thought I can use 'sudo:yes' like this:

- hosts: default
  roles:
    - role: zzet.rbenv
      sudo: yes
      rbenv:
        env: system
        version: v0.4.0
        ruby_version: 2.1.1

But I got permission denied and stopped at the 'clone rbenv repo' task when I run the playbook. It looks like the role do not care about 'sudo:yes' I passed in.

Leo Liang

Slow tasks for plugins

The plugin tasks are quite slow, probably because they are running whether or not the plugins are currently at the correct committish. This section:

TASK [zzet.rbenv : install plugins for selected users] *************************
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rbenv/rbenv-vars.git', u'version': u'v1.2.0', u'name': u'rbenv-vars'}])
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rbenv/ruby-build.git', u'version': u'master', u'name': u'ruby-build'}])
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rbenv/rbenv-default-gems.git', u'version': u'ead67889c91c53ad967f85f5a89d986fdb98f6fb', u'name': u'rbenv-default-gems'}])
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rbenv/rbenv-installer.git', u'version': u'bc21e7055dcc8f5f9bc66ce0c78cc9ae0c28cd7a', u'name': u'rbenv-installer'}])
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rkh/rbenv-update.git', u'version': u'1961fa180280bb50b64cbbffe6a5df7cf70f5e50', u'name': u'rbenv-update'}])
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rkh/rbenv-whatis.git', u'version': u'v1.0.0', u'name': u'rbenv-whatis'}])
ok: [default] => (item=[u'vagrant', {u'repo': u'https://github.com/rkh/rbenv-use.git', u'version': u'v1.0.0', u'name': u'rbenv-use'}])`

could potentially be sped up a great deal by simply checking out the correct commitish (if it exists), and only perform a clone, fetch, or pull if the repository doesn't exist or doesn't contain the necessary commits.

Install rbenv broken since last release

Hi,
The last release has broken the rbenv install for a user.
The issue seems to come from this block of code, it skips the rbenv install:

- name: install ruby {{ item[2].version }} for select users
  shell: $SHELL -lc "{{ rbenv_root }}/bin/rbenv install {{ item[2].version }}"
  become: yes
  become_user: "{{ item[1] }}"
  with_nested:
    - "{{ rbenv_versions.results }}"
    - "{{ rbenv_users }}"
    - "{{ rbenv.rubies }}"
  when:
    - item[0].rc == 0
    - item[0].item[0] == item[1]
    - item[2].version not in item[0].stdout_lines
  ignore_errors: yes
  environment: "{{ item[2].env | default({}) | combine({ 'TMPDIR': rbenv_tmpdir }) }}"

No package matching 'libyaml-devel' found available, installed or updated

I'm running this role against Red Hat 7 and seeing this error:

TASK [zzet.rbenv : install build depends] ******************************************************************************
failed: [staging] (item=[u'bzip2', u'gcc', u'git', u'libffi-devel', u'libyaml-devel', u'openssl-devel', u'readline-devel', u'zlib-devel']) => {"changed": false, "failed": true, "item": ["bzip2", "gcc", "git", "libffi-devel", "libyaml-devel", "openssl-devel", "readline-devel", "zlib-devel"], "msg": "No package matching 'libyaml-devel' found available, installed or updated", "rc": 126, "results": ["No package matching 'libyaml-devel' found available, installed or updated"]}

clean up after version change

I have these variables:

rbenv:
env: user
version: v1.0.0
ruby_version: 2.3.1

So I want to upgrade to ruby_version: 2.4.1

There maybe should be a task to remove / clean up old ruby versions?

[DEPRECATION WARNING]: Using bare variables is deprecated

As of Ansible 2.0 or 2.1 I believe...

TASK [zzet.rbenv : check ruby 2.2.4 installed for select users] ****************
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks so that the environment value uses the full variable syntax ('{{rbenv_users}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

TASK [zzet.rbenv : install ruby 2.2.4 for select users] ************************
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks so that the environment  value uses the full variable syntax ('{{ruby_installed.results}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks so that the environment  value uses the full variable syntax ('{{rbenv_users}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

TASK [zzet.rbenv : check if user ruby version is 2.2.4] ************************
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks so that the environment  value uses the full variable syntax ('{{rbenv_users}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

TASK [zzet.rbenv : set ruby 2.2.4 for select users] ****************************
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks so that the environment  value uses the full variable syntax ('{{ruby_selected.results}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Using bare variables is deprecated. Update your playbooks so that the environment value uses the full variable syntax ('{{rbenv_users}}').
This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

Fails on Debian Stretch due to permissions

I ran version 2.2.6 and 3.3.6 on Debian Jessy without a problem. But on Debian Stretch I get the following error:

TASK [zzet.rbenv : checkout rbenv_repo for selected users] *********************************************************************************
fatal: [vagrant]: FAILED! => {"msg": "Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chown: changing ownership of '/tmp/ansible-tmp-1515564561.64-22943182032838/': Operation not permitted\nchown: changing ownership of '/tmp/ansible-tmp-1515564561.64-22943182032838/git.py': Operation not permitted\n}). For information on working around this, see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user"}

I'm connecting as user vagrant to a local virtual machine. The user has full sudo permissions and is supposed to install rbenv for another user. Here is the config from the playbook:

    - role: zzet.rbenv
      rbenv:
        env: user
        version: v0.4.0
        default_ruby: 1.9.3-p551
        rubies:
          - version: 1.9.3-p551
      rbenv_owner: "{{ app_user }}"
      rbenv_group: "{{ app_user }}"
      rbenv_users:
        - "{{ app_user }}"

I'm using Ansible 2.4.2.0l

conditional fail with ansible_pkg_mgr

Running with ansible 1.7.2 and 1.8.4 (fails on both) on ubuntu 14.04, vagrant 1.6.3, virtualbox 4.3.10

TASK: [zzet.rbenv | include env vars] ***************************************** 
ok: [default]

TASK: [zzet.rbenv | update apt cache] ***************************************** 
fatal: [default] => error while evaluating conditional: ansible_pkg_mgr == 'apt'

FATAL: all hosts have already failed -- aborting                                                                                       

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/home/adam/playbook.retry

default                    : ok=1    changed=0    unreachable=1    failed=0   

Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.

My config:


---
- hosts: all
  user: vagrant
  gather_facts: False
  sudo: True
  roles:
    - role: zzet.rbenv
      rbenv_users:
        - vagrant

Am I missing something?

'rbenv_owner' is undefined

I tried to run the example from the readme file:

- hosts: web
  gather_facts: true # https://github.com/zzet/ansible-rbenv-role/issues/37
  vars:
    rbenv:
      env: user
      version: v0.4.0
      ruby_version: 2.0.0-p353
  roles:
    - role: zzet.rbenv
      rbenv_users:
        - user

But I get an error:

TASK [zzet.rbenv : set rbenv_owner] ********************************************
fatal: [vagrant]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'rbenv_owner' is undefined\n\nThe error appears to have been in '/home/maikel/github/fairfood-install/roles/zzet.rbenv/tasks/main.yml': line 14, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: set rbenv_owner\n  ^ here\n"}

It helps to provide the variables rbenv_owner and rbenv_group. The readme mentions these variables, but I didn't expect to need them for a user installation (not system). Maybe that should be included in the readme and the example? Ideally, they would default to the target user if rbenv.env: user.

1.3.0 fails to set ruby version

The main task tasks/main.yml doesn't set the Ruby version. Instead of running rbenv global {{ rbenv.ruby_version }} && rbenv rehash it runs the install command a second time.

I will try a newer version. A fix in version 1.3.1 would be nice.

error Install with env user at task: initialization to profile system-wide

Hi, first good job with playbook.
So I'm try use this playbook withe env: true but this errors happened:

TASK [zzet.rbenv : add rbenv initialization to profile system-wide] **********************************************************************************
fatal: [rails_server]: FAILED! => {"changed": false, "checksum": "80e9fe35728856b6e7444cb0fbcc844a8424674c", "gid": 1000, "group": "deployer", "mode": "0664", "msg": "chown failed: [Errno 1] Operation not permitted: '/etc/profile.d/rbenv.sh'", "owner": "deployer", "path": "/etc/profile.d/rbenv.sh", "size": 132, "state": "file", "uid": 1000}

I was in doubt why tasks below it's necessary at user environment:

- name: add rbenv initialization to profile system-wide
  template:
    src: rbenv_user.sh.j2
    dest: /etc/profile.d/rbenv.sh
    owner: root
    group: root
    mode: 0755
  become: yes
  when:
    - (ansible_os_family != 'OpenBSD' and ansible_os_family != 'Darwin') and rbenv_user_profile

My confi roles is:

- name: Install Rails
  hosts: webserver
  gather_facts: true
  become: yes
  become_user: deployer
  vars_files:
    - vars/production.yml

  roles:
    - common
    - role: zzet.rbenv
      rbenv_users:
        - deployer
    - wkhtmltox
    - ruby_config
    - nginx_passenger
    - redis
    - memcached
    - { role: Datadog.datadog, become_user: root }

I removed this lines at ~/.ansible/roles/zzet.rbenv/tasks/user_install.yml and works.

Thank You
Bye

[feature request] ability to not install a system ruby version?

I want to install rbenv with this role but then not install a ruby version until later in my build when my app sources are checked out. There's a .ruby-version file which defines the proper ruby version (at which point I can just add a shell: bash -lc rbenv install line to install the correct ruby version without specifying it anywhere in my ansible vars. Does that make sense? Could it be possible to define rbenv.ruby_version as an empty/ false value to skip the default install?

Role works on Ubuntu only

Please add 'apt' package manager as a dependency to the README. This role doesn't work outside of the Ubuntu family.
TASK [zzet.rbenv : update apt cache] ************************************************************************************************************************************ fatal: [my-host]: FAILED! => {"msg": "The conditional check 'ansible_pkg_mgr == 'apt'' failed. The error was: error while evaluating conditional (ansible_pkg_mgr == 'apt'): 'ansible_pkg_mgr' is undefined\n\nThe error appears to be in '/Users/deploy/.ansible/roles/zzet.rbenv/tasks/apt_build_depends.yml': line 1, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: update apt cache\n ^ here\n"}

Task: chown permission to .rbenv directory

item[0] seems to be undefined for this task and is throwing me an error in the when statement:

when: (not "system" == "{{ rbenv.env }}") and (item[0].rc != 0)

If I remove the item comparison, the new error complains about another value of item:

fatal: [default] => One or more undefined variables: 'None' has no attribute 'name'

which pertains to line:

shell: "chown -R {{ item[1].name }}:{{ item[1].name }} {{ item[1].home }}/.rbenv"

Please help me fix this.

Thank you.

Increment version for users -> rbenv_users change?

I've just spent a while figuring out why one of the steps from this role wasnt working, and I think its because users was changed to rbenv_users in 5e76c74. Should this have had a version increment?

Also the README shows rbenv_users in the defaults section and users in the Description and Example sections.

Bundler 2.0 compatibility

Bundler v2.0 has been released. It has a hard dependency on RubyGems >3.0.
http://bundler.io/blog/2019/01/03/announcing-bundler-2.html

This role by default uses this plugin
https://github.com/rbenv/rbenv-default-gems
plus a defaults file
https://github.com/zzet/ansible-rbenv-role/blob/master/files/default-gems
to install the bundler gem.

This installation will fail for any Ruby version that doesn't come bundled with RubyGems 3.0.

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
$ gem install bundler
ERROR:  Error installing bundler:
	The last version of bundler (>= 0) to support your Ruby & RubyGems was 1.17.3. Try installing it with `gem install bundler -v 1.17.3`
	bundler requires RubyGems

Ruby 2.6.0 does package RubyGems > 3.0:
https://www.ruby-lang.org/en/news/2018/12/25/ruby-2-6-0-released/

Options:

  1. End users of this role could customise the default_gems_file with a bundler <3.0 restriction.

  2. This role could try to detect RubyGems version and set the default_gems content appropriately.

  3. This role could update RubyGems gem update --system. Might introduce incompatibilities.

  4. End users could upgrade to Ruby 2.6. Might not be feasible.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.