-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathinstall.sh
executable file
·448 lines (397 loc) · 19 KB
/
install.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
#!/bin/bash
#
# OctoEverywhere for Klipper And Bambu Lab Printers!
#
# Use this script to install the OctoEverywhere plugin for:
# OctoEverywhere for Klipper - Where this device is running Moonraker.
# OctoEverywhere for Creality - Where this device is a Creality device (Sonic Pad, K1, etc)
# OctoEverywhere Companion Plugin - Where this plugin will connect to Moonraker running on a different device on the same LAN
# OctoEverywhere Bambu Connect - Where this plugin will connect to a Bambu printer running on the save LAN.
#
# For a device running Klipper locally, use no arguments.
# For a companion install, use the -companion argument.
# For a Bambu Connect install, use the -bambu argument.
#
# Simply run ./install.sh from the git repo root directory to get started!
#
# If you need help, feel free to contact us at support@octoeverywhere.com
#
#
# The responsibility of this script is to bootstrap the setup by installing the required system libs,
# virtual environment, and py requirements. The core of the setup logic is done by the PY install script.
#
# Set this to terminate on error.
# We don't do this anymore, because some commands return non-zero exit codes, but still are successful.
# set -e
#
# First things first, we need to detect what kind of OS we are running on. The script works by default with all
# Debian OSs, but some printers with embedded computers run strange embedded OSs, that have a lot of restrictions.
# These must stay in sync with update.sh and uninstall.sh!
#
# The K1 and K1 Max run an OS called Buildroot. We detect that by looking at the os-release file.
# Quick note about bash vars, to support all OSs, we use the most compilable var version. This means we use ints
# where 1 is true and 0 is false, and we use comparisons like this [[ $IS_K1_OS -eq 1 ]]
IS_K1_OS=0
if grep -Fqs "ID=buildroot" /etc/os-release
then
IS_K1_OS=1
# On the K1, we always want the path to be /usr/data
# /usr/share has very limited space, so we don't want to use it.
# This is also where the github script installs moonraker and everything.
HOME="/usr/data"
fi
# Next, we try to detect if this OS is the Sonic Pad OS.
# The Sonic Pad runs openwrt. We detect that by looking at the os-release file.
IS_SONIC_PAD_OS=0
if grep -Fqs "sonic" /etc/openwrt_release
then
IS_SONIC_PAD_OS=1
# On the K1, we always want the path to be /usr/share, this is where the rest of the klipper stuff is.
HOME="/usr/share"
fi
# Get the root path of the repo, aka, where this script is executing
OE_REPO_DIR=$(readlink -f $(dirname "$0"))
# This is the root of where our py virtual env will be. Note that all OctoEverywhere instances share this same
# virtual environment. This how the rest of the system is, where all other services, even with multiple instances, share the same
# virtual environment. I probably wouldn't have done it like this, but we have to create this before we know what instance we are targeting, so it's fine.
OE_ENV="${HOME}/octoeverywhere-env"
# Note that this is parsed by the update process to find and update required system packages on update!
# On update THIS SCRIPT ISN'T RAN, only this line is parsed out and used to install / update system packages.
# For python packages, the `requirements.txt` package is used on update.
# This var name MUST BE `PKGLIST`!!
#
# Note! This was deprecated in newer versions of moonraker, instead the deps are in the moonraker-system-dependencies.json file.
# For now we will keep both around AND IN SYNC so we can support older versions of moonraker.
#
# The python requirements are for the installer and plugin
# The virtualenv is for our virtual package env we create
# The curl requirement is for some things in this bootstrap script.
# python3-venv is required for teh virtualenv command to fully work.
# This must stay in sync with the dockerfile package installs
PKGLIST="python3 python3-pip virtualenv python3-venv curl"
# For the Creality OS, we only need to install these.
# We don't override the default name, since that's used by the Moonraker installer
# Note that we DON'T want to use the same name as above (not even in this comment) because some parsers might find it.
# Note we exclude virtualenv python3-venv curl because they can't be installed on the sonic pad via the package manager.
CREALITY_DEP_LIST="python3 python3-pip python3-pillow"
SONIC_PAD_DEP_LIST="python3 python3-pip"
#
# Console Write Helpers
#
c_default=$(echo -en "\e[39m")
c_green=$(echo -en "\e[92m")
c_yellow=$(echo -en "\e[93m")
c_magenta=$(echo -en "\e[35m")
c_red=$(echo -en "\e[91m")
c_cyan=$(echo -en "\e[96m")
log_header()
{
echo -e "${c_magenta}$1${c_default}"
}
log_important()
{
echo -e "${c_yellow}$1${c_default}"
}
log_error()
{
log_blank
echo -e "${c_red}$1${c_default}"
log_blank
}
log_info()
{
echo -e "${c_green}$1${c_default}"
}
log_blue()
{
echo -e "${c_cyan}$1${c_default}"
}
log_blank()
{
echo ""
}
#
# It's important for consistency that the repo root is in set $HOME for the K1 and Sonic Pad
# To enforce that, we will move the repo where it should be.
ensure_creality_os_right_repo_path()
{
# TODO - re-enable this for the || [[ $IS_K1_OS -eq 1 ]] after the github script updates.
if [[ $IS_SONIC_PAD_OS -eq 1 ]]
then
# Due to the K1 shell, we have to use grep rather than any bash string contains syntax.
if echo $OE_REPO_DIR |grep "$HOME" - > /dev/null
then
return
else
log_info "Current path $OE_REPO_DIR"
log_error "For the Creality devices the OctoEverywhere repo must be cloned into $HOME/octoeverywhere"
log_important "Moving the repo and running the install again..."
cd $HOME
# Send errors to null, if the folder already exists this will fail.
git clone https://github.com/QuinnDamerell/OctoPrint-OctoEverywhere octoeverywhere 2>/dev/null || true
cd $HOME/octoeverywhere
# Ensure state
git reset --hard
git checkout master
git pull
# Run the install, if it fails, still do the clean-up of this repo.
if [[ $IS_K1_OS -eq 1 ]]
then
sh ./install.sh "$@" || true
else
./install.sh "$@" || true
fi
installExit=$?
# Delete this folder.
rm -fr $OE_REPO_DIR
# Take the user back to the new install folder.
cd $HOME
# Exit.
exit $installExit
fi
fi
}
#
# Logic to create / update our virtual py env
#
ensure_py_venv()
{
log_header "Checking Python Virtual Environment For OctoEverywhere..."
# If the service is already running, we can't recreate the virtual env so if it exists, don't try to create it.
# Note that we check the bin folder exists in the path, since we mkdir the folder below but virtualenv might fail and leave it empty.
OE_ENV_BIN_PATH="$OE_ENV/bin"
if [ -d $OE_ENV_BIN_PATH ]; then
# This virtual env refresh fails on some devices when the service is already running, so skip it for now.
# This only refreshes the virtual environment package anyways, so it's not super needed.
#log_info "Virtual environment found, updating to the latest version of python."
#python3 -m venv --upgrade "${OE_ENV}"
return 0
fi
log_info "No virtual environment found, creating one now."
mkdir -p "${OE_ENV}"
if [[ $IS_K1_OS -eq 1 ]]
then
# The K1 requires we setup the virtualenv like this.
# --system-site-packages is important for the K1, since it doesn't have much disk space.
# Ideally we use /opt/bin/python3, since that version of python will be updated over time.
# It installs with the opkg command, if opkg is there.
# If not, we will use the version of python built into the system for the existing Creality stuff.
if [[ -f /opt/bin/python3 ]]
then
/opt/bin/virtualenv -p /opt/bin/python3 --system-site-packages "${OE_ENV}"
else
python3 /usr/lib/python3.8/site-packages/virtualenv.py -p /usr/bin/python3 --system-site-packages "${OE_ENV}"
fi
else
# Everything else can use this more modern style command.
# We don't want to use --system-site-packages, so we don't consume whatever packages are on the system.
virtualenv -p /usr/bin/python3 "${OE_ENV}"
fi
}
#
# Logic to make sure all of our required system packages are installed.
#
install_or_update_system_dependencies()
{
log_header "Checking required system packages are installed..."
if [[ $IS_K1_OS -eq 1 ]]
then
# The K1 by default doesn't have any package manager. In some cases
# the user might install opkg via the 3rd party moonraker installer script.
# But in general, PY will already be installed.
# We will try to update python from the package manager if possible, otherwise, we will ignore it.
if [[ -f /opt/bin/opkg ]]
then
# Use the full path to ensure it's found, since it might not be in the path if you user didn't restart the printer.
/opt/bin/opkg update || true
/opt/bin/opkg install ${CREALITY_DEP_LIST} || true
fi
# On the K1, the only we thing we ensure is that virtualenv is installed via pip.
# We have had users report issues where this install gets stuck, using the no cache dir flag seems to fix it.
# 5/14/24 - The trusted hosts had to be added to fix a cert issue with pypi we aren't sure why it started happening all of the sudden.
pip3 install -q --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host=files.pythonhosted.org --no-cache-dir virtualenv
elif [[ $IS_SONIC_PAD_OS -eq 1 ]]
then
# The sonic pad always has opkg installed, so we can make sure these packages are installed.
# We have had users report issues where this install gets stuck, using the no cache dir flag seems to fix it.
opkg update || true
opkg install ${SONIC_PAD_DEP_LIST} || true
pip3 install -q --no-cache-dir virtualenv
else
# Print this before the date update, since it might prompt for the user's password.
log_info "Installing required system packages..."
log_important "You might be asked for your system password - this is required to install the required system packages."
# It seems a lot of printer control systems don't have the date and time set correctly, and then the fail
# getting packages and other downstream things. We will will use our HTTP API to set the current UTC time.
# Note that since cloudflare will auto force http -> https, we use https, but ignore cert errors, that could be
# caused by an incorrect date.
# Note some companion systems don't have curl installed, so this will fail.
#log_info "Ensuring the system date and time is correct..."
sudo date -s `curl --insecure 'https://octoeverywhere.com/api/util/date' 2>/dev/null` || true
# These we require to be installed in the OS.
# Note we need to do this before we create our virtual environment
sudo apt update 1>/dev/null 2>/dev/null || true
sudo apt install --yes ${PKGLIST} 2>/dev/null
# The PY lib Pillow depends on some system packages that change names depending on the OS.
# The easiest way to do this was just to try to install them and ignore errors.
# Most systems already have the packages installed, so this only fixes edge cases.
# Notes on Pillow deps: https://pillow.readthedocs.io/en/latest/installation.html
log_info "Ensuring zlib is install for Pillow, it's ok if this package install fails."
sudo apt install --yes zlib1g-dev 2>/dev/null || true
sudo apt install --yes zlib-devel 2>/dev/null || true
sudo apt install --yes python-imaging 2>/dev/null || true
sudo apt install --yes python3-pil 2>/dev/null || true
sudo apt install --yes python3-pillow 2>/dev/null || true
fi
#log_info "System package install complete."
}
#
# Logic to install or update the virtual env and all of our required packages.
#
install_or_update_python_env()
{
# Now, ensure the virtual environment is created.
ensure_py_venv
# Update pip if needed - we added a note because this takes a while on the sonic pad.
log_info "Updating PIP if needed... (this can take a few seconds or so)"
if [[ $IS_K1_OS -eq 1 ]]
then
"${OE_ENV}"/bin/python -m pip install --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host=files.pythonhosted.org --no-cache-dir --upgrade pip
else
"${OE_ENV}"/bin/python -m pip install --upgrade pip
fi
# Finally, ensure our plugin requirements are installed and updated.
log_info "Installing or updating required python libs..."
if [[ $IS_K1_OS -eq 1 ]]
then
"${OE_ENV}"/bin/pip3 install --trusted-host pypi.python.org --trusted-host pypi.org --trusted-host=files.pythonhosted.org --require-virtualenv --no-cache-dir -q -r "${OE_REPO_DIR}"/requirements.txt
else
"${OE_ENV}"/bin/pip3 install --require-virtualenv --no-cache-dir -q -r "${OE_REPO_DIR}"/requirements.txt
fi
#log_info "Python libs installed."
}
#
# Logic to ensure the user isn't trying to use this script to setup in OctoPrint.
#
check_for_octoprint()
{
if [[ $IS_SONIC_PAD_OS -eq 1 ]] || [[ $IS_K1_OS -eq 1 ]]
then
# Skip, there's no need and we don't have curl.
return
else
# Check if we are running in the Bambu Connect or Companion mode, if so, don't do this since
# The device could be running OctoPrint and that's fine.
if [[ "$*" == *"-bambu"* ]] || [[ "$*" == *"-companion"* ]]
then
return
fi
# Do a basic check to see if OctoPrint is running on the standard port.
# This obviously doesn't work for all OctoPrint setups, but it works for the default ones.
if curl -s "http://127.0.0.1:5000" >/dev/null ; then
log_important "Just a second... OctoPrint was detected!"
log_blank
log_important "This install script is used to install OctoEverywhere for Mainsail, Fluidd, Moonraker, etc."
log_important "If you want to install OctoEverywhere for OctoPrint, you need to use OctoPrint's Plugin Manager, found in OctoPrint's web settings UI."
log_blank
read -p "Do you want to continue this setup for Mainsail, Fluidd, Moonraker, etc? [y/n]: " -e result
log_blank
if [ "${result^^}" != "Y" ] ; then
log_info "Stopping install process."
exit 0
fi
fi
fi
}
log_blank
log_blank
log_blank
cat << EOF
@@@@@@@@@@@@@@@@@@@@@@@@***@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@***********************@@@@@@@@@@@@@
@@@@@@@@@@*******************************@@@@@@@@@
@@@@@@@@***********************************@@@@@@@
@@@@@,,,************************/////////*****@@@@
@@@@,,,,,,*****************//////////////******@@@
@@,,,,,,,,,,***********//////////////////*******@@
@@,,,,,,,,,,,,*******////////****///////*********@
@,,,,,,,,,,,/////////////////****//////***********
@,,,,,,,//////////////////////////////************
,,,,,,,,////////////////////////////**************
@,,,,,,,,,,,,/////////////////////****************
@,,,,,,,,,,,,,,/////////////////******************
@@,,,,,,,,,,,,,,,,//////////////*****************@
@@@,,,,,/#######,,,,///////////*****************@@
@@@@,,,##########,,,,,,,//////,****************@@@
@@@@@,##########,,,,,,,,,////,,,,*************@@@@
@@@@@########,,,,,,,,,,,,//,,,,,,,,********@@@@@@@
@@@@@#@@@@,,,,,,,,,,,,,,,,,,,,,,,,,,,***,@@@@@@@@@
@@@@@@@@@@@@@@@,,,,,,,,,,,,,,,,,,,,,@@@@@@@@@@@@@@
EOF
log_blank
log_header " OctoEverywhere For Klipper, Creality OS, And Bambu Lab Printers"
log_blue " The 3D Printing Communities #1 Remote Access And AI Cloud Service"
log_blank
log_blank
log_important "OctoEverywhere empowers the worldwide maker community with..."
log_info " - Free & Unlimited Mainsail, Fluidd, And Bambu Lab Printers Remote Access"
log_info " - Free & Unlimited Next-Gen AI Print Failure Detection"
log_info " - Free Full Frame Rate & Full Resolution Webcam Streaming"
log_info " - 5 Star Rated iOS & Android Apps"
log_info " - Real-Time Print Notifications"
log_info " - And So Much More"
log_blank
log_blank
# These are helpful for debugging.
if [[ $IS_SONIC_PAD_OS -eq 1 ]]
then
echo "Running in Sonic Pad OS mode"
fi
if [[ $IS_K1_OS -eq 1 ]]
then
echo "Running in K1 and K1 Max OS mode"
fi
# Before anything, make sure this repo is cloned into the correct path on Creality OS devices.
# If this is Creality OS and the path is wrong, it will re-clone the repo, run the install again, and exit.
ensure_creality_os_right_repo_path
# Next, make sure our required system packages are installed.
# These are required for other actions in this script, so it must be done first.
install_or_update_system_dependencies
# Check that OctoPrint isn't found. If it is, we want to check with the user to make sure they are
# not trying to setup OE for OctoPrint.
check_for_octoprint $*
# Now make sure the virtual env exists, is updated, and all of our currently required PY packages are updated.
install_or_update_python_env
# Before launching our PY script, set any vars it needs to know
# Pass all of the command line args, so they can be handled by the PY script.
# Note that USER can be empty string on some systems when running as root. This is fixed in the PY installer.
USERNAME=${USER}
USER_HOME=${HOME}
CMD_LINE_ARGS=${@}
PY_LAUNCH_JSON="{\"OE_REPO_DIR\":\"${OE_REPO_DIR}\",\"OE_ENV\":\"${OE_ENV}\",\"USERNAME\":\"${USERNAME}\",\"USER_HOME\":\"${USER_HOME}\",\"CMD_LINE_ARGS\":\"${CMD_LINE_ARGS}\"}"
#log_info "Bootstrap done. Starting python installer..."
# Now launch into our py setup script, that does everything else required.
# Since we use a module for file includes, we need to set the path to the root of the module
# so python will find it.
export PYTHONPATH="${OE_REPO_DIR}"
# We can't use pushd on Creality OS, so do this.
CURRENT_DIR=${pwd}
cd ${OE_REPO_DIR} > /dev/null
# Disable the PY cache files (-B), since they will be written as sudo, since that's what we launch the PY
# installer as. The PY installer must be sudo to write the service files, but we don't want the
# complied files to stay in the repo with sudo permissions.
if [[ $IS_SONIC_PAD_OS -eq 1 ]] || [[ $IS_K1_OS -eq 1 ]]
then
# Creality OS only has a root user and we can't use sudo.
${OE_ENV}/bin/python3 -B -m py_installer ${PY_LAUNCH_JSON}
else
sudo ${OE_ENV}/bin/python3 -B -m py_installer ${PY_LAUNCH_JSON}
fi
cd ${CURRENT_DIR} > /dev/null
# Check the output of the py script.
retVal=$?
if [ $retVal -ne 0 ]; then
log_error "Failed to complete setup. Error Code: ${retVal}"
fi
# Note the rest of the user flow (and terminal info) is done by the PY script, so we don't need to report anything else.
exit $retVal