Giter VIP home page Giter VIP logo

Comments (9)

wintermoot avatar wintermoot commented on July 17, 2024

I should add, when I create a standalone rvm.yml playbook and use the provided example. It kind of works?

Upgraded Ansible to latest 2.13.4 and checked I am using latest v2.1.2 version of rvm.ruby Role from Ansible-Galaxy

When I run my rvm.yml it seems say RVM is installed.. since it then skips the install on the next step. Confirmed the .rvm folder exists in the proper user folder.

But it hangs on the Installing Rubies step. I let it run for over an hour, it doesn't seem to be consuming any additional disk space or doing anything. It just hangs until I CTRL-C it..

Any thoughts? I'll post a complete output of the CLI from ansible in the next comment for full detail

Thanks

Andy

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024

ISSUE:

trying to run a simple rvm.ruby playbook and it installs rvm as expected with proper permissions and .rvm folder is populated.

MISSING: rubies for ruby-2.3.1 (the .rvm/rubies folder is empty) but the ansible playbook seems to say it's OK?

                    TASK [rvm.ruby : Detect if rubies are installed] 
                    **************************************************************************************
                    ok: [10.10.200.201] => (item=ruby-2.3.1)

then it stalls at the "installing rubies" task.

see console output and details below:

webuser@hoth:~/ansible/deb1$ cat rvm.yml
---

- name: Configure servers with ruby support for single user
  hosts: web_servers

  roles:
	- { role: rvm.ruby,
		become: yes,
		tags: ruby,
		rvm1_rubies: ['ruby-2.3.1'],
		rvm1_user: 'webuser',
		rvm1_install_flags: '--auto-dotfiles --user-install',
		rvm1_rvm_check_for_updates: true
	  }
webuser@hoth:~/ansible/deb1$



webuser@hoth:~/ansible/deb1$ ansible-playbook rvm.yml

PLAY [Configure servers with ruby support for single user] ****************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************
ok: [10.10.200.201]

TASK [rvm.ruby : Detect rvm binary] ***************************************************************************************************
ok: [10.10.200.201]

TASK [rvm.ruby : Detect rvm installer] ************************************************************************************************
ok: [10.10.200.201]

TASK [rvm.ruby : Detect current rvm version] ******************************************************************************************
ok: [10.10.200.201]

TASK [rvm.ruby : Install rvm installer] ***********************************************************************************************
skipping: [10.10.200.201]

