From 10638f622faeb7e611e7b5f98cd5dc8b1bd7945c Mon Sep 17 00:00:00 2001 From: Travis Downs Date: Sat, 21 Dec 2024 01:25:00 -0300 Subject: [PATCH] feature: allow downloading of package by remote host Currently node_exporter install always downloads the package on the localhost and unpacks it there then uploads it to the remote host. In the case the ansible controller is at the other end of a thin network pipe, or if it may not even have access to the package URL, it may be desirable to download and unpack it on the remote host instead. This change adds that ability as an optional behavior to _common/install and wires it up for use by node_exporter, using the node_exporter_localhost_download variable. The default for node exporter and any other binaries remains the same as before: delegate to localhost. Fixes #389. Signed-off-by: Travis Downs --- roles/_common/tasks/install.yml | 14 ++++++++------ roles/_common/vars/main.yml | 1 + roles/node_exporter/defaults/main.yml | 5 +++++ roles/node_exporter/meta/argument_specs.yml | 3 +++ roles/node_exporter/tasks/main.yml | 1 + 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/roles/_common/tasks/install.yml b/roles/_common/tasks/install.yml index 7ff5a852c..7b0450ab5 100644 --- a/roles/_common/tasks/install.yml +++ b/roles/_common/tasks/install.yml @@ -46,12 +46,12 @@ - install - "{{ ansible_parent_role_names | first | regex_replace(ansible_collection_name ~ '.', '') }}_install" -- name: "Create localhost binary cache path" +- name: "Create binary cache path on {{ 'localhost' if (_common_delegate_to_localhost | bool) else 'remote host'}}" ansible.builtin.file: path: "{{ _common_local_cache_path }}" state: directory mode: 0755 - delegate_to: localhost + delegate_to: "{{ 'localhost' if (_common_delegate_to_localhost | bool) else omit }}" check_mode: false become: false tags: @@ -78,7 +78,7 @@ run_once: true when: (_common_checksums_url) - - name: "Download {{ __common_binary_basename }}" + - name: "Download {{ __common_binary_basename }} from {{ _common_binary_url }} on {{ 'localhost' if (_common_delegate_to_localhost | bool) else 'remote host'}}" ansible.builtin.get_url: url: "{{ _common_binary_url }}" dest: "{{ _common_local_cache_path }}/{{ _common_binary_name | default(__common_binary_basename) }}" @@ -90,17 +90,18 @@ retries: 5 delay: 2 # run_once: true # <-- this can't be set due to multi-arch support - delegate_to: localhost + delegate_to: "{{ 'localhost' if (_common_delegate_to_localhost | bool) else omit }}" check_mode: false - - name: "Unpack binary archive {{ __common_binary_basename }}" + - name: "Unpack binary archive {{ __common_binary_basename }} on {{ 'localhost' if (_common_delegate_to_localhost | bool) else 'remote host'}}" ansible.builtin.unarchive: src: "{{ _common_local_cache_path }}/{{ __common_binary_basename }}" dest: "{{ _common_local_cache_path }}" mode: 0755 list_files: true extra_opts: "{{ _common_binary_unarchive_opts | default(omit, true) }}" - delegate_to: localhost + remote_src: "{{ not (_common_delegate_to_localhost | bool) }}" + delegate_to: "{{ 'localhost' if (_common_delegate_to_localhost | bool) else omit }}" check_mode: false when: __common_binary_basename is search('\.zip$|\.tar\.gz$') @@ -129,6 +130,7 @@ mode: 0755 owner: root group: root + remote_src: "{{ not (_common_delegate_to_localhost | bool) }}" loop: "{{ _common_binaries }}" become: true notify: diff --git a/roles/_common/vars/main.yml b/roles/_common/vars/main.yml index 8d8beb8b8..790010b23 100644 --- a/roles/_common/vars/main.yml +++ b/roles/_common/vars/main.yml @@ -19,6 +19,7 @@ _common_tls_server_config: {} _common_http_server_config: {} _common_basic_auth_users: {} _common_web_listen_address: "" +_common_delegate_to_localhost: "true" # Variables that should not be overwritten __common_binary_basename: "{{ _common_binary_url | urlsplit('path') | basename }}" __common_github_api_headers: "{{ {'GITHUB_TOKEN': lookup('ansible.builtin.env', 'GITHUB_TOKEN')} if (lookup('ansible.builtin.env', 'GITHUB_TOKEN')) else {} }}" diff --git a/roles/node_exporter/defaults/main.yml b/roles/node_exporter/defaults/main.yml index 70cb27ef5..a01a567c7 100644 --- a/roles/node_exporter/defaults/main.yml +++ b/roles/node_exporter/defaults/main.yml @@ -33,3 +33,8 @@ node_exporter_system_user: "{{ node_exporter_system_group }}" node_exporter_config_dir: "/etc/node_exporter" # Local path to stash the archive and its extraction node_exporter_local_cache_path: "/tmp/node_exporter-{{ ansible_system | lower }}-{{ _node_exporter_go_ansible_arch }}/{{ node_exporter_version }}" +# If true (the default) we download node exporter archive and unpack it on localhost, before +# uploading it to the remote host(s). If false we download and unpack the archive on the remote +# host directly, which may be useful if the ansible controller host is slower (network-wise) +# than the remote host. +node_exporter_localhost_download: true diff --git a/roles/node_exporter/meta/argument_specs.yml b/roles/node_exporter/meta/argument_specs.yml index 05aa16e31..07f496561 100644 --- a/roles/node_exporter/meta/argument_specs.yml +++ b/roles/node_exporter/meta/argument_specs.yml @@ -82,3 +82,6 @@ argument_specs: node_exporter_config_dir: description: "Path to directory with node_exporter configuration" default: "/etc/node_exporter" + node_exporter_localhost_download: + description: "Determines if the node exporter package archive is downloaded and extracted on local (true) or remote host (false)" + default: true diff --git a/roles/node_exporter/tasks/main.yml b/roles/node_exporter/tasks/main.yml index d41d4370a..9c939dc3d 100644 --- a/roles/node_exporter/tasks/main.yml +++ b/roles/node_exporter/tasks/main.yml @@ -21,6 +21,7 @@ _common_system_user: "{{ node_exporter_system_user }}" _common_config_dir: "{{ node_exporter_config_dir }}" _common_binary_unarchive_opts: ['--strip-components=1'] + _common_delegate_to_localhost: "{{ node_exporter_localhost_download }}" tags: - node_exporter_install