-
Notifications
You must be signed in to change notification settings - Fork 19
/
build-charm
executable file
·147 lines (127 loc) · 4.83 KB
/
build-charm
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
#!/bin/bash -e
# Build a src charm or layer from a local checkout/clone directory.
#
# Some layer components may be blocked by egress firewalls. It may
# be necessary to use an http_proxy (set env var beforehand if so).
charm_dir="$1"
charm_name="$2"
usage="usage: build-charm <charm checkout dir> <charm name>
ex:
./build-charm /path/to/git/clone/of/charm-tempest tempest
If <charm name> is not provided, attempt to detect and set
it from the charm checkout dir.
"
required_files="config.yaml copyright README.md metadata.yaml"
function build_charm () {
local charm_dir="${1}"
local charm_name="${2}"
# Build via tox
if grep "^\[testenv:build\]$" $charm_dir/tox.ini &> /dev/null; then
echo " . Building $charm_dir ($charm_name) via tox"
local DIR="$(pwd)"
cd $charm_dir
# Let us retry a couple of times in case of a transient failure fetching bits
n=0
until [ $n -ge 3 ]
do
tox -e build && break
n=$[$n+1]
sleep 3
done
cd $DIR
else
echo " . No tox build target in $charm_dir ($charm_name). The charm should support 'tox -e build'!"
exit 1
fi
}
function set_charm_name () {
local charm_dir="${1}"
# Attempt to learn the charm/asset name from the metadata.yaml if not specified
# as a parameter, then from the charm dir if not specified in metadata.yaml.
if [[ -z "$_charm_name" ]]; then
# Prefer name from metadata yaml
charm_name="$(grep "^name:" $charm_dir/src/metadata.yaml | awk '{ print $2 }')"
[[ -z "$charm_name" ]] && charm_name="$(grep "^name:" $charm_dir/metadata.yaml | awk '{ print $2 }')"
# /path/to/charm-foo yields foo
[[ -z "$charm_name" ]] && charm_name="$(echo "$charm_dir" | sed -n -e 's/^.*charm-//p')"
# /path/to/charm-foo yields charm-foo
[[ -z "$charm_name" ]] && charm_name="${charm_dir##*/}"
# /path/to/charm-foo yields /path/to/charm-foo
[[ -z "$charm_name" ]] && charm_name="$charm_dir"
echo " + Autodetected charm name as: $charm_name"
else
echo " + Using specified charm name: $charm_name"
fi
}
function set_charm_type () {
local charm_dir="${1}"
local charm_name="${2}"
# Get charm type and perform very basic pre-flight checks
if [[ -f "$charm_dir/layer.yaml" ]] ||\
[[ -f "$charm_dir/src/layer.yaml" ]]; then
charm_type='REACTIVE'
elif [[ -f "$charm_dir/src/charm.py" ]]; then
charm_type='OPERATOR'
fi
if [[ -z $charm_type ]]; then
echo " ! $charm_name is of unknown type"
exit 1
fi
}
function validate_build_charm_o () {
local charm_dir="${1}"
local charm_name="${2}"
local required_files="${3}"
BUILT_ASSET_FILE="${charm_dir}/${charm_name}.charm"
[[ -f $BUILT_ASSET_FILE ]] || { echo "Cannot find charm archive file"; exit 1; }
for file in $required_files; do
unzip -l $BUILT_ASSET_FILE $file || { echo "$file missing from build charm"; exit 1; }
done
}
function validate_build_charm_r () {
local charm_dir="${1}"
local charm_name="${2}"
local required_files="${3}"
# NOTE(ajkavanagh): starting with charm-tools>=2.8 the default behaviour of
# the charm build '-d' option has changed, in that in no longer appends
# 'builds' to the directory. However, as we need to support both stable
# (charm-tools < 2.8) and master (charm-tools >=2.8), the tox for master now
# forces the build into the same ./build/builds/ directory.
# This note can be reviewed in the post 21.04 cycle.
if grep '^\"\?series\"\?:$' $charm_dir/src/metadata.yaml &> /dev/null; then
echo " . $charm_dir is a multi-series charm based on its metadata.yaml"
EXPECTED_BUILD_DIR="$charm_dir/build/builds/$charm_name"
else
echo "WARN: $charm_dir does not declare series in metadata. Multi-series metadata is enforced on push/release."
EXPECTED_BUILD_DIR="$charm_dir/build/trusty/$charm_name"
fi
# OSCI automation relies on this env var being set after build.
export BUILT_ASSET_DIR="$(readlink -f $EXPECTED_BUILD_DIR)"
# Very basic validation of the built artifact.
if [[ -d "$charm_dir/src" ]]; then
# Expect files to exist in all built src charms. These may or may not
# exist in layer test builds.
for file in $required_files; do
[[ -f "$BUILT_ASSET_DIR/$file" ]] || { echo "$file missing from build charm"; exit 1; }
done
fi
if [[ ! -f "$BUILT_ASSET_DIR/.build.manifest" ]]; then
echo " ! Unable to confirm the built artifact in: $BUILT_ASSET_DIR"
exit 1
fi
}
if [[ ! -d "$charm_dir" ]]; then
echo "$usage"
echo " ! charm_dir ($charm_dir) not found"
exit 1
fi
set_charm_name $charm_dir
set_charm_type $charm_dir $charm_name
build_charm $charm_dir $charm_name
if [[ $charm_type == 'REACTIVE' ]]; then
validate_build_charm_r $charm_dir $charm_name "$required_files"
echo " . Built asset dir: $BUILT_ASSET_DIR"
else
validate_build_charm_o $charm_dir $charm_name "$required_files"
echo " . Built asset file: $BUILT_ASSET_FILE"
fi