-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.py
164 lines (137 loc) · 4.39 KB
/
build.py
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env python
"""Build Splunk app package"""
import tarfile
from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
from configparser import ConfigParser
from os import getcwd, path
from pathlib import Path, PurePath
from posixpath import join as posixjoin
from re import search
from subprocess import check_call
from sys import executable
APPS_WITH_CERT = ("1-deploymentserver", "1-indexserver", "100_splunkcloud")
def get_version(dir_path: Path) -> str:
"""Return version number from app.conf"""
app_conf_path = path.join(
dir_path,
"default",
"app.conf",
)
app_conf = ConfigParser()
app_conf.read(app_conf_path)
launcher = app_conf["launcher"] if "launcher" in app_conf.sections() else {}
version = launcher.get("version", "")
return f"-{version}" if len(version) >= 1 else ""
def exclusion(tarinfo: tarfile.TarInfo) -> tarfile.TarInfo | None:
"""Exclude dev files and cache, and reset file/folder permission"""
# exclude certain folders/files
name = tarinfo.name
pathname = PurePath(name)
if search(
r"/\.|\\\.|__pycache__|pyproject\.toml|requirements",
name,
) or (len(pathname.parts) == 2 and tarinfo.isfile() and pathname.suffix != ".md"):
return None
app = pathname.parts[0]
# reset file stats
tarinfo.uid = 0
tarinfo.gid = 0
tarinfo.uname = tarinfo.gname = ""
if tarinfo.isfile():
# remove execution permission
tarinfo.mode = 0o644
# except for scripts
# tarinfo uses posix (not nt)
if name.startswith(posixjoin(app, "bin")) and pathname.suffix in (
".sh",
".ps1",
".cmd",
".bat",
".py",
):
tarinfo.mode = 0o744
if tarinfo.isdir():
# remove write permission from group & world
tarinfo.mode = 0o755
return tarinfo
def find_ca_cert(dir_arg: Path) -> Path | str:
"""Locate ca-certificates.crt in parent folder of app folder"""
for i in range(2):
cert_path = dir_arg.absolute().parents[i].joinpath("ca-certificates.crt")
if cert_path.is_file():
return cert_path
return ""
def main(
directory: Path | str = getcwd(),
output: Path | str = getcwd(),
splunk_sdk: bool = False,
) -> Path:
"""
:param directory: Path to Splunk app
:param output: Output folder
:param splunk_sdk: Install splunk-sdk library
"""
directory = Path(directory)
app_name = directory.name
output_dir = Path(output)
if not output_dir.is_dir():
output_dir.mkdir(mode=0o755, parents=True)
pkg_file = f"{app_name}{get_version(directory)}.tar.gz"
output_gz = output_dir.joinpath(pkg_file)
if splunk_sdk is True:
lib_path = path.join(directory, "lib")
print(f'Installing splunk-sdk into "{lib_path}"...')
check_call(
[
executable,
"-m",
"pip",
"install",
"--quiet",
"splunk-sdk == 2.*",
"-t",
lib_path,
"--upgrade",
]
)
with tarfile.open(output_gz, "w:gz") as tar:
# arcname: rename directory to app_name
tar.add(directory, arcname=app_name, filter=exclusion)
# only certain apps need ca-certificates.crt
ca_cert = find_ca_cert(directory)
if app_name in APPS_WITH_CERT and len(ca_cert) >= 1:
tar.add(
ca_cert,
arcname=path.join(app_name, "local", "ca-certificates.crt"),
filter=exclusion,
)
print(f"Created {output_gz.absolute()}")
return output_gz.absolute()
if __name__ == "__main__":
cwd_default = getcwd()
parser = ArgumentParser(
description="Create Splunk app package.",
formatter_class=ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"--directory",
"-d",
help="Path to Splunk app.",
default=cwd_default,
type=Path,
)
parser.add_argument(
"--output",
"-o",
help="Output folder. Automatically create one if not found.",
default=cwd_default,
type=Path,
)
parser.add_argument(
"--splunk-sdk",
"-s",
help="Install splunk-sdk library",
type="store_true",
)
args = parser.parse_args()
main(**vars(args))