forked from chr0n1x/ethos-systemd
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit
More file actions
executable file
·227 lines (185 loc) · 7.69 KB
/
Copy pathinit
File metadata and controls
executable file
·227 lines (185 loc) · 7.69 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
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
#!/usr/bin/bash -x
# BEGINNING BOOTSTRAP SCRIPT
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
VERSION="v1"
LEADER="false"
source /etc/environment || :
echo "-------Beginning Bootstrap Script: $VERSION-------"
if [[ $(/usr/bin/mount | grep xen) ]]; then sudo /usr/bin/umount /proc/xen; fi
sudo chown root:docker /var/run/docker.sock
# Setup profile.d
sudo mkdir /etc/profile.d || :
sudo cp ${SCRIPTDIR}/$VERSION/profile.d/* /etc/profile.d/. 2>/dev/null || :
sudo cp --dereference ${SCRIPTDIR}/$VERSION/profile.d/${NODE_ROLE}/* /etc/profile.d/.
source $SCRIPTDIR/$VERSION/lib/helpers.sh
# Control tier - must form an etcd2 cluster first
# Bastion tier - etcd2 cluster is separate from control, but also needs to be set up
if [[ "$NODE_ROLE" = "control" || "$NODE_ROLE" = "bastion" ]]; then
sudo ${SCRIPTDIR}/$VERSION/util/etcd2-setup.sh $SCRIPTDIR $VERSION
fi
# Worker tier - must run the IAM proxy setup before any other containers
if [[ "$NODE_ROLE" = "worker" && -f ${SCRIPTDIR}/$VERSION/util/iam-proxy.sh ]]; then
sudo ${SCRIPTDIR}/$VERSION/util/iam-proxy.sh $SCRIPTDIR $VERSION
fi
function leader-setup() {
echo "-------Leader node, beginning leader setup-------"
LEADER="true"
etcd-set /bootstrap.service/leader-status started
for script in $(ls ${SCRIPTDIR}/$VERSION/setup/leader|grep -e '.sh$')
do
sudo ${SCRIPTDIR}/$VERSION/setup/leader/${script}
done
echo "-------Leader node, writing finished flag to etcd-------"
etcd-set /bootstrap.service/leader-status finished
echo "-------Leader node, leader is finished, continuing bootstrap-------"
}
function follower-setup() {
# Wait until etcd bootstrap value is set
# This ensures that the etcd cluster is healthy and replicated on workers and proxy
while [[ $(/home/core/ethos-systemd/v1/lib/etcdauth.sh get /bootstrap.service/leader-status) != "finished" ]]
do
echo "-------Follower node, waiting for leader to finish script setup-------"
sleep 10
done
echo "-------Follower node, leader is finished, continuing bootstrap-------"
# Run the common scripts on all instances
for script in $(ls ${SCRIPTDIR}/$VERSION/setup/common|grep -e '.sh$')
do
sudo ${SCRIPTDIR}/$VERSION/setup/common/${script}
done
}
function bastion-setup() {
echo "-------Bastion node, beginning bastion setup-------"
LEADER="true"
etcd-set /bootstrap.service/leader-status started
for script in $(ls ${SCRIPTDIR}/$VERSION/setup/bastion|grep -e '.sh$')
do
sudo ${SCRIPTDIR}/$VERSION/setup/bastion/${script}
done
echo "-------Bastion node, writing finished flag to etcd-------"
etcd-set /bootstrap.service/leader-status finished
echo "-------Bastion node, bastion is finished, continuing bootstrap-------"
}
# Check the bootstrap process to see if this node should run the leader scripts
/home/core/ethos-systemd/v1/lib/etcdauth.sh get /bootstrap.service/leader-status
if [[ $? != 0 && ("$NODE_ROLE" = "control" || "$NODE_ROLE" = "bastion") ]]; then
# The election process follows the following algorithm:
# 1. A list of all cluster members is obtained
# 2. IP addresses of all members are filtered and sorted
# 3. The first IP in the sorted list becomes the leader
# 4. If the node's local IP matches, it begins running the leader scripts
# 5. Others continue to wait for it to complete
LEADER_IP=$(/home/core/ethos-systemd/v1/lib/etcdauth.sh member list | awk '{print $4}' | cut -d':' -f 2 | cut -c3- | sort | head -n1)
LOCAL_IP=$(curl -sS http://169.254.169.254/latest/meta-data/local-ipv4)
if [[ "$LEADER_IP" = "$LOCAL_IP" ]]; then
if [[ "$NODE_ROLE" = "control" ]]; then
leader-setup
elif [[ "$NODE_ROLE" = "bastion" ]]; then
bastion-setup
fi
fi
fi
# TODO: what happens if the elected leader dies?
# TODO: what happens during a reboot?
# Run the follower setup on all nodes (including leader)
follower-setup
# TODO: add a pause to wait for fleet to become healthy
function required-units() {
echo "-------Beginning REQUIRED fleet submissions needed by general, optional, and specific-units -------"
for unit in $(ls ${SCRIPTDIR}/$VERSION/fleet/required |grep -e '.service$\|.timer$') ; do
submit-fleet-unit ${SCRIPTDIR}/$VERSION/fleet/required/${unit}
start-fleet-unit ${SCRIPTDIR}/$VERSION/fleet/required/${unit}
done
}
function general-units() {
echo "-------Beginning general purpose fleet submissions-------"
for unit in $(ls ${SCRIPTDIR}/$VERSION/fleet|grep -e '.service$\|.timer$')
do
# skip control- prefixed units on non-control leader nodes (e.g., bastion)
if [[ $unit =~ ^control ]]; then
if [[ $NODE_ROLE = control ]]; then
submit-fleet-unit ${SCRIPTDIR}/$VERSION/fleet/${unit}
start-fleet-unit ${SCRIPTDIR}/$VERSION/fleet/${unit}
else
continue
fi
else
submit-fleet-unit ${SCRIPTDIR}/$VERSION/fleet/${unit}
start-fleet-unit ${SCRIPTDIR}/$VERSION/fleet/${unit}
fi
done
echo "-------Done general purpose fleet submissions-------"
}
function optional-units() {
# start services specified in $(etcdctl get /environment/services)
# mapped to the /opt directory of these scripts
echo "-------Beginning optional fleet submissions-------"
for service in $(etcd-get /environment/services)
do
servicedir=${SCRIPTDIR}/${VERSION}/opt/${service}/fleet
if [[ ! -d $servicedir ]]; then
continue
fi
for unit in $(ls $servicedir|grep -e '.service$\|.timer$')
do
# skip control units on non-control leader nodes (e.g., bastion)
if [[ $unit =~ control ]]; then
if [[ $NODE_ROLE = control ]]; then
submit-fleet-unit $servicedir/$unit
start-fleet-unit $unit
else
continue
fi
else
submit-fleet-unit $servicedir/$unit
start-fleet-unit $unit
fi
done
done
echo "-------Done optional fleet submissions-------"
}
function specific-units() {
# TODO: just submit all of these, for every tier, on the leader
echo "-------Beginning node-specific fleet submissions-------"
for unit in $(ls ${SCRIPTDIR}/$VERSION/fleet-local/${NODE_ROLE}|grep -e '.service$')
do
submit-fleet-unit ${SCRIPTDIR}/$VERSION/fleet-local/${NODE_ROLE}/${unit}
start-fleet-unit "${unit%.service}${COREOS_PRIVATE_IPV4}"
done
for envservice in $(etcd-get /environment/services)
do
servicedir=${SCRIPTDIR}/${VERSION}/opt/${envservice}/fleet-local/${NODE_ROLE}
if [[ ! -d $servicedir ]]; then
continue
fi
for unit in $(ls $servicedir|grep -e '.service$')
do
# skip control units on non-control leader nodes (e.g., bastion)
if [[ $unit =~ control ]]; then
if [[ $NODE_ROLE = control ]]; then
submit-fleet-unit $servicedir/$unit
start-fleet-unit "${unit%.service}${COREOS_PRIVATE_IPV4}"
else
continue
fi
else
submit-fleet-unit $servicedir/$unit
start-fleet-unit "${unit%.service}${COREOS_PRIVATE_IPV4}"
fi
done
done
echo "-------Done node-specific fleet submissions-------"
}
if [[ "$LEADER" = "true" ]]; then
required-units
optional-units
general-units
fi
specific-units
echo "-------Done bootstrap script-------"
# TODO:
# In util-units/update-scripts.service, the entire folder is deleted and re-cloned. Since leader already has "bootstrap finished" in etcd, it wont run again
# In util-units/update-scripts.service, the setup-credentials.sh file no longer exists
# Should we manually submit the core-os update service before everything else runs?
# Does the log rotator need to start early on
# Can we use an Environment="IMAGE=etcdctl get /images/gcron-logrotate" in the log rotate service? Not if we submit it early