TASK [rvm.ruby : Import GPG keys from keyservers] *************************************************************************************
failed: [10.10.200.201] (item=hkp://pool.sks-keyservers.net) => {"ansible_loop_var": "item", "changed": false, "cmd": "gpg --batch --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB", "delta": "0:00:20.295737", "end": "2022-09-13 01:46:01.922931", "item": "hkp://pool.sks-keyservers.net", "msg": "non-zero return code", "rc": 2, "start": "2022-09-13 01:45:41.627194", "stderr": "gpg: keyserver receive failed: Server indicated a failure", "stderr_lines": ["gpg: keyserver receive failed: Server indicated a failure"], "stdout": "", "stdout_lines": []}
failed: [10.10.200.201] (item=hkp://ipv4.pool.sks-keyservers.net) => {"ansible_loop_var": "item", "changed": false, "cmd": "gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB", "delta": "0:00:05.970048", "end": "2022-09-13 01:46:08.367213", "item": "hkp://ipv4.pool.sks-keyservers.net", "msg": "non-zero return code", "rc": 2, "start": "2022-09-13 01:46:02.397165", "stderr": "gpg: keyserver receive failed: Server indicated a failure", "stderr_lines": ["gpg: keyserver receive failed: Server indicated a failure"], "stdout": "", "stdout_lines": []}
ok: [10.10.200.201] => (item=hkp://pgp.mit.edu)
skipping: [10.10.200.201] => (item=hkp://keyserver.pgp.com)
...ignoring

TASK [rvm.ruby : Was GPG import from keyservers succesfull?] **************************************************************************
skipping: [10.10.200.201] => (item={'changed': False, 'stdout': '', 'stderr': 'gpg: keyserver receive failed: Server indicated a failure', 'rc': 2, 'cmd': 'gpg --batch --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', 'start': '2022-09-13 01:45:41.627194', 'end': '2022-09-13 01:46:01.922931', 'delta': '0:00:20.295737', 'failed': True, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'gpg --batch --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', '_uses_shell': True, 'warn': False, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': [], 'stderr_lines': ['gpg: keyserver receive failed: Server indicated a failure'], 'item': 'hkp://pool.sks-keyservers.net', 'ansible_loop_var': 'item'})
skipping: [10.10.200.201] => (item={'changed': False, 'stdout': '', 'stderr': 'gpg: keyserver receive failed: Server indicated a failure', 'rc': 2, 'cmd': 'gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', 'start': '2022-09-13 01:46:02.397165', 'end': '2022-09-13 01:46:08.367213', 'delta': '0:00:05.970048', 'failed': True, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'gpg --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', '_uses_shell': True, 'warn': False, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': [], 'stderr_lines': ['gpg: keyserver receive failed: Server indicated a failure'], 'item': 'hkp://ipv4.pool.sks-keyservers.net', 'ansible_loop_var': 'item'})
ok: [10.10.200.201] => (item={'changed': False, 'stdout': '', 'stderr': 'gpg: key 105BD0E739499BDB: 2 duplicate signatures removed\ngpg: key 105BD0E739499BDB: "Piotr Kuczynski " not changed\ngpg: key 3804BB82D39DC0E3: "Michal Papis (RVM signing) " not changed\ngpg: Total number processed: 2\ngpg:              unchanged: 2', 'rc': 0, 'cmd': 'gpg --batch --keyserver hkp://pgp.mit.edu --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', 'start': '2022-09-13 01:46:08.859014', 'end': '2022-09-13 01:48:41.236967', 'delta': '0:02:32.377953', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'gpg --batch --keyserver hkp://pgp.mit.edu --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', '_uses_shell': True, 'warn': False, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': [], 'stderr_lines': ['gpg: key 105BD0E739499BDB: 2 duplicate signatures removed', 'gpg: key 105BD0E739499BDB: "Piotr Kuczynski " not changed', 'gpg: key 3804BB82D39DC0E3: "Michal Papis (RVM signing) " not changed', 'gpg: Total number processed: 2', 'gpg:              unchanged: 2'], 'failed': False, 'item': 'hkp://pgp.mit.edu', 'ansible_loop_var': 'item'})
skipping: [10.10.200.201] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': 'hkp://keyserver.pgp.com', 'ansible_loop_var': 'item'})

TASK [rvm.ruby : Import GPG keys from rvm.io, if keyservers failed] *******************************************************************
skipping: [10.10.200.201] => (item=mpapis.asc)
skipping: [10.10.200.201] => (item=pkuczynski.asc)

TASK [rvm.ruby : Install rvm] *********************************************************************************************************
skipping: [10.10.200.201]

TASK [rvm.ruby : Update rvm] **********************************************************************************************************
ok: [10.10.200.201]

TASK [rvm.ruby : Configure rvm] *******************************************************************************************************
skipping: [10.10.200.201]

TASK [rvm.ruby : Detect if rubies are installed] **************************************************************************************
ok: [10.10.200.201] => (item=ruby-2.3.1)

TASK [rvm.ruby : Install rubies] ******************************************************************************************************

It just stalls here.. I let it run for a few hours to see, so far, still no progress or sign of life.

NOTE: I did try something mentioned in another thread, about rvm getting stuck waiting for user input.. so I edited my .rvm/.rvmrc file to include "rvm_trust_rvmrcs_flag=1" but it still doesn't seem to have helped with it being seemingly stuck.

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024
webuser@hoth:~/ansible/deb1$ cat rvm.yml
---

- name: Configure servers with ruby support for single user
  hosts: web_servers

  roles:
    - { role: rvm.ruby,
        tags: ruby,
        rvm1_user: 'webuser',
        rvm1_rubies: ['ruby-2.3.1','ruby-2.3.4'],
        rvm1_bundler_install: True,
        rvm1_delete_ruby: ,
        rvm1_install_path: '~/.rvm',
        rvm1_install_flags: '--auto-dotfiles  --user-install',
        rvm1_rvm_latest_installer: 'https://raw.githubusercontent.com/rvm/rvm/master/binscripts/rvm-installer',
        rvm1_rvm_version: 'stable',
        rvm1_rvm_check_for_updates: True,
        rvm1_gpg_keys: '409B6B1796C275462A1703113804BB82D39DC0E3',
        rvm1_gpg_key_server: 'hkp://keys.openpgp.org',
        rvm1_autolib_mode: 3,
        rvm1_symlink: true,
      }
webuser@hoth:~/ansible/deb1$
webuser@hoth:~/ansible/deb1$ ansible-playbook -vvvvvv rvm.yml

removed stuff that is working


TASK [rvm.ruby : Install rubies] ****************************************************************************************************************************************************************************
task path: /home/webuser/.ansible/roles/rvm.ruby/tasks/rubies.yml:11
<10.10.200.201> ESTABLISH SSH CONNECTION FOR USER: ansibusr
<10.10.200.201> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<10.10.200.201> SSH: ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set: (-o)(IdentityFile="/home/webuser/.ssh/ansible")
<10.10.200.201> SSH: ansible_password/ansible_ssh_password not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no)
<10.10.200.201> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="ansibusr")
<10.10.200.201> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)
<10.10.200.201> SSH: Set ssh_common_args: ()
<10.10.200.201> SSH: Set ssh_extra_args: ()
<10.10.200.201> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath="/home/webuser/.ansible/cp/551e395509")
<10.10.200.201> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/webuser/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansibusr"' -o ConnectTimeout=10 -o 'ControlPath="/home/webuser/.ansible/cp/551e395509"' 10.10.200.201 '/bin/sh -c '"'"'echo ~ansibusr && sleep 0'"'"''
<10.10.200.201> (0, b'/home/ansibusr\n', b'OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f  31 Mar 2020\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files\r\ndebug1: /etc/ssh/ssh_config line 21: Applying options for *\r\ndebug2: resolve_canonicalize: hostname 10.10.200.201 is address\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 2579\r\ndebug3: mux_client_request_session: session request sent\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.10.200.201> ESTABLISH SSH CONNECTION FOR USER: ansibusr
<10.10.200.201> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<10.10.200.201> SSH: ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set: (-o)(IdentityFile="/home/webuser/.ssh/ansible")
<10.10.200.201> SSH: ansible_password/ansible_ssh_password not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no)
<10.10.200.201> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="ansibusr")
<10.10.200.201> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)
<10.10.200.201> SSH: Set ssh_common_args: ()
<10.10.200.201> SSH: Set ssh_extra_args: ()
<10.10.200.201> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath="/home/webuser/.ansible/cp/551e395509")
<10.10.200.201> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/webuser/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansibusr"' -o ConnectTimeout=10 -o 'ControlPath="/home/webuser/.ansible/cp/551e395509"' 10.10.200.201 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /var/tmp `"&& mkdir "` echo /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715 `" && echo ansible-tmp-1663186894.0136704-2758-227152985737715="` echo /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715 `" ) && sleep 0'"'"''
<10.10.200.201> (0, b'ansible-tmp-1663186894.0136704-2758-227152985737715=/var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715\n', b'OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f  31 Mar 2020\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files\r\ndebug1: /etc/ssh/ssh_config line 21: Applying options for *\r\ndebug2: resolve_canonicalize: hostname 10.10.200.201 is address\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 2579\r\ndebug3: mux_client_request_session: session request sent\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
Using module file /home/webuser/.local/lib/python3.8/site-packages/ansible/modules/command.py
<10.10.200.201> PUT /home/webuser/.ansible/tmp/ansible-local-2671kfai1b94/tmpul6qp0g2 TO /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715/AnsiballZ_command.py
<10.10.200.201> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<10.10.200.201> SSH: ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set: (-o)(IdentityFile="/home/webuser/.ssh/ansible")
<10.10.200.201> SSH: ansible_password/ansible_ssh_password not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no)
<10.10.200.201> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="ansibusr")
<10.10.200.201> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)
<10.10.200.201> SSH: Set ssh_common_args: ()
<10.10.200.201> SSH: Set sftp_extra_args: ()
<10.10.200.201> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath="/home/webuser/.ansible/cp/551e395509")
<10.10.200.201> SSH: EXEC sftp -b - -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/webuser/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansibusr"' -o ConnectTimeout=10 -o 'ControlPath="/home/webuser/.ansible/cp/551e395509"' '[10.10.200.201]'
<10.10.200.201> (0, b'sftp> put /home/webuser/.ansible/tmp/ansible-local-2671kfai1b94/tmpul6qp0g2 /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715/AnsiballZ_command.py\n', b'OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f  31 Mar 2020\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files\r\ndebug1: /etc/ssh/ssh_config line 21: Applying options for *\r\ndebug2: resolve_canonicalize: hostname 10.10.200.201 is address\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 2579\r\ndebug3: mux_client_request_session: session request sent\r\ndebug2: Remote version: 3\r\ndebug2: Server supports extension "[email protected]" revision 1\r\ndebug2: Server supports extension "[email protected]" revision 2\r\ndebug2: Server supports extension "[email protected]" revision 2\r\ndebug2: Server supports extension "[email protected]" revision 1\r\ndebug2: Server supports extension "[email protected]" revision 1\r\ndebug2: Server supports extension "[email protected]" revision 1\r\ndebug3: Sent message fd 3 T:16 I:1\r\ndebug3: SSH_FXP_REALPATH . -> /home/ansibusr size 0\r\ndebug3: Looking up /home/webuser/.ansible/tmp/ansible-local-2671kfai1b94/tmpul6qp0g2\r\ndebug3: Sent message fd 3 T:17 I:2\r\ndebug3: Received stat reply T:101 I:2\r\ndebug1: Couldn\'t stat remote file: No such file or directory\r\ndebug3: Sent message SSH2_FXP_OPEN I:3 P:/var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715/AnsiballZ_command.py\r\ndebug3: Sent message SSH2_FXP_WRITE I:4 O:0 S:32768\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 4 32768 bytes at 0\r\ndebug3: Sent message SSH2_FXP_WRITE I:5 O:32768 S:32768\r\ndebug3: Sent message SSH2_FXP_WRITE I:6 O:65536 S:32768\r\ndebug3: Sent message SSH2_FXP_WRITE I:7 O:98304 S:32768\r\ndebug3: Sent message SSH2_FXP_WRITE I:8 O:131072 S:1294\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 5 32768 bytes at 32768\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 6 32768 bytes at 65536\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 7 32768 bytes at 98304\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: In write loop, ack for 8 1294 bytes at 131072\r\ndebug3: Sent message SSH2_FXP_CLOSE I:4\r\ndebug3: SSH2_FXP_STATUS 0\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.10.200.201> ESTABLISH SSH CONNECTION FOR USER: ansibusr
<10.10.200.201> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<10.10.200.201> SSH: ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set: (-o)(IdentityFile="/home/webuser/.ssh/ansible")
<10.10.200.201> SSH: ansible_password/ansible_ssh_password not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no)
<10.10.200.201> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="ansibusr")
<10.10.200.201> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)
<10.10.200.201> SSH: Set ssh_common_args: ()
<10.10.200.201> SSH: Set ssh_extra_args: ()
<10.10.200.201> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath="/home/webuser/.ansible/cp/551e395509")
<10.10.200.201> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/webuser/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansibusr"' -o ConnectTimeout=10 -o 'ControlPath="/home/webuser/.ansible/cp/551e395509"' 10.10.200.201 '/bin/sh -c '"'"'setfacl -m u:webuser:r-x /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715/ /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715/AnsiballZ_command.py && sleep 0'"'"''
<10.10.200.201> (0, b'', b'OpenSSH_8.2p1 Ubuntu-4ubuntu0.5, OpenSSL 1.1.1f  31 Mar 2020\r\ndebug1: Reading configuration data /etc/ssh/ssh_config\r\ndebug1: /etc/ssh/ssh_config line 19: include /etc/ssh/ssh_config.d/*.conf matched no files\r\ndebug1: /etc/ssh/ssh_config line 21: Applying options for *\r\ndebug2: resolve_canonicalize: hostname 10.10.200.201 is address\r\ndebug1: auto-mux: Trying existing master\r\ndebug2: fd 3 setting O_NONBLOCK\r\ndebug2: mux_client_hello_exchange: master version 4\r\ndebug3: mux_client_forwards: request forwardings: 0 local, 0 remote\r\ndebug3: mux_client_request_session: entering\r\ndebug3: mux_client_request_alive: entering\r\ndebug3: mux_client_request_alive: done pid = 2579\r\ndebug3: mux_client_request_session: session request sent\r\ndebug3: mux_client_read_packet: read header failed: Broken pipe\r\ndebug2: Received exit status from master 0\r\n')
<10.10.200.201> ESTABLISH SSH CONNECTION FOR USER: ansibusr
<10.10.200.201> SSH: ansible.cfg set ssh_args: (-C)(-o)(ControlMaster=auto)(-o)(ControlPersist=60s)
<10.10.200.201> SSH: ANSIBLE_PRIVATE_KEY_FILE/private_key_file/ansible_ssh_private_key_file set: (-o)(IdentityFile="/home/webuser/.ssh/ansible")
<10.10.200.201> SSH: ansible_password/ansible_ssh_password not set: (-o)(KbdInteractiveAuthentication=no)(-o)(PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey)(-o)(PasswordAuthentication=no)
<10.10.200.201> SSH: ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set: (-o)(User="ansibusr")
<10.10.200.201> SSH: ANSIBLE_TIMEOUT/timeout set: (-o)(ConnectTimeout=10)
<10.10.200.201> SSH: Set ssh_common_args: ()
<10.10.200.201> SSH: Set ssh_extra_args: ()
<10.10.200.201> SSH: found only ControlPersist; added ControlPath: (-o)(ControlPath="/home/webuser/.ansible/cp/551e395509")
<10.10.200.201> SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o 'IdentityFile="/home/webuser/.ssh/ansible"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o 'User="ansibusr"' -o ConnectTimeout=10 -o 'ControlPath="/home/webuser/.ansible/cp/551e395509"' -tt 10.10.200.201 '/bin/sh -c '"'"'sudo -H -S -n  -u webuser /bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-uggvdzjoasfkbvbsjcvkggonkybddjzj ; /usr/bin/python3 /var/tmp/ansible-tmp-1663186894.0136704-2758-227152985737715/AnsiballZ_command.py'"'"'"'"'"'"'"'"' && sleep 0'"'"''
Escalation succeeded

