-
Notifications
You must be signed in to change notification settings - Fork 1
/
support-pack.sh
executable file
·244 lines (212 loc) · 5.99 KB
/
support-pack.sh
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#!/bin/sh
#
# Copyright (C) 2021-present Savoir-faire Linux Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
VERSION="0.1.0"
# Default configuration file
SUPPORT_PACK_CONF='/etc/support-pack/support-pack.conf'
TSTAMP=$(date +%Y%m%d-%H%M%S)
# Name of the working directory that will contain all support log files.
WORKDIR="/tmp/support-pack-${TSTAMP}"
# Name of the archive that will be created.
ARCHIVE="/tmp/support-pack-${TSTAMP}.tar.gz"
# This file is in the support-pack and contains a report of the execution of
# support-pack itself.
LOGFILE="support-pack.txt"
die()
{
echo "$*" 1>&2
exit 1
}
support_info()
{
echo "[INFO ] $*" 1>&2
}
support_error()
{
echo "[ERROR] $*" 1>&2
}
# Silently check if a command is available.
# arg1: The command to check availability.
#
support_cmd_available()
{
type "$1" > /dev/null 2>&1
return $?
}
# Execute a command while adding the support-pack boilerplate.
#
# When wrapping a command with support_cmd,
# * stdout remains unchanged
# * stderr is captured in the support-pack log if the command returns a non-zero
# code. Otherwise, stderr is discarded.
#
# arg1: the command to run
#
# example:
# support_cmd ps | support_log_file process.txt
#
support_cmd()
{
local ret
if ! support_cmd_available "$1"; then
support_error "Command \"$1\" is not available"
return
fi
echo "[SUPPORT-PACK] >>>> $*"
support_info "Exec command \"$*\""
local errfile=$(mktemp)
# TERM is vt100 to avoid most color/control chars in generated text files.
TERM=vt100 "$@" 2>"${errfile}"
ret=$?
if [ "${ret}" != "0" ]; then
support_error "\"$*\" returned a non-zero error code: ${ret}"
cat "${errfile}" | sed 's/^/\t-> /' 1>&2
fi
rm -f "${errfile}"
echo
}
# Redirect stdin to a support-pack file. If the file does not contain at least 1
# byte, it is omitted from the support-pack archive.
# arg1: name of the file.
#
# examples:
# support_cmd echo "Hello, World!" | support_log_file dummy.txt
#
support_log_file()
{
local tmpfile=$(mktemp)
cat >>"${tmpfile}"
# "-s" is FILE exists and has a size greater than zero
if [ -s "${tmpfile}" ]; then
mv -f "${tmpfile}" "$WORKDIR/$1"
support_info "Created file \"$1\""
else
rm -f "${tmpfile}"
support_error "\"$1\" was omitted because it is empty"
fi
}
# Copy a file to the support-pack.
# arg1: Source file.
# arg2: (optional) Name of the destination file in the support-pack. The name is
# relative to the root of the support-pack.
# If missing, use same name as source file.
support_copy_file()
{
if [ ! -f "$1" ]; then
support_error "$1 doesn't exist or is not a regular file."
return
fi
local dst="$2"
if [ -z "$dst" ]; then
dst="$(basename "${1}")"
fi
support_info "Copying \"$1\" to \"${dst}\""
mkdir -p "$(dirname "${WORKDIR}/${dst}")"
cp "${1}" "${WORKDIR}/${dst}"
}
# Copy a directory to the support-pack.
# arg1: Source directory.
# arg2: (optional) Name of the destination directory in the support-pack.
# The name is relative to the root of the support-pack.
# If missing, use same name as source file.
support_copy_dir()
{
if [ ! -d "$1" ]; then
support_error "$1 doesn't exist or is not a directory."
return
fi
local dst="$2"
if [ -z "$dst" ]; then
dst=$(basename "${1}")
fi
support_info "Copying \"${1}\" to \"${dst}\""
mkdir -p "$(dirname "${WORKDIR}/${dst}")"
cp -r -L "${1}" "${WORKDIR}/${dst}"
}
usage()
{
cat <<EOF
Usage: $PROGNAME [OPTION] [CONFIG_FILE]
If [CONFIG_FILE] is specified, it is the configuration file used.
Otherwise, "${SUPPORT_PACK_CONF}" is used.
Options:
-o <output> Change destination path of the .tar.gz archive.
-v or --version Show version.
-h or --help Show this help text.
--notgz Skip tar file creation
EOF
}
while [ $# -gt 0 ]; do
case "$1" in
help|-h|"--help")
usage
exit 0
;;
version|-v|"--version")
echo $VERSION
exit 0
;;
-o)
ARCHIVE=${2}
shift
;;
--notgz)
NOTGZ="1"
;;
-*)
die "Unsupported flag: ${1}"
;;
*)
# Take config file as argument
if [ -r "$1" ]; then
SUPPORT_PACK_CONF="$(readlink -f "$1")"
fi
;;
esac
shift
done
main()
{
# Ensure cleanup of temporary files
trap support_pack_cleanup EXIT
# Cleanup anything left from the last execution of support-pack.
rm -rf /tmp/support-pack-*
# Create the working directory.
mkdir -p "${WORKDIR}"
# Run the support-pack config.
# All stdout from the config file should be piped to a support-pack file, so
# it's ok to ignore any remaining output.
. "$SUPPORT_PACK_CONF" 2>&1 | tee -a "${WORKDIR}/${LOGFILE}" 1>&2
# Tar the file.
if [ -z "${NOTGZ}" ]; then
support_info "Archiving files.."
tar -C "/tmp" -cf - support-pack-${TSTAMP} | gzip -9c > "${ARCHIVE}" ||
die "Fatal: Fail to create ${ARCHIVE}"
local size=$(du -h ${ARCHIVE} | cut -f1)
support_info "Archive \"${ARCHIVE}\" (${size}) has been created."
# Outputs the name of the archive created.
readlink -f "${ARCHIVE}"
else
# Outputs the name of the working directory.
readlink -f "${WORKDIR}"
fi
}
# Cleanup of temporary files
support_pack_cleanup()
{
rm -rf "${tmpfile}" "${errfile}"
}
main