executable-downloaded

Example:

# Install Hashicorp Terraform for user (in ~/.local/bin).
- executable-downloaded:
    url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
    extract: true

Description

Download a binary, (optionally) extract it, make it executable.

This frecklet tries to be as generically useful as possible for the situation where there is a single-file binary.

It comes with a few defaults, which are dependent on the user that was chosen as the owner and the value for 'dest' that was specified:

  • if no user:

    • if localhost target: user that executes the frecklet is used
    • if non-localhost target: login user for target is used
  • no dest:

    • if user == 'root': dest = '/usr/local/bin'
    • if user is not 'root': dest = "~/.local/bin"

Since a lot of 'single-binary'-applications come as a zipped (or otherwise archived) package, this frecklet also comes with an 'extract' flag. If set, freckles will try to extract the downloaded artifact into a temporary folder, and then move the content(s) of the archive to the target 'dest'-ination (using the 'exe_name' value as a pattern matcher -- see below).

Also, depending on whether 'exe_name' is provided and 'extract' is true or false, the behaviour of this frecklet slightly changes:

  • if no 'exe_name':
    • if 'extract' is false: full path to executable is "{{ dest }}/{{ basename of url }}"
    • if 'extract' is true: all content of the archive will be moved into "{{ dest }}"
  • if 'exe_name':
    • if 'extract' is false: full path to executable is "{{ dest }}/{{ exe_name }}"
    • if 'extract' is true: '
    • if not 'extract_subfolder': 'exe_name' will be treated as glob, and all files matching that glob will be moved into "{{ dest }}"
    • if 'extract_subfolder', 'exe_name' will be treated as glob, and all files in 'extract_subfolder' matching that glob will be moved into "{{ dest }}"

Variables

Name Type Default Description

url

string --

The url to download (can be templated). Required

dest

string --

The (absolute) path to the parent folder of the downloaded executable file.

exe_mode

string 0755

The mode for the executable file(s) (default: '0755').

exe_name

string --