it just stalls here.. no real activity on server or network..

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024

A friend with more Ansible experience pointed out that ansible-galaxy is not the best way to install packages anymore (often out of date).

Version I had: v2.1.2 rvm.ruby
Version I have now: v2.2.0 rvm1-ansible

I still wasn't getting any further, it was still stalling on installing rubies.

running the playbook locally on the target host gives me more details

TASK [rvm1-ansible : Install rubies] ********************************************************************
failed: [localhost] (item=ruby-2.3.1) => {"ansible_loop_var": "item", "changed": true, "cmd": ["~/.rvm/bin/rvm", "install", "ruby-
2.3.1"], "delta": "0:00:14.826188", "end": "2022-09-14 19:22:33.070177", "item": "ruby-2.3.1", "msg": "non-zero return code", "rc": 
100, "start": "2022-09-14 19:22:18.243989", "stderr": "No binary rubies available for: debian/11/x86_64/ruby-2.3.1.\nContinuing 
with compilation. Please read 'rvm help mount' to get more information on binary rubies.\nError running 
'requirements_debian_libs_install gawk autoconf automake bison libgdbm-dev libncurses5-dev libsqlite3-dev libtool libyaml-
dev sqlite3 libgmp-dev libssl1.0-dev',\nplease read /home/webuser/.rvm/log/1663197746_ruby-
2.3.1/package_install_gawk_autoconf_automake_bison_libgdbm-dev_libncurses5-dev_libsqlite3-dev_libtool_libyaml-
dev_sqlite3_libgmp-dev_libssl1.0-dev.log\nRequirements installation failed with status: 100.", "stderr_lines": ["No binary rubies 
available for: debian/11/x86_64/ruby-2.3.1.", "Continuing with compilation. Please read 'rvm help mount' to get more 
information on binary rubies.", "Error running 'requirements_debian_libs_install gawk autoconf automake bison libgdbm-dev 
libncurses5-dev libsqlite3-dev libtool libyaml-dev sqlite3 libgmp-dev libssl1.0-dev',", "please read 
/home/webuser/.rvm/log/1663197746_ruby-2.3.1/package_install_gawk_autoconf_automake_bison_libgdbm-dev_libncurses5-
dev_libsqlite3-dev_libtool_libyaml-dev_sqlite3_libgmp-dev_libssl1.0-dev.log", "Requirements installation failed with status: 
100."], "stdout": "Searching for binary rubies, this might take some time.\nChecking requirements for 
debian.\n\u001b[32mRemoving undesired packages: libssl-dev\u001b[0m|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-
\b\\\b|\b/\b-\b.|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b|\b/\b.\nInstalling requirements for 
debian.\n\u001b[32mUpdating system\u001b[0m|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b|\b/\b-\b.|\b/\b-\b\\\b|\b/\b-
\b\\\b|\b.-\b\\\b.\n\u001b[32mInstalling required packages: gawk, autoconf, automake, bison, libgdbm-dev, libncurses5-dev, 
libsqlite3-dev, libtool, libyaml-dev, sqlite3, libgmp-dev, libssl1.0-dev\u001b[0m|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-
\b\\\b|\b/\b-\b.|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b.", "stdout_lines": ["Searching for binary rubies, this might take 
some time.", "Checking requirements for debian.", "\u001b[32mRemoving undesired packages: libssl-dev\u001b[0m|\b/\b-
\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b|\b/\b-\b.|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b|\b/\b.", "Installing 
requirements for debian.", "\u001b[32mUpdating system\u001b[0m|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b|\b/\b-
\b.|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b.", "\u001b[32mInstalling required packages: gawk, autoconf, automake, bison, libgdbm-
dev, libncurses5-dev, libsqlite3-dev, libtool, libyaml-dev, sqlite3, libgmp-dev, libssl1.0-dev\u001b[0m|\b/\b-\b\\\b|\b/\b-
\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b|\b/\b-\b.|\b/\b-\b\\\b|\b/\b-\b\\\b|\b.-\b\\\b|\b/\b-\b\\\b."]}


PLAY RECAP **********************************************************************************************
localhost                  : ok=8    changed=0    unreachable=0    failed=1    skipped=4    rescued=0    ignored=0

webuser@deb1:~/ansible$

Is rvm supposed to be able to compile a version when it can't find binaries?

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024

I changed the target version to v2.7.4 for the rubies and ran locally again, I believe I found the issue, it's asking for a password!

TASK [rvm1-ansible : Install rubies] ********************************************************************
webuser password required for 'apt-get --quiet --yes update':

once I put in the password, it was able to run to the end of the playbook!

webuser@deb1:~/ansible$ ansible-playbook --ask-become-pass rvm.yml
BECOME password:
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost
does not match 'all'

PLAY [Configure servers with ruby support for single user] **********************************************

TASK [Gathering Facts] **********************************************************************************
ok: [localhost]

TASK [rvm1-ansible : Detect rvm binary] *****************************************************************
ok: [localhost]

TASK [rvm1-ansible : Detect rvm installer] **************************************************************
ok: [localhost]

TASK [rvm1-ansible : Detect current rvm version] ********************************************************
ok: [localhost]

TASK [rvm1-ansible : Install rvm installer] *************************************************************
skipping: [localhost]

TASK [rvm1-ansible : Import GPG keys from keyservers] ***************************************************
ok: [localhost] => (item=hkp://keys.openpgp.org)
skipping: [localhost] => (item=hkp://pgp.mit.edu)
skipping: [localhost] => (item=hkp://keyserver.pgp.com)
skipping: [localhost] => (item=hkp://keyserver.ubuntu.com)

TASK [rvm1-ansible : Was GPG import from keyservers succesfull?] ****************************************
ok: [localhost] => (item={'cmd': 'gpg --batch --keyserver hkp://keys.openpgp.org --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', 'stdout': '', 'stderr': 'gpg: key 105BD0E739499BDB: "Piotr Kuczynski " not changed\ngpg: key 3804BB82D39DC0E3: "Michal Papis (RVM signing) " not changed\ngpg: Total number processed: 2\ngpg:              unchanged: 2', 'rc': 0, 'start': '2022-09-14 19:39:03.180285', 'end': '2022-09-14 19:39:05.393427', 'delta': '0:00:02.213142', 'changed': False, 'invocation': {'module_args': {'_raw_params': 'gpg --batch --keyserver hkp://keys.openpgp.org --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB', '_uses_shell': True, 'warn': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': [], 'stderr_lines': ['gpg: key 105BD0E739499BDB: "Piotr Kuczynski " not changed', 'gpg: key 3804BB82D39DC0E3: "Michal Papis (RVM signing) " not changed', 'gpg: Total number processed: 2', 'gpg:              unchanged: 2'], 'failed': False, 'item': 'hkp://keys.openpgp.org', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': 'hkp://pgp.mit.edu', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': 'hkp://keyserver.pgp.com', 'ansible_loop_var': 'item'})
skipping: [localhost] => (item={'changed': False, 'skipped': True, 'skip_reason': 'Conditional result was False', 'item': 'hkp://keyserver.ubuntu.com', 'ansible_loop_var': 'item'})

TASK [rvm1-ansible : Import GPG keys from rvm.io, if keyservers failed] *********************************
skipping: [localhost] => (item=mpapis.asc)
skipping: [localhost] => (item=pkuczynski.asc)

TASK [rvm1-ansible : Install rvm] ***********************************************************************
skipping: [localhost]

TASK [rvm1-ansible : Update rvm] ************************************************************************
ok: [localhost]

TASK [rvm1-ansible : Configure rvm] *********************************************************************
skipping: [localhost]

TASK [rvm1-ansible : Detect rubies] *********************************************************************
ok: [localhost]

TASK [rvm1-ansible : Install rubies] ********************************************************************
webuser password required for 'apt-get --quiet --yes update':
changed: [localhost] => (item=ruby-2.7.4)

TASK [rvm1-ansible : Detect default ruby version] *******************************************************
ok: [localhost]

TASK [rvm1-ansible : Select default ruby] ***************************************************************
changed: [localhost]

TASK [rvm1-ansible : Detect installed ruby patch number] ************************************************
ok: [localhost] => (item=ruby-2.7.4)

TASK [rvm1-ansible : Install bundler if not installed] **************************************************
ok: [localhost] => (item={'cmd': '~/.rvm/bin/rvm list strings | grep ruby-2.7.4 | tail -n 1\n', 'stdout': 'ruby-2.7.4', 'stderr': '', 'rc': 0, 'start': '2022-09-14 19:43:40.469208', 'end': '2022-09-14 19:43:41.116651', 'delta': '0:00:00.647443', 'changed': False, 'invocation': {'module_args': {'_raw_params': '~/.rvm/bin/rvm list strings | grep ruby-2.7.4 | tail -n 1\n', '_uses_shell': True, 'warn': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['ruby-2.7.4'], 'stderr_lines': [], 'failed': False, 'item': 'ruby-2.7.4', 'ansible_loop_var': 'item'})

TASK [rvm1-ansible : Symlink ruby related binaries on the system path] **********************************
skipping: [localhost] => (item=erb)
skipping: [localhost] => (item=executable-hooks-uninstaller)
skipping: [localhost] => (item=gem)
skipping: [localhost] => (item=irb)
skipping: [localhost] => (item=rake)
skipping: [localhost] => (item=rdoc)
skipping: [localhost] => (item=ri)
skipping: [localhost] => (item=ruby)

TASK [rvm1-ansible : Symlink bundler binaries on the system path] ***************************************
skipping: [localhost] => (item=bundle)
skipping: [localhost] => (item=bundler)

TASK [rvm1-ansible : Delete ruby if relevant] ***********************************************************
skipping: [localhost]

PLAY RECAP **********************************************************************************************
localhost                  : ok=13   changed=2    unreachable=0    failed=0    skipped=7    rescued=0    ignored=0

webuser@deb1:~/ansible$

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024

I should also mention, now that I ran the RVM playbook locally and it installed.. I can run the remote one too, since it just confirms everything is installed and doesn't need to install the rubies, which ends up triggering that password prompt:

So this right here seems to be the root cause (you can only see this, if you run the playbook locally on the target box, instead of running the remote playbook).

TASK [rvm1-ansible : Install rubies] ********************************************************************
webuser password required for 'apt-get --quiet --yes update':

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024

The server I am testing with (deb1 from logs above) is running Debian 11 Bullseye with all latest updates applied.

I couldn't find any part of the rvm1-ansible code which referenced this explicit call to 'apt-get --quiet --yes update'.

I'm curious to test with Ubuntu (since it seems to be THE distro referenced in the readme). However, I'd appreciate any advice on how to best deal with this on Debian. Is there a list of packages I should possibly install first using Ansible's package manager instead of relying on RVM to handle that?

I'm trying to find a solution that works on a fresh machine with remote execution.

The only way I was able to get the playbook to run was locally on the host so I could see that password prompt

from rvm1-ansible.

sfgeorge avatar sfgeorge commented on July 17, 2024

Hello! First off, Welcome and thank you for sharing not only your issues but the solutions you found along the way – so helpful for future readers!

I'm a little late to the party, but nevertheless I have a few comments along all of these issues you've already solved . . . :)


I believe the issue I'm having is that your instructions seem to show examples in a standalone playbook. Whereas I seem to be trying to run a Roles: within roles/tasks and .. well I haven't found any docs to help me figure out what I am doing wrong here. I'd really like to continue using roles/ based playbooks to keep things tidy.

Yes, it is possible to invoke rvm1-ansible as a role amongst an existing playbook. As you may have already discovered, the "mapping values are not allowed in this context" issue required updating the indenting from this:

- name: install rvm using the roles function
     roles:
            - { role: rvm.ruby,
                tags: ruby,
                rvm1_rubies: ['ruby-2.6.6'],
                rvm1_user: 'webuser'
              }

to this:

- name: install rvm using the roles function
  roles:
    - { role: rvm.ruby,
        tags: ruby,
        rvm1_rubies: ['ruby-2.6.6'],
        rvm1_user: 'webuser'
      }

...Welcome to the world of ansible YAML and watching your whitespace. 😂

I often use https://yaml-online-parser.appspot.com/ to help me double-check my YAML prior to executing – it is otherwise difficult to discern whether some errors originate from rvm, rvm-ansible, ansible runtime, or my underlying YAML syntax.


But it hangs on the Installing Rubies step. I let it run for over an hour, it doesn't seem to be consuming any additional disk space or doing anything. It just hangs until I CTRL-C it..

Glad you were able to get past this... yes as you later discovered, a common issue encountered for Ansible users is getting past a silent waiting for authentication step.


A friend with more Ansible experience pointed out that ansible-galaxy is not the best way to install packages anymore (often out of date).

Yes, though that is likely our fault rather than galaxy's. We're having some issue with publishing new versions of rvm-ansible to galaxy. You found the workaround, and here it is for others for reference as well:

#236 (comment)


Is rvm supposed to be able to compile a version when it can't find binaries?

Yes, RVM updates package manifests and installs packages by default through its autolibs setting, and this can be configured by passing a rvm1_autolib_mode: value to rvm-ansible as seen on rvm-ansible readme. This can be used to enable/disable this functionality.

I couldn't find any part of the rvm1-ansible code which referenced this explicit call to 'apt-get --quiet --yes update'.

Yeah, I know that's a little jarring to see your whole system being updated unexpectedly. 😲 This again is due to autolibs setting.

As for where this is defined, that's within rvm itself, rather than rvm-ansible (which merely installs RVM and runs several RVM setup commands).

I'm curious to test with Ubuntu (since it seems to be THE distro referenced in the readme). However, I'd appreciate any advice on how to best deal with this on Debian. Is there a list of packages I should possibly install first using Ansible's package manager instead of relying on RVM to handle that?

I agree... I don't particularly like the idea of incidentally upgrading fundamental packages on a system just because I re-ran playbook. And this has broken systems for me on several occasions due to the side effects of the good intentions of the autolibs feature.

Nevertheless, autolibs is extremely convenient in non-production environments.

You can properly protect your production environment from unexpected updates in one of a few ways.

Option 1 – Scrummage the RVM code for your OS to see which packages will be needed, and install them on your own terms.

Option 2 – Watch what autolibs does, then imitate it.

  1. Use RVM/rvm-ansible to install to an ephemeral system (such as a container)
  2. Review Syslog / or the package manager log to observe what package changes were made.
  3. Add desired package changes to your ansible playbook.

The only way I was able to get the playbook to run was locally on the host so I could see that password prompt

A few tips on getting passed tricky password prompt issues with provisioning...

  1. Run ansible / ansible-playbook with a lot of verbosity (-vvv). The reason is because you've got 2 layers where a password prompt may be occur – upon ssh'ing in, or upon ansible trying to invoke appropriate privilege escalation; by default invoking sudo will require entering a password. And several ansible (and rvm-ansible) operations require sudo.
  2. Review https://docs.ansible.com/ansible/latest/user_guide/become.html and decide which approach you'd like to use amongst the many options ansible provides for invoking sudo (what is more generally referred to as "become" in ansible nomenclature).
  3. If you hit a lot of resistance, consider allowing your ssh-login user to invoke sudo without an additional password prompt, by adding them to the sudoers list.

Thanks again for your updates along the way. Let us know if you hit further challenges or questions!

from rvm1-ansible.

wintermoot avatar wintermoot commented on July 17, 2024

Hello! First off, Welcome and thank you for sharing not only your issues but the solutions you found along the way – so helpful for future readers!

You're welcome! Want it or not, there's some lessons one has to learn when starting out and learned a lot in the process.
All the tips you included in your reply are excellent and I'm going to add those to my Ansible and Ruby coding process.

Yes, it is possible to invoke rvm1-ansible as a role amongst an existing playbook. As you may have already discovered, the "mapping values are not allowed in this context" issue required updating the indenting from this:
...Welcome to the world of ansible YAML and watching your whitespace. 😂

I often use https://yaml-online-parser.appspot.com/ to help me double-check my YAML prior to executing – it is otherwise difficult to discern whether some errors originate from rvm, rvm-ansible, ansible runtime, or my underlying YAML syntax.

Didn't realize it was so picky :) I should dive deeper into the actual syntax of YML.

Yeah, I know that's a little jarring to see your whole system being updated unexpectedly. 😲 This again is due to autolibs setting.

That makes sense, I really appreciate your help with detailed instructions on how to quickly extract that list of package dependencies and then trying to "imitate it".

I agree... I don't particularly like the idea of incidentally upgrading fundamental packages on a system just because I re-ran playbook. And this has broken systems for me on several occasions due to the side effects of the good intentions of the autolibs feature.

A few tips on getting passed tricky password prompt issues with provisioning...

  1. Run ansible / ansible-playbook with a lot of verbosity (-vvv). The reason is because you've got 2 layers where a password prompt may be occur – upon ssh'ing in, or upon ansible trying to invoke appropriate privilege escalation; by default invoking sudo will require entering a password. And several ansible (and rvm-ansible) operations require sudo.
  2. Review https://docs.ansible.com/ansible/latest/user_guide/become.html and decide which approach you'd like to use amongst the many options ansible provides for invoking sudo (what is more generally referred to as "become" in ansible nomenclature).
  3. If you hit a lot of resistance, consider allowing your ssh-login user to invoke sudo without an additional password prompt, by adding them to the sudoers list.

Excellent suggestions, added to my notes! I went overboard on the -vvvvv's but it's really by running it locally on the box that I was able to see what was going on. Wish Ansible would return those prompts somehow. Or throw a timeout when it realizes it's stuck on a task. But I imagine the stuff I am running into is just newb mistakes Ansible users learn to avoid through experience.

Thanks again for your updates along the way. Let us know if you hit further challenges or questions!

I appreciate your help and taking the time to share some great info which will be helpful moving forward

Thanks!

Andy

from rvm1-ansible.

Related Issues (20)

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.