-
Notifications
You must be signed in to change notification settings - Fork 463
/
background_installer.sh
executable file
·461 lines (404 loc) · 13.2 KB
/
background_installer.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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
#!/bin/bash
OPENPLC_DIR="$(dirname $(readlink -f $0))"
SWAP_FILE="$OPENPLC_DIR/swapfile"
WIRINGPI_VERSION="3.4"
VENV_DIR="$OPENPLC_DIR/.venv"
function print_help_and_exit {
echo ""
echo "Error: You must provide a platform name as argument"
echo ""
echo "Usage: ./install.sh [platform] where [platform] can be"
echo " win Install OpenPLC on Windows over Cygwin"
echo " linux Install OpenPLC on a Debian-based Linux distribution"
echo " docker Install OpenPLC in a Docker container"
echo " rpi Install OpenPLC on a Raspberry Pi"
echo " opi Install OpenPLC on a Orange Pi"
echo " neuron Install OpenPLC on a UniPi Neuron PLC"
echo " unipi Install OpenPLC on a Raspberry Pi with UniPi v1.1 PLC"
echo " custom Skip all specific package installation and tries to install"
echo " OpenPLC assuming your system already has all dependencies met."
echo " This option can be useful if you're trying to install OpenPLC"
echo " on an unsuported Linux platform or had manually installed"
echo " all the dependency packages before."
echo ""
exit 1
}
[ $# -eq 0 ] && print_help_and_exit
function fail {
echo "$*"
echo "OpenPLC was NOT installed!"
exit 1
}
#set -x
# arg1: sudo or blank
function linux_install_deps {
if [ -x /bin/yum ]; then
yum clean expire-cache
yum check-update
$1 yum -q -y install curl make automake gcc gcc-c++ kernel-devel pkg-config bison flex autoconf libtool openssl-devel cmake python3
#Installing dependencies for Ubuntu/Mint/Debian
elif [ -x /usr/bin/apt-get ]; then
$1 apt-get update
$1 apt-get install -y build-essential pkg-config bison flex autoconf \
automake libtool make git \
sqlite3 cmake curl python3 python3-venv
#Installing dependencies for opensuse tumbleweed
elif [ -x /usr/bin/zypper ]; then
$1 zypper ref
$1 zypper in -y curl make automake gcc gcc-c++ kernel-devel pkg-config bison flex autoconf libtool openssl-devel cmake libmodbus-devel
$1 zypper in -y python python-xml python3 python3-pip
#Installing dependencies for Alpine Linux 3.20 and later
elif command -v apk >/dev/null; then
$1 apk update
$1 apk add build-base pkgconfig bison flex autoconf automake libtool make git sqlite cmake curl
$1 apk add python3 py3-libxml2 py3-pip gcc g++ linux-headers openssl-dev util-linux-misc
else
fail "Unsupported linux distro."
fi
}
function install_wiringpi {
echo "[WIRINGPI]"
echo "Trying distribution package..."
sudo apt-get install -y wiringpi && return 0
echo "Falling back to direct download..."
local FILE="wiringpi_${WIRINGPI_VERSION}_arm64.deb"
local URL="https://github.com/WiringPi/WiringPi/releases/download/$WIRINGPI_VERSION/$FILE"
(
set -e
wget -c -O "$OPENPLC_DIR/$FILE" "$URL"
sudo dpkg -i "$OPENPLC_DIR/$FILE"
sudo apt install -f
rm -f "$OPENPLC_DIR/$FILE"
) || fail "Failed to install wiringpi."
}
function install_pigpio {
echo "[PIGPIO]"
echo "Trying distribution package..."
sudo apt-get install -y pigpio && return 0
echo "Falling back to direct download..."
local URL="https://github.com/joan2937/pigpio/archive/master.zip"
(
set -e
wget -c "$URL"
unzip master.zip
cd pigpio-master
make
sudo make install
rm -f master.zip
)
}
function install_wiringop {
echo "[WIRINGOP]"
local URL="https://github.com/orangepi-xunlong/wiringOP/archive/master.zip"
(
set -e
rm -f master.zip
wget -c "$URL"
unzip -o master.zip
cd wiringOP-master
sudo ./build clean
sudo ./build
rm -f ../master.zip
)
}
function install_py_deps {
python3 -m venv "$VENV_DIR" --system-site-packages
source "$VENV_DIR/bin/activate"
"$VENV_DIR/bin/python3" -m pip install --upgrade pip
if [ "$1" == "neuron" ]; then
"$VENV_DIR/bin/python3" -m pip install flask==2.2.5 werkzeug==2.2.2 flask-login==0.6.2 pyserial pymodbus==2.5.3
else
"$VENV_DIR/bin/python3" -m pip install flask==2.3.3 werkzeug==2.3.7 flask-login==0.6.2 pyserial pymodbus==2.5.3
fi
python3 -m pip install pymodbus==2.5.3
deactivate
}
function swap_on {
echo "creating swapfile..."
# Fallocate is instantaneous. Only use dd as fallback.
$1 touch "$SWAP_FILE"
$1 fallocate -zl 1G "$SWAP_FILE" ||
$1 dd if=/dev/zero of="$SWAP_FILE" bs=1M count=1000
$1 mkswap "$SWAP_FILE"
$1 swapon "$SWAP_FILE"
}
function swap_off {
echo "removing swapfile..."
$1 swapoff "$SWAP_FILE"
$1 rm -f "$SWAP_FILE"
}
function install_matiec {
echo "[MATIEC COMPILER]"
cd "$OPENPLC_DIR/utils/matiec_src"
autoreconf -i
./configure
make
cp ./iec2c "$OPENPLC_DIR/webserver/" || fail "Error compiling MatIEC"
cd "$OPENPLC_DIR"
}
function install_st_optimizer {
echo "[ST OPTIMIZER]"
cd "$OPENPLC_DIR/utils/st_optimizer_src"
g++ st_optimizer.cpp -o "$OPENPLC_DIR/webserver/st_optimizer" || fail "Error compiling ST Optimizer"
cd "$OPENPLC_DIR"
}
function install_glue_generator {
echo "[GLUE GENERATOR]"
cd "$OPENPLC_DIR/utils/glue_generator_src"
g++ -std=c++11 glue_generator.cpp -o "$OPENPLC_DIR/webserver/core/glue_generator" || fail "Error compiling Glue Generator"
cd "$OPENPLC_DIR"
}
function install_ethercat {
echo "[EtherCAT]"
cd "$OPENPLC_DIR/utils/ethercat_src"
./install.sh || fail "Error compiling EtherCAT"
echo ethercat > "$OPENPLC_DIR/webserver/scripts/ethercat"
cd "$OPENPLC_DIR"
}
function disable_ethercat {
echo "" > "$OPENPLC_DIR/webserver/scripts/ethercat"
}
function install_opendnp3 {
echo "[OPEN DNP3]"
cd "$OPENPLC_DIR/utils/dnp3_src"
swap_on "$1"
cmake .
make
$1 make install || fail "Error installing OpenDNP3"
$1 ldconfig
swap_off "$1"
cd "$OPENPLC_DIR"
}
function disable_opendnp3 {
echo ""
echo "[OPEN DNP3]"
cd "$OPENPLC_DIR/webserver/core"
if test -f dnp3.cpp; then
mv dnp3.cpp dnp3.disabled || fail "Error disabling OpenDNP3"
fi
if test -f dnp3_dummy.disabled; then
mv dnp3_dummy.disabled dnp3_dummy.cpp || fail "Error disabling OpenDNP3"
fi
cd "$OPENPLC_DIR"
}
function install_libmodbus {
echo "[LIBMODBUS]"
cd "$OPENPLC_DIR/utils/libmodbus_src"
./autogen.sh
./configure
$1 make install || fail "Error installing Libmodbus"
$1 ldconfig
cd "$OPENPLC_DIR"
# Fix for RPM-based distros
if [ -x /bin/yum ]; then
sudo cp /usr/local/lib/pkgconfig/libmodbus.pc /usr/share/pkgconfig/
sudo cp /usr/local/lib/lib*.* /lib64/
fi
}
function install_systemd_service() {
if [ "$1" == "sudo" ]; then
echo "[OPENPLC SERVICE]"
$1 tee /lib/systemd/system/openplc.service > /dev/null <<EOF
[Unit]
Description=OpenPLC Service
After=network.target
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
Group=root
WorkingDirectory=$OPENPLC_DIR
ExecStart=$OPENPLC_DIR/start_openplc.sh
[Install]
WantedBy=multi-user.target
EOF
echo "Enabling OpenPLC Service..."
$1 systemctl daemon-reload
$1 systemctl enable openplc
fi
}
function install_openrc_service() {
if [ "$(whoami)" == "root" ]; then
echo "[OPENPLC SERVICE]"
tee /etc/init.d/openplc > /dev/null <<EOF
#!/sbin/openrc-run
name="OpenPLC"
description="OpenPLC Service"
command="$OPENPLC_DIR/start_openplc.sh"
pidfile="/run/\${RC_SVCNAME}.pid"
depend() {
need net
}
start() {
ebegin "Starting OpenPLC"
start-stop-daemon --start --exec \${command} \
--background --make-pidfile --pidfile \${pidfile}
eend $?
}
stop() {
ebegin "Stopping OpenPLC"
start-stop-daemon --stop --pidfile \${pidfile}
eend $?
}
EOF
echo "Setting permissions and enabling OpenPLC Service..."
chmod 755 /etc/init.d/openplc
rc-update add openplc default
fi
}
function install_all_libs {
install_matiec "$1"
install_st_optimizer "$1"
install_glue_generator "$1"
install_opendnp3 "$1"
disable_ethercat "$1"
install_libmodbus "$1"
}
function finalize_install {
echo "[FINALIZING]"
cd "$OPENPLC_DIR/webserver/scripts"
if [ "$1" == "win" ]; then
./change_hardware_layer.sh blank
else
./change_hardware_layer.sh blank_linux
fi
./compile_program.sh blank_program.st
cat > "$OPENPLC_DIR/start_openplc.sh" <<EOF
#!/bin/bash
if [ -d "/docker_persistent" ]; then
mkdir -p /docker_persistent/st_files
cp -n /workdir/webserver/dnp3_default.cfg /docker_persistent/dnp3.cfg
cp -n /workdir/webserver/openplc_default.db /docker_persistent/openplc.db
cp -n /workdir/webserver/st_files_default/* /docker_persistent/st_files/
cp -n /dev/null /docker_persistent/persistent.file
cp -n /dev/null /docker_persistent/mbconfig.cfg
fi
cd "$OPENPLC_DIR/webserver"
"$OPENPLC_DIR/.venv/bin/python3" webserver.py
EOF
chmod a+x "$OPENPLC_DIR/start_openplc.sh"
cd "$OPENPLC_DIR"
}
if [ "$1" == "win" ]; then
echo "Installing OpenPLC on Windows"
cp ./utils/apt-cyg/apt-cyg ./
install apt-cyg /bin
apt-cyg update
apt-cyg install lynx
apt-cyg install gcc-core gcc-g++ git pkg-config automake autoconf libtool make sqlite3 python3
lynx -source https://bootstrap.pypa.io/pip/get-pip.py > get-pip3.py
#Setting up venv
python3 -m venv "$VENV_DIR"
"$VENV_DIR/bin/python3" get-pip3.py
"$VENV_DIR/bin/python3" -m pip install flask==2.3.3 werkzeug==2.3.7 flask-login==0.6.2 pyserial pymodbus==2.5.3
echo ""
echo "[MATIEC COMPILER]"
cp ./utils/matiec_src/bin_win32/*.* ./webserver/
if [ $? -ne 0 ]; then
echo "Error compiling MatIEC"
echo "OpenPLC was NOT installed!"
exit 1
fi
install_st_optimizer
install_glue_generator
disable_opendnp3
install_libmodbus
finalize_install win
elif [ "$1" == "win_msys2" ]; then
echo "Installing OpenPLC on Windows"
pacman -Suy --noconfirm
pacman -S gcc git pkg-config automake autoconf libtool make sqlite3 python3 lynx --noconfirm
lynx -source https://bootstrap.pypa.io/pip/get-pip.py > get-pip3.py
#Setting up venv
python3 -m venv "$VENV_DIR"
"$VENV_DIR/bin/python3" get-pip3.py
"$VENV_DIR/bin/python3" -m pip install flask==2.3.3 werkzeug==2.3.7 flask-login==0.6.2 pyserial pymodbus==2.5.3
echo ""
echo "[MATIEC COMPILER]"
cp ./utils/matiec_src/bin_win32/*.* ./webserver/
if [ $? -ne 0 ]; then
echo "Error compiling MatIEC"
echo "OpenPLC was NOT installed!"
exit 1
fi
install_st_optimizer
install_glue_generator
disable_opendnp3
install_libmodbus
cp /usr/include/modbus/*.h /usr/include/
finalize_install win
elif [ "$1" == "linux" ]; then
echo "Installing OpenPLC on Linux"
sudo="sudo"
test -x /sbin/openrc-run && unset sudo # we are probably running on a system with openrc (Alpine, Gentoo, devuan)
linux_install_deps ${sudo}
install_py_deps
install_all_libs ${sudo}
[ "$2" == "ethercat" ] && install_ethercat
if [ -x /sbin/openrc-run ]; then # we are probably running on a system with openrc (Alpine, Gentoo, devuan)
install_openrc_service
else # we now assume a system with systemd
install_systemd_service ${sudo}
fi
finalize_install linux
elif [ "$1" == "docker" ]; then
echo "Installing OpenPLC on Linux inside Docker"
linux_install_deps
install_py_deps
install_all_libs
# Create persistent folder for docker
if [[ ! -d "/docker_persistent" ]]
then
mkdir /docker_persistent
fi
finalize_install linux
elif [ "$1" == "rpi" ]; then
echo "Installing OpenPLC on Raspberry Pi"
linux_install_deps sudo
install_pigpio
install_py_deps
install_all_libs sudo
install_systemd_service sudo
finalize_install linux
elif [ "$1" == "opi" ]; then
echo "Installing OpenPLC on Orange Pi"
linux_install_deps sudo
install_wiringop
install_py_deps
install_all_libs sudo
install_systemd_service sudo
finalize_install linux
elif [ "$1" == "neuron" ]; then
echo "Installing OpenPLC on UniPi Neuron PLC"
echo ""
echo "[DISABLING UNIPI SERVICES]"
sudo systemctl stop neuronhost.service
sudo systemctl disable neuronhost.service
sudo systemctl stop neurontcp.service
sudo systemctl disable neurontcp.service
sudo systemctl stop evok.service
sudo systemctl disable evok.service
sudo systemctl stop unipitcp.service
sudo systemctl disable unipitcp.service
linux_install_deps sudo
install_py_deps neuron
install_all_libs sudo
install_systemd_service sudo
finalize_install linux
elif [ "$1" == "unipi" ]; then
echo "Installing OpenPLC on Raspberry Pi with UniPi v1.1 PLC"
linux_install_deps sudo
install_wiringpi
install_py_deps
install_all_libs sudo
install_systemd_service sudo
finalize_install linux
elif [ "$1" == "custom" ]; then
echo "Installing OpenPLC on Custom Platform"
install_all_libs
install_systemd_service sudo
finalize_install linux
else
print_help_and_exit
fi