A (matcher) glob to determine which files to copy to destination (in case of 'extract'), or the target file name (defaults to either '*' or 'url | basename'.

extract

boolean False

Whether the downloaded file is an archive and needs to be extracted.

extract_subfolder

string --

Base part where to start looking for the exe_name patter.

force

boolean --

Force overwrite executable if it already exists.

group

string --

The group of the executable.

owner

string --

The owner of the executable.

Examples

Example 1

Install Hashicorp Terraform for user (in ~/.local/bin).

Code
- executable-downloaded:
    url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
    extract: true

Example 2

Install Hashicorp Terraform system-wide.

Code
- executable-downloaded:
    url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
    owner: root
    group: root
    extract: true

Example 3

Install Hashicorp Terraform system-wide, in custom location.

Code
- executable-downloaded:
    url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
    owner: root
    group: root
    dest: /opt/terraform
    extract: true

Code

doc:
  short_help: Download a binary, (optionally) extract it, make it executable.
  help: |
    Download a binary, (optionally) extract it, make it executable.

    This frecklet tries to be as generically useful as possible for the situation where there is a single-file binary.

    It comes with a few defaults, which are dependent on the user that was chosen as the owner and the value for 'dest' that was specified:

      - if no user:
        - if localhost target: user that executes the frecklet is used
        - if non-localhost target: login user for target is used

      - no dest:
        - if user == 'root': dest = '/usr/local/bin'
        - if user is not 'root': dest = "~/.local/bin"

    Since a lot of 'single-binary'-applications come as a zipped (or otherwise archived) package, this frecklet also comes with an
    'extract' flag. If set, *freckles* will try to extract the downloaded artifact into a temporary folder, and then move the content(s)
    of the archive to the target 'dest'-ination (using the 'exe_name' value as a pattern matcher -- see below).

    Also, depending on whether 'exe_name' is provided and 'extract' is true or false, the behaviour of this *frecklet* slightly changes:

      - if no 'exe_name':
        - if 'extract' is false: full path to executable is "{{ dest }}/{{ basename of url }}"
        - if 'extract' is true: all content of the archive will be moved into "{{ dest }}"
      - if 'exe_name':
        - if 'extract' is false: full path to executable is "{{ dest }}/{{ exe_name }}"
        - if 'extract' is true: '
          - if not 'extract_subfolder': 'exe_name' will be treated as glob, and all files matching that glob will be moved into "{{ dest }}"
          - if 'extract_subfolder', 'exe_name' will be treated as glob, and all files in 'extract_subfolder' matching that glob will be moved into "{{ dest }}"
  examples:
  - title: Install Hashicorp Terraform for user (in ~/.local/bin).
    vars:
      url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
      extract: true
  - title: Install Hashicorp Terraform system-wide.
    vars:
      url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
      owner: root
      group: root
      extract: true
  - title: Install Hashicorp Terraform system-wide, in custom location.
    vars:
      url: https://releases.hashicorp.com/terraform/0.12.6/terraform_0.12.6_linux_amd64.zip
      owner: root
      group: root
      dest: /opt/terraform
      extract: true

args:
  dest:
    doc:
      short_help: The (absolute) path to the parent folder of the downloaded executable
        file.
    type: string
    required: false
  url:
    doc:
      short_help: The url to download (can be templated).
    type: string
    required: true
  extract:
    doc:
      short_help: Whether the downloaded file is an archive and needs to be extracted.
    type: boolean
    required: false
    default: false
    cli:
      param_decls:
      - --extract
  extract_subfolder:
    doc:
      short_help: Base part where to start looking for the exe_name patter.
    type: string
    required: false
  exe_name:
    doc:
      short_help: A (matcher) glob to determine which files to copy to destination
        (in case of 'extract'), or the target file name (defaults to either '*' or
        'url | basename'.
    type: string
    required: false
  exe_mode:
    doc:
      short_help: "The mode for the executable file(s) (default: '0755')."
    type: string
    default: '0755'
    required: false
  owner:
    doc:
      short_help: The owner of the executable.
    type: string
    required: false
    empty: false
    cli:
      metavar: USER
  group:
    doc:
      short_help: The group of the executable.
    type: string
    required: false
    empty: false
    cli:
      metavar: GROUP
  force:
    doc:
      short_help: Force overwrite executable if it already exists.
    type: boolean
    required: false
    cli:
      param_decls:
      - --force
      - -f

frecklets:
- group-exists:
    frecklet::skip: '{{:: group | true_if_empty ::}}'
    group: '{{:: group ::}}'
- user-exists:
    frecklet::skip: '{{:: owner | true_if_empty ::}}'
    name: '{{:: owner ::}}'
    group: '{{:: group ::}}'

#  - unzip-installed
#  - packages-installed:
#      become: true
#      packages:
#        - name: ca-certificates
#          pkgs:
#            debian: ca-certificates

- frecklet:
    name: executable-downloaded.at.yml
    type: ansible-tasklist
    resources:
      ansible-tasklist:
      - folder-exists.at.yml
      - file-downloaded.at.yml
      - archive-extracted.at.yml
      - executable-downloaded.at.yml
      - set-user-home-dir-var.at.yml
    properties:
      elevated: '{{:: owner | true_if_not_empty ::}}'
      idemptotent: true
      internet: true
    desc:
      short: download exectuable and put in place
      long: |
        Create temporary folder and download url '{{:: url ::}}' into it.

        {%:: if extract ::%}Extract downloaded file, then copy all (extracted) files {%:: if exe_name ::%}matching the glob-string '{{:: exe_name ::}}' {%:: endif ::%}into '{{:: dest ::}}'.{%:: else ::%}Copy the downloaded file into the folder '{{:: dest ::}}'{%:: if exe_name ::%} using the target file name {{:: exe_name ::}}{%:: endif ::%}.{%:: endif ::%}

        {%:: if owner ::%}Set the user '{{:: owner ::}}' as owner of the target file(s).{%:: endif ::%}
  vars:
    __dest__: '{{:: dest ::}}'
    __url__: '{{:: url ::}}'
    __extract__: '{{:: extract ::}}'
    __extract_subfolder__: '{{:: extract_subfolder ::}}'
    __exe_name__: '{{:: exe_name ::}}'
    __mode__: '{{:: exe_mode ::}}'
    __owner__: '{{:: owner ::}}'
    __group__: '{{:: group ::}}'
    __force__: '{{:: force ::}}'
frecklecute executable-downloaded --help

Usage: frecklecute executable-downloaded [OPTIONS]

  Download a binary, (optionally) extract it, make it executable.

  This frecklet tries to be as generically useful as possible for the
  situation where there is a single-file binary.

  It comes with a few defaults, which are dependent on the user that was
  chosen as the owner and the value for 'dest' that was specified:

    - if no user:     - if localhost target: user that executes the frecklet
    is used     - if non-localhost target: login user for target is used

    - no dest:     - if user == 'root': dest = '/usr/local/bin'     - if
    user is not 'root': dest = "~/.local/bin"

  Since a lot of 'single-binary'-applications come as a zipped (or otherwise
  archived) package, this frecklet also comes with an 'extract' flag. If
  set, *freckles* will try to extract the downloaded artifact into a
  temporary folder, and then move the content(s) of the archive to the
  target 'dest'-ination (using the 'exe_name' value as a pattern matcher --
  see below).

  Also, depending on whether 'exe_name' is provided and 'extract' is true or
  false, the behaviour of this *frecklet* slightly changes:

    - if no 'exe_name':     - if 'extract' is false: full path to executable
    is "{{ dest }}/{{ basename of url }}"     - if 'extract' is true: all
    content of the archive will be moved into "{{ dest }}"   - if
    'exe_name':     - if 'extract' is false: full path to executable is "{{
    dest }}/{{ exe_name }}"     - if 'extract' is true: '       - if not
    'extract_subfolder': 'exe_name' will be treated as glob, and all files
    matching that glob will be moved into "{{ dest }}"       - if
    'extract_subfolder', 'exe_name' will be treated as glob, and all files
    in 'extract_subfolder' matching that glob will be moved into "{{ dest
    }}"

