-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.py
More file actions
147 lines (111 loc) · 4.16 KB
/
install.py
File metadata and controls
147 lines (111 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""Support for finding and installing the vault binary.
Use of this package requires that you have vault installed and
available. It is only a single binary, so not very hard to install,
but the package will be used in situations where we don't want to
think about this too much.
If the environment variable `$VAULT_DEV_BIN_PATH` is set, then this is
preferred (and if vault is not found here an error is thrown). This
can be the full path to the vault binary (include `.exe` on windows)
or to the directory in which `vault` or `vault.exe` is found.
If vault is present on `$PATH` we will use that.
We provide some support for downloading and installing vault, by
passing `install=True` to `ensure_installed()`.
If using GitHub actions, you can use an action
(e.g. `eLco/setup-vault`) to do this.
"""
import os
import platform
import shutil
import tempfile
import zipfile
from pathlib import Path
import requests
def vault_path(*, required: bool = True) -> Path | None:
"""Compute path to vault binary
Args:
required: Throw if vault is not found
Returns: The path to the vault binary, or `None` if not found, and
if `required` is `False`.
"""
if path := _find_vault_environ():
return path
if path := _find_vault_system():
return path
if required:
msg = "vault not found"
raise Exception(msg)
return None
def ensure_installed(*, install: bool = False) -> None:
"""Ensure that vault is installed.
Args:
install: Install vault if not found? If not already installed
and if `install` is `False`, this function will throw.
Returns:
Nothing, called for side effects only.
"""
path = vault_path(required=install)
if path:
print(f"Found vault at '{path}'")
if not path:
print("Did not find system vault, installing one for tests")
path = _vault_install_session()
print(f"Using vault at '{path}'")
def vault_download(dest: str | Path, version: str, platform: str) -> Path:
"""Download vault.
Args:
dest: Destination directory
version: The version to download
platform: The platform to download (`linux`, `windows` or `darwin`)
Returns: The full path to the downloaded binary.
"""
filename = _vault_exe_filename(platform)
dest_bin = Path(dest) / filename
if not dest_bin.exists():
print(f"installing vault to '{dest}'")
url = _vault_url(version, platform)
data = requests.get(url, timeout=600).content
with tempfile.TemporaryFile() as tmp:
tmp.write(data)
tmp.seek(0)
z = zipfile.ZipFile(tmp)
z.extract(filename, dest)
os.chmod(dest_bin, 0o755) # noqa S103
return dest_bin
def _find_vault_environ() -> Path | None:
path = os.environ.get("VAULT_DEV_BIN_PATH")
if not path:
return None
ret = Path(path)
if not ret.exists():
msg = "VAULT_DEV_BIN_PATH is set, but does not exist"
raise Exception(msg)
if ret.is_dir():
filename = _vault_exe_filename(_vault_platform())
ret = ret / filename
if not ret.exists():
msg = f"{filename} not found at {ret}, from VAULT_DEV_BIN_PATH"
raise Exception(msg)
return ret
def _find_vault_system() -> Path | None:
if path := shutil.which("vault"):
return Path(path)
else:
return None
def _vault_exe_filename(platform: str) -> str:
"""Filename for the vault binary.
Args:
platform: The platform `windows`, `linux` or `darwin`
Returns:
The name of the vault binary (either `vault.exe` or `vault`)
"""
return "vault.exe" if platform == "windows" else "vault"
def _vault_url(version: str, platform: str, arch: str = "amd64") -> str:
base = "https://releases.hashicorp.com/vault"
return f"{base}/{version}/vault_{version}_{platform}_{arch}.zip"
def _vault_platform() -> str:
return platform.system().lower()
def _vault_install_session() -> Path:
tmp = tempfile.TemporaryDirectory(delete=False)
path = vault_download(tmp.name, "1.0.0", _vault_platform())
os.environ["VAULT_DEV_BIN_PATH"] = str(path)
return path