Options:
  --url URL                       The url to download (can be templated).
                                  [required]
  --dest DEST                     The (absolute) path to the parent folder of
                                  the downloaded executable file.
  --exe-mode EXE_MODE             The mode for the executable file(s)
                                  (default: '0755').
  --exe-name EXE_NAME             A (matcher) glob to determine which files to
                                  copy to destination (in case of 'extract'),
                                  or the target file name (defaults to either
                                  '*' or 'url | basename'.
  --extract                       Whether the downloaded file is an archive
                                  and needs to be extracted.
  --extract-subfolder EXTRACT_SUBFOLDER
                                  Base part where to start looking for the
                                  exe_name patter.
  -f, --force                     Force overwrite executable if it already
                                  exists.
  --group GROUP                   The group of the executable.
  --owner USER                    The owner of the executable.
  --help                          Show this message and exit.
# -*- coding: utf-8 -*-


#
# module path: pycklets.executable_downloaded.ExecutableDownloaded
#


from dataclasses import dataclass
from pyckles import AutoPycklet
from typing import *    # noqa

@dataclass
class ExecutableDownloaded(AutoPycklet):
    """Download a binary, (optionally) extract it, make it executable.

     This frecklet tries to be as generically useful as possible for the situation where there is a single-file binary.

     It comes with a few defaults, which are dependent on the user that was chosen as the owner and the value for 'dest' that was specified:

       - if no user:
         - if localhost target: user that executes the frecklet is used
         - if non-localhost target: login user for target is used

       - no dest:
         - if user == 'root': dest = '/usr/local/bin'
         - if user is not 'root': dest = "~/.local/bin"

     Since a lot of 'single-binary'-applications come as a zipped (or otherwise archived) package, this frecklet also comes with an
     'extract' flag. If set, *freckles* will try to extract the downloaded artifact into a temporary folder, and then move the content(s)
     of the archive to the target 'dest'-ination (using the 'exe_name' value as a pattern matcher -- see below).

     Also, depending on whether 'exe_name' is provided and 'extract' is true or false, the behaviour of this *frecklet* slightly changes:

       - if no 'exe_name':
         - if 'extract' is false: full path to executable is "{{ dest }}/{{ basename of url }}"
         - if 'extract' is true: all content of the archive will be moved into "{{ dest }}"
       - if 'exe_name':
         - if 'extract' is false: full path to executable is "{{ dest }}/{{ exe_name }}"
         - if 'extract' is true: '
           - if not 'extract_subfolder': 'exe_name' will be treated as glob, and all files matching that glob will be moved into "{{ dest }}"
           - if 'extract_subfolder', 'exe_name' will be treated as glob, and all files in 'extract_subfolder' matching that glob will be moved into "{{ dest }}"

       Args:
         dest: The (absolute) path to the parent folder of the downloaded executable file.
         exe_mode: The mode for the executable file(s) (default: '0755').
         exe_name: A (matcher) glob to determine which files to copy to destination (in case of 'extract'), or the target file name (defaults to either '*' or 'url | basename'.
         extract: Whether the downloaded file is an archive and needs to be extracted.
         extract_subfolder: Base part where to start looking for the exe_name patter.
         force: Force overwrite executable if it already exists.
         group: The group of the executable.
         owner: The owner of the executable.
         url: The url to download (can be templated).

    """

    FRECKLET_ID = "executable-downloaded"

    dest: str = None
    exe_mode: str = None
    exe_name: str = None
    extract: bool = None
    extract_subfolder: str = None
    force: bool = None
    group: str = None
    owner: str = None
    url: str = None


    def __post_init__(self):
        super(ExecutableDownloaded, self).__init__(var_names=["dest", "exe_mode", "exe_name", "extract", "extract_subfolder", "force", "group", "owner", "url"])


frecklet_class = ExecutableDownloaded
# -*- coding: utf-8 -*-


#
# module path: pycklets.executable_downloaded.ExecutableDownloaded
#


from pyckles import AutoPycklet

class ExecutableDownloaded(AutoPycklet):
    """Download a binary, (optionally) extract it, make it executable.

     This frecklet tries to be as generically useful as possible for the situation where there is a single-file binary.

     It comes with a few defaults, which are dependent on the user that was chosen as the owner and the value for 'dest' that was specified:

       - if no user:
         - if localhost target: user that executes the frecklet is used
         - if non-localhost target: login user for target is used

       - no dest:
         - if user == 'root': dest = '/usr/local/bin'
         - if user is not 'root': dest = "~/.local/bin"

     Since a lot of 'single-binary'-applications come as a zipped (or otherwise archived) package, this frecklet also comes with an
     'extract' flag. If set, *freckles* will try to extract the downloaded artifact into a temporary folder, and then move the content(s)
     of the archive to the target 'dest'-ination (using the 'exe_name' value as a pattern matcher -- see below).

     Also, depending on whether 'exe_name' is provided and 'extract' is true or false, the behaviour of this *frecklet* slightly changes:

       - if no 'exe_name':
         - if 'extract' is false: full path to executable is "{{ dest }}/{{ basename of url }}"
         - if 'extract' is true: all content of the archive will be moved into "{{ dest }}"
       - if 'exe_name':
         - if 'extract' is false: full path to executable is "{{ dest }}/{{ exe_name }}"
         - if 'extract' is true: '
           - if not 'extract_subfolder': 'exe_name' will be treated as glob, and all files matching that glob will be moved into "{{ dest }}"
           - if 'extract_subfolder', 'exe_name' will be treated as glob, and all files in 'extract_subfolder' matching that glob will be moved into "{{ dest }}"

       Args:
         dest: The (absolute) path to the parent folder of the downloaded executable file.
         exe_mode: The mode for the executable file(s) (default: '0755').
         exe_name: A (matcher) glob to determine which files to copy to destination (in case of 'extract'), or the target file name (defaults to either '*' or 'url | basename'.
         extract: Whether the downloaded file is an archive and needs to be extracted.
         extract_subfolder: Base part where to start looking for the exe_name patter.
         force: Force overwrite executable if it already exists.
         group: The group of the executable.
         owner: The owner of the executable.
         url: The url to download (can be templated).

    """

    FRECKLET_ID = "executable-downloaded"

    def __init__(self, dest=None, exe_mode="0755", exe_name=None, extract=None, extract_subfolder=None, force=None, group=None, owner=None, url=None):

        super(ExecutableDownloaded, self).__init__(var_names=["dest", "exe_mode", "exe_name", "extract", "extract_subfolder", "force", "group", "owner", "url"])
        self._dest = dest
        self._exe_mode = exe_mode
        self._exe_name = exe_name
        self._extract = extract
        self._extract_subfolder = extract_subfolder
        self._force = force
        self._group = group
        self._owner = owner
        self._url = url

    @property
    def dest(self):
        return self._dest

    @dest.setter
    def dest(self, dest):
        self._dest = dest

    @property
    def exe_mode(self):
        return self._exe_mode

    @exe_mode.setter
    def exe_mode(self, exe_mode):
        self._exe_mode = exe_mode

    @property
    def exe_name(self):
        return self._exe_name

    @exe_name.setter
    def exe_name(self, exe_name):
        self._exe_name = exe_name

    @property
    def extract(self):
        return self._extract

    @extract.setter
    def extract(self, extract):
        self._extract = extract

    @property
    def extract_subfolder(self):
        return self._extract_subfolder

    @extract_subfolder.setter
    def extract_subfolder(self, extract_subfolder):
        self._extract_subfolder = extract_subfolder

    @property
    def force(self):
        return self._force

    @force.setter
    def force(self, force):
        self._force = force

    @property
    def group(self):
        return self._group

    @group.setter
    def group(self, group):
        self._group = group

    @property
    def owner(self):
        return self._owner

    @owner.setter
    def owner(self, owner):
        self._owner = owner

    @property
    def url(self):
        return self._url

    @url.setter
    def url(self, url):
        self._url = url



frecklet_class = ExecutableDownloaded