Thinstation / thinstation

A framework for making thin and light Linux based images for x86 based machines and thinclients.
https://www.thinstation.net/
807 stars 187 forks source link

Custom Package Creation & Adding to build.conf #858

Open Theknight2015 opened 4 days ago

Theknight2015 commented 4 days ago

Thank you in advance to anyone able to provide guidance or help on this issue.

I've been looking through the documentation of thinstation as well as other issues and forums and I can't seem to find a clear answer or "guide" on how to create your own custom package that installs a program like python3-pip or something. I have watched the video Donald Cupp put out on YouTube - https://www.youtube.com/watch?v=4socE4i_mUc

My problem is that in that guide he was able to use aur.archlinux.org package repo to install strongswan and I'm trying to install python3-pip which isn't on there. It's on the crux repo though. I looked at the crux repo and found the package file (that's what Donald Cupp gets after running some commands on the PKGBUILD file from the aur repo download).

Once I realized that the crux repo provided me with the pkgfile already I jumped to that part in the video since I already had the pkgfile I assumed it would work. I followed the rest of the tutorial to the letter and everything seemed to work fine.

When I added python3-pip (the name of the folder where pkgfile and all the other stuff was in the ts/ports/components directory) to my build.conf file and ran ./build I searched the log and got python3-pip: Setup complete so I assumed the setup and install process worked.

When I boot the thin clinet I run pip3 --version and I get a bunch of errors. If I run python3-pip --version or python3 -m pip --version I get things like Command Not Found or No Module Named pip and other stuff like that.

So obviously the original test command of pip3 --version is the one I need but again that causes a bunch of errors like: File "/bin/pip3", line 33, in <module> and other stuff like that talking about load_entry_point errors but I don't know what any of that means though.

Thanks again for any help anyone can provide! I know this is an odd issue to pose but hopefully someone can steer me right.

Thinstation commented 4 days ago

So, pip is a dynamic package installer. I could never think of any real use of it inside of a transient OS. However, if you need some python packages installed into your image, you can make a folder at /build/packages/"your package"/build, then create a pip freeze file called pip3.freeze in that folder that lists all the python packages you want. Also make sure there is a file at /build/packages/"your package"/dependencies with python3 as some of the content. Then add package "your package" to your build.conf. Let me know if you really need pip inside the image, and I will write something up.

Thinstation commented 4 days ago

build/packages/docker-compose is a good example

Theknight2015 commented 4 days ago

So my goal is to be able to run a python script on the thin clients. This particular python script starts with the following:

import tkinter as tk
from tkinter import scrolledtext, messagebox
from PIL import Image, ImageTk, ImageGrab
import requests
import base64
from io import BytesIO
from datetime import datetime
import logging
import os

So I need those various modules installed to run it. If I don't have those it won't run. My end goal is to make it so all the required python modules are installed and once the thin client boots up I want it to run some type of script that copies the python script from my server and places it in a directory on the client then automatically launches said script. It's a gui python script.

So if I'm understanding the instructions above correctly, I need to add the following in the /build/packages/pipinstaller/build pip.freeze file? (pipinstaller is the package name I chose)

tkinter as tk
PIL
requests
base64
io
datetime
logging
os
ctypes
subprocess
sys

There's a couple extra modules from another script I may run as well in this section above. My /build/packages/pipinstaller/dependencies file needs to contain python3 and then my build.conf file needs to have the line package pipinstaller in it?

My main questions are how do I get tkinter imported as tk which is what my script calls for. It's my understanding that tkinter is a package like python3 and like pip right? Or am I missing something here? I know this is a super niche case but I'm hoping to figure this out. Thanks for all the help so far!

Thinstation commented 4 days ago

Yes. pip3.freeze though. I had pip2.freeze for python2, but that's not really used anymore. Also make sure that the python3 package gets installed somehow, either as a dependency of your package or in build.conf explicitly. I think tk is actually already built in, but you could run pip freeze on a system that runs your application for the exact syntax to put in the pip3.freeze file.

Theknight2015 commented 4 days ago

I did as you suggested and ran pip freeze on a windows machine that runs the script directly and I got the following:

certifi==2024.8.30
charset-normalizer==3.4.0
idna==3.10
pillow==11.0.0
pyodbc==5.2.0
requests==2.32.3
urllib3==2.2.3

So I added the relivant entries to the pip.freeze file and re-ran ./build then booted my thin client.

I then opened a terminal on the client and ran the following commands in order (The results of the command are after the "-" to the right of each commandin quotes and my notes or questions are after in parentheses)

python3 -m pip --version - "No module named pip" (this is expected since pip is not a module right?) python3 -m request --version - "No module named requests" (I'm assuming this is not supposed to say that?) python3 -m tkinter --version - "Tcl Error: Can't find usable init.tcl in the following directories..." (Not sure on this one) python3 -m tk --version - "No module named tk" (Not sure if this was supposed to work since tkinter didn't) python3 -m pillow --version - "No module named pillow" (I'm assuming this probably should have worked)

Here is my pip.freeze file contents:

tkinter as tk
PIL
requests
base64
io
datetime
logging
os
ctypes
subprocess
sys
pillow
pyodbc
urllib3

I know there's a lot more in here but I'm trying to future proof my systems to allow for other python scripts to be run without needing to modify the build. My dependencies file in the pipinstaller directory (IE: one up from the pip.freeze file directory) contains the following single line python3 and nothing else.

My build.conf file has a line in it that says package python3 and another line that says package pipinstaller (IE: the pipinstaller directory in the packages directory right?) and both of these lines are on top of one another just below the package freerdp line which I assume is correct?

I feel like maybe I'm missing something simple here but maybe I'm also just not understanding?

Thinstation commented 4 days ago

pip3.freeze

Theknight2015 commented 4 days ago

Wow... How did I type that out so many times and not notice the 3 was missing. I'll test and get back to you. Thank you!

Thinstation commented 4 days ago

Towards the end of the build you should see messages about python packages being installed.

Thinstation commented 4 days ago

Also, you can just copy the output of the pip freeze from the windows machine and paste it into the pip3.freeze file. I don't think tkinter as tk is going to work or if all those other ones are even python packages vs subcomponents of the packages listed in pip freeze

Theknight2015 commented 4 days ago

I did just see that. Here is the output of it:

Installing Python3 Packages
**ERROR: Invalid requirement: 'tkinter as tk' (from line 1 of ./tmp-tree/pip3.freeze)**
cp: cannot stat './py-tmp/usr/*': No such file or directory
Running File System Fixups
        Building Charmap Cache
        Removing Extra Files
        Running mkfontdir and mkfontscale
        Caching pixbuf loaders
        Caching gtk-2.0 immodules
        Compiling Schemas
        Linking BusyBox

        Running Finalize

So I went back and modified the pip3.freeze file to only have tkinter not tkinter as tk and this is the output of that at the end where python stuff gets installed:

Installing Python3 Packages
ERROR: Could not find a version that satisfies the requirement tkinter (from versions: none)
ERROR: No matching distribution found for tkinter
cp: cannot stat './py-tmp/usr/*': No such file or directory
Running File System Fixups
        Building Charmap Cache
        Removing Extra Files
        Running mkfontdir and mkfontscale
        Caching pixbuf loaders
        Caching gtk-2.0 immodules
        Compiling Schemas
        Linking BusyBox

        Running Finalize

So then I just removed the tkinter line all together from the pip3.freeze file and rebuilt. This is what I got for the section Installing Python3 Packages:

Installing Python3 Packages
ERROR: Could not find a version that satisfies the requirement PIL (from versions: none)
ERROR: No matching distribution found for PIL
cp: cannot stat './py-tmp/usr/*': No such file or directory
Running File System Fixups
        Building Charmap Cache
        Removing Extra Files
        Running mkfontdir and mkfontscale
        Caching pixbuf loaders
        Caching gtk-2.0 immodules
        Compiling Schemas
        Linking BusyBox

        Running Finalize

So with all that being said. Basically what I've now done is removed line by line anything that I don't need or wasn't explicitly referenced in any of the scripts or anything that threw errors during build and I was left with:

certifi
charset-normalizer
idna
pillow
pyodbc
requests
urllib3

And using that pip.freeze file I was able to get the following at the end of the build process:

Installing Python3 Packages
Collecting certifi
  Downloading certifi-2024.8.30-py3-none-any.whl (167 kB)
     |████████████████████████████████| 167 kB 1.9 MB/s
Collecting charset-normalizer
  Downloading charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (144 kB)
     |████████████████████████████████| 144 kB 17.0 MB/s
Collecting idna
  Downloading idna-3.10-py3-none-any.whl (70 kB)
     |████████████████████████████████| 70 kB 6.1 MB/s
Collecting pillow
  Downloading pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl (4.4 MB)
     |████████████████████████████████| 4.4 MB 31.0 MB/s
Collecting pyodbc
  Downloading pyodbc-5.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (333 kB)
     |████████████████████████████████| 333 kB 42.1 MB/s
Collecting requests
  Using cached requests-2.32.3-py3-none-any.whl (64 kB)
Collecting urllib3
  Downloading urllib3-2.2.3-py3-none-any.whl (126 kB)
     |████████████████████████████████| 126 kB 48.4 MB/s
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests, pyodbc, pillow
Successfully installed certifi-2024.8.30 charset-normalizer-3.4.0 idna-3.10 pillow-11.0.0 pyodbc-5.2.0 requests-2.32.3 urllib3-2.2.3
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
Running File System Fixups
        Building Charmap Cache
        Removing Extra Files
        Running mkfontdir and mkfontscale
        Caching pixbuf loaders
        Caching gtk-2.0 immodules
        Compiling Schemas
        Linking BusyBox

        Running Finalize

Once I booted into the client I ran a test of python3 -c "import requests; print(requests.__version__)" and the response was 2.23.3 which indicates the requests package is now installed. Thank you so much!

Now out of curiosity - And this may need to be a separate thread - how would one go about either pulling the python script I want to run from the tftp server and opening it (I'm assuming a startup script of some kind would have to be made?) or building the python script into the image so it's already in the filesystem of the thin client and then create a terminal script that launches that python script?

Thinstation commented 4 days ago

Either or. You can look at packages/template for some context, but once all of those are filled out, you can set your application as an autostart session. During your init, you can have it download the latest version before execution, or just have it inserted during build.

Theknight2015 commented 4 days ago

Okay thanks! I may ask for clarification on those options later on. After some additional testing with the script I have, I found something odd when I try to run it. I get the following error and I'm not sure how to fix it. I added tcl to the pip3.freeze file but that didn't change anything.

When running python3 myscriptname.py after getting it downloaded via tftp I get these errors in the log:

CRITICAL - Critical error in the application: can't find a usable init.tcl in the following directories: /usr.lib.tcl8.6 /lib/tcl8.6 /library /tcl8.6.9/library /tcl8.6.9/library

This probably means that Tcl wasn't installed properly

I'm assuming thinstation client builds don't come with whatever this file is?

I'm leaving work for the day so I'll reply on Monday when I get back. Thanks for your help!

Thinstation commented 4 days ago

Might need to run mkrepackage tcl and then add tcl as a dependency of your package.

Thinstation commented 1 day ago

see https://github.com/Thinstation/thinstation/wiki/Packaging and https://github.com/Thinstation/thinstation/wiki/Ports-and-Packages

Theknight2015 commented 1 day ago

If I'm understanding the mkrepackage option correctly, I should be able to run mkrepackage tcl and it should do what I need to fix the tcl problem then I rebuild with ./build? That seems to simple and like I'm not actually understanding something.

Thinstation commented 1 day ago

You need to make sure that tcl gets put into your build by either adding it to the dependencies of your package or putting "package tcl" into build.conf

Theknight2015 commented 1 day ago

tcl was already added as a single line in the dependencies for the custom package. I went ahead and added it to the build.conf as well and rebuilt. Here is the output of that:

Building PKG Packages

Building Module PKG Packages

Installing Python3 Packages
Collecting certifi
  Using cached certifi-2024.8.30-py3-none-any.whl (167 kB)
Collecting charset-normalizer
  Using cached charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (144 kB)
Collecting idna
  Using cached idna-3.10-py3-none-any.whl (70 kB)
Collecting pillow
  Using cached pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl (4.4 MB)
Collecting pyodbc
  Using cached pyodbc-5.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (333 kB)
Collecting requests
  Using cached requests-2.32.3-py3-none-any.whl (64 kB)
Collecting urllib3
  Using cached urllib3-2.2.3-py3-none-any.whl (126 kB)
Collecting tcl
  Using cached Tcl-0.2-py3-none-any.whl (2.4 kB)
Installing collected packages: urllib3, idna, charset-normalizer, certifi, tcl, requests, pyodbc, pillow
Successfully installed certifi-2024.8.30 charset-normalizer-3.4.0 idna-3.10 pillow-11.0.0 pyodbc-5.2.0 requests-2.32.3 tcl-0.2 urllib3-2.2.3
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv
Running File System Fixups
        Building Charmap Cache
        Removing Extra Files
        Running mkfontdir and mkfontscale
        Caching pixbuf loaders
        Caching gtk-2.0 immodules
        Compiling Schemas
        Linking BusyBox

        Running Finalize

Upon testing after having tcl in both the build.conf file as package tcl and the dependency file as a line tcl I got the same Critical error. I'm not understanding, if tcl is included in the system which I think it is based on the fact there is already a tcl folder in packages, why would it be throwing errors unless there is a problem with the tcl package itself?

If you think there might be a problem with the tcl package, how would one go about rebuilding that package or fixing it?

Again thanks for all the help. I know it's been a lot of back and forth. I apologize if I'm missing something simple or not understanding correctly.

Thinstation commented 1 day ago

Strange, when I run repackage on tcl, I see that there is an init.tcl at /build/packages/tcl/lib/tcl8.6/init.tcl

Thinstation commented 1 day ago

Maybe try installing all your python packages in the chroot, and try and run your script there to make sure it will run in a rich environment.

Theknight2015 commented 1 day ago

When you say install my python packages in the chroot environment what do you mean by that? Like make package folders for each python package (IE: requests, pillow... etc) or do you mean something else?

Theknight2015 commented 1 day ago

Also I checked that folder you specified above and there is a init.tcl file along with a bunch of other files and directories. Not sure if that matters or not.

Thinstation commented 1 day ago

In the chroot environment where you would normally run ./build, do a pip install , then put your script somewhere and try and run it.

Theknight2015 commented 1 day ago

Okay here is the output of each command as I went through it:

pip install requests

Requirement already satisfied: requests in /usr/lib/python3.9/site-packages (2.25.1)
Requirement already satisfied: chardet<5,>=3.0.2 in /usr/lib/python3.9/site-packages (from requests) (4.0.0)
Collecting idna<3,>=2.5
  Downloading idna-2.10-py2.py3-none-any.whl (58 kB)
     |████████████████████████████████| 58 kB 2.5 MB/s
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/lib/python3.9/site-packages (from requests) (1.26.5)
Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python3.9/site-packages (from requests) (2021.5.30)
Installing collected packages: idna
  Attempting uninstall: idna
    Found existing installation: idna 3.2
    Uninstalling idna-3.2:
      Successfully uninstalled idna-3.2
Successfully installed idna-2.10
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

pip install pyodbc

Collecting pyodbc
  Using cached pyodbc-5.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (333 kB)
Installing collected packages: pyodbc
Successfully installed pyodbc-5.2.0
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

pip install urllib3

Requirement already satisfied: urllib3 in /usr/lib/python3.9/site-packages (1.26.5)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

`pip install pillow'

Collecting pillow
  Using cached pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl (4.4 MB)
Installing collected packages: pillow
Successfully installed pillow-11.0.0
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

pip install idna

Requirement already satisfied: idna in /usr/lib/python3.9/site-packages (2.10)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

pip install charset-normalizer

Collecting charset-normalizer
  Using cached charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (144 kB)
Installing collected packages: charset-normalizer
Successfully installed charset-normalizer-3.4.0
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

pip install certifi

Requirement already satisfied: certifi in /usr/lib/python3.9/site-packages (2021.5.30)
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

pip install tcl

Collecting tcl
  Using cached Tcl-0.2-py3-none-any.whl (2.4 kB)
Installing collected packages: tcl
Successfully installed tcl-0.2
WARNING: Running pip as root will break packages and permissions. You should install packages reliably by using venv: https://pip.pypa.io/warnings/venv

After installing all of them (or at least running the commands to install all of them) I then rebuilt using ./build and once the thin client booted I downloaded the script from the tftp server using this command tftp -g -r myscript.py 192.xxx.x.xxx -l ~/Downloads/myscript.py which downloads the script to the downloads folder of the client. Once there I ran python3 myscript.py which is supposed to open the script and create a script.log file in the same directory (IE: the Downloads directory). It tries to run the script but nothing shows on screen. When I run ls in that terminal window it shows me there is now a script.log file so I run nano script.log to open it. Inside that log is the same error as before.

INFO - Script Started
INFO - Initializing the GUI
CRITICAL - Critical error in the application: can't find a usable init.tcl in the following directories: /usr.lib.tcl8.6 /lib/tcl8.6 /library /tcl8.6.9/library /tcl8.6.9/library

I'm at a loss on why the tcl isn't working. I don't think I've modified it in any way. At least not to my knowledge and not intentionally. It should be working from what I'm gathering. I'm even getting a Successfully installed tcl-0.2 message in the output of pip install tcl in the chroot environment so I'm not sure why it's not working.

Thinstation commented 1 day ago

Maybe it needs tk as well, but what I wanted you to do was run your script in the chroot environment, not from an image.

Theknight2015 commented 1 day ago

Oh okay, I went ahead and did it 2 ways. The first way I ran it was in the regular terminal window by navigating to the build directory and running sudo python3 myscript.py (I placed the script there already and I know this is not in the chroot environment but I wanted to try it just in case) and it gave me the following errors when running that way:

Traceback (most recent call last):
  File "/home/tsadmin/thinstation/ts/build/1920x1080DPI1.00.py", line 3, in <module>
    from PIL import Image, ImageTk, ImageGrab
ImportError: cannot import name 'ImageTk' from 'PIL' (/usr/lib/python3/dist-packages/PIL/__init__.py). Did you mean: 'Image'?

Then the second time I ran it I went to the thinstation directory and ran sudo ./setup-chroot followed by q when the window appeared with the README file then I ran cd build then python3 myscript.py and got the following in the script.log file as there was no window that opened up

2024-10-21 14:32:41,282 - INFO - Script started.
2024-10-21 14:32:41,282 - INFO - Initializing the GUI.
2024-10-21 14:32:41,605 - CRITICAL - Critical error in the application: bad argument "zoomed": must be normal, iconic, or withdrawn

So I changed the zoomed argument to normal in the script and then reran in chroot environment then got this error

2024-10-21 14:35:52,516 - INFO - Script started.
2024-10-21 14:35:52,516 - INFO - Initializing the GUI.
2024-10-21 14:35:52,542 - CRITICAL - Critical error in the application: X get_image failed: error 8 (73, 0, 1025)

I'm assuming this is due to some module of python not being installed?

Thinstation commented 1 day ago

Running applications inside the chroot that need X can get a little tricky. I've made some improvements to that with the 6.3.0 release, but if your still on 6.2, then you need to completely logout of your system and login directly as root, then open the chroot and try again.

Thinstation commented 1 day ago

Anyways, I wrote a simple python tcl gui and did a repackage on tcl and put both in a test image. It required that I also add tk, so I did a mkrepackage on tk and put that into the build, and the test app ran. So I think you might just need to add tk

Theknight2015 commented 1 day ago

Okay, I followed your advice and entered the chroot environment where I issued the mkrepackage tk command and then added package tk to my build then ./build and now my python script (after downloading) works. I'll have to modify it some since there are certain aspects that don't transfer from windows (where I developed the script) to linux but I can do that.

Do you have a tutorial/example of how to make a script that automatically downloads the file and opens it? I would love for there to be a way for me to make the file download to the Downloads directory on boot and automatically run when the system opens. I'm not sure exactly how to do that but I'd assume it's pretty basic with a terminal file/command process?

Thinstation commented 1 day ago

I recently updated the template package to include all files that might be used. https://github.com/Thinstation/thinstation/wiki/Packaging goes over this. I think what you want is a systemd service that executes a script that downloads your script and places it somewhere in the path, like /bin. You can then follow other instructions on that page that will show you how to set up the command execution of your script in /etc/cmd files. Then just make a new session in your thinstation.buildtime that calls your application.

Theknight2015 commented 22 hours ago

I was able to get the system to include a start_my_script.sh file in the /usr/bin/ folder of my thin client. I open a terminal window and type /usr/bin/start_my_script.sh and it works. It opens my script. Now how do I set it to automatically run that command on terminal? I tried

SESSION_0_TYPE=xfwm4
SESSION_0_AUTOSTART=on
SESSION_0_ICON=OFF
USE_XRANDR=TRUE
XRANDR_OPTIONS="--output HDMI1 --primary --mode 1920x1080 --output HDMI2 --mode 1920x1080 --left-of HDMI1"
SESSIONS 1-3 Go Here and Pertain to freerdp
SESSION_4=terminal
SESSION_4_AUTOSTART=TRUE
SESSION_4_CMD=/usr/bin/start_my_script.sh

But this doesn't seem to work. Nothing happens.

Thinstation commented 21 hours ago

You need to make a link to /etc/thinstation.packages in /etc/init.d called start_my_script. In /etc/cmd, create a file called start_my_script.global with the contents CMD_GLOBAL="/bin/start_my_script.sh", then add SESSION_4_TYPE=start_my_script, SESSION_4_AUTOSTART=true to thinstation.conf.buildtime

Theknight2015 commented 4 hours ago

So maybe I'm just missing something here. I'll explain step by step what I've done and see if maybe you can find a flaw in my process. First thing is I copied the /build/packages/template directory and all it's contents. The new directory is called my_script and it's located in the packages directory so the path is /build/packages/my_script

Inside my_script I have bin, dependencies, etc and lib. Dependencies is a file and the rest are directories.

Inside the bin directory there is a file called start_my_script.sh and the contents of this file are as follows:

#!/bin/bash
# Download the Python script from the TFTP server
tftp -g -r my_py_file_from_my_tftp_server.py my_tftp_server_ip_here -l /home/MyUsernameSetInBuild.conf/Downloads/my_py_file_from_my_tftp_server.py

# Run the downloaded Python script
python3 /home/MyUsernameSetInBuild.conf/Downloads/my_py_file_from_my_tftp_server.py

Inside the dependencies file is the following:

#add your own dependancies to this file, base should always be included.
base
python3

Inside etc I have the cmd, console, init.d and systemd directories. Inside the cmd directory is a file called start_my_script and inside that file is the following line: CMD_GLOBAL="/bin/start_my_script.sh" Inside the init.d directory is a file called start_my_script and inside that file is the following:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          start_my_script
# Required-Start:    $all
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
# Short-Description: Script to pull Python script from TFTP and execute it
### END INIT INFO

case "$1" in
  start)
    echo "Starting my_script script..."
    # Fetch the Python script from the TFTP server
    tftp -g -r my_py_file_from_my_tftp_server.py my_tftp_server_ip_here -l /home/MyUsernameSetInBuild.conf/Downloads/my_py_file_from_my_tftp_server.py

    # Ensure the script has execution permissions
    chmod +x /home/MyUsernameSetInBuild.conf/Downloads/my_py_file_from_my_tftp_server.py

    # Run the Python script
    python3 /home/MyUsernameSetInBuild.conf/Downloads/my_py_file_from_my_tftp_server.py &
    ;;
  stop)
    echo "Stopping my script script..."
    # Add any stop functionality here if necessary
    ;;
  *)
    echo "Usage: /etc/init.d/start_my_script {start|stop}"
    exit 1
    ;;
esac

exit 0

Inside the systemd directory is a system directory and inside that system directory is a multi-user.target.wants directory and a start_my_script.service file. The service file is also inside the multi-user.target.wants directory and here is the contents of both of those service files

[Unit]
Description=Start My Script Script
After=network.target

[Service]
Type=simple
ExecStart=/etc/init.d/start_my_script start

[Install]
WantedBy=multi-user.target

Again both the start_my_script.service file in the system directory as well as the multi-user.target.wants directory contain that same exact code. The console directory only contains a readme file so I did not include it above.

Going back one directory you'll find the lib directory. Inside the lib directory is a file called "any_additional_libs_go_here" which is a blank file. There is also a menu directory with a README file and an example file inside it. I have not changed or modified these files in any way from when I copied them from the template folder.

I think I have everything set correctly for the package. My thinstation.conf file for that specific host is as follows now:

AUDIO_LEVEL=90
MIC_LEVEL=0
SESSION_0_TYPE=xfwm4
SESSION_0_AUTOSTART=on
SESSION_0_ICON=OFF
USE_XRANDR=TRUE
XRANDR_OPTIONS="--output HDMI1 --primary --mode 1920x1080 --output HDMI2 --mode 1920x1080 --left-of HDMI1"
SESSION_1 - SESSION_2 are freerdp stuff.
SESSION_3_TYPE="start_second_screen"
SESSION_3_AUTOSTART=true
SESSION_3_ICON=OFF

I feel like I've done everything correctly but it still doesn't launch the python script on start up. If I go to the /etc/init.d directory and start typing "start_" and hit tab it auto populates with start_my_script.sh but if I do the "ls" command to list the directory it only shows start_my_script with no .sh at the end. However, If I hit the return key on the start_my_script.sh autopopulated command the python script I have downloads and opens. Also if I navigate to the /bin directory and do a ./start_my_script.sh command it opens. Obviously both of these methods are downloading the script then running it.

One thing I noticed when browsing is that in the init.d directory there are freerdp, terminal and xfwm4 options that are baby blue in color. My start_my_script option is green like the rest of the files. This indicates the permissions on the freerpd, xfwm4 and terminal applications are different that my start_my_script one right? Could this be the problem?

It's also worth noting that the python script does download to my downloads folder as intended after one of the start_my_script options is run but it is not present immediately after a fresh boot up. I have to run either the init.d directory start_my_script or the /bin directory start_my_script.sh before the python file appears in my Downloads directory which is where I want it to go.

Hopefully I'm just missing something simple but I'm honestly at a loss right now on what I'm doing wrong.

Thinstation commented 3 hours ago

I was thinking this morning, that I should make a simple way to just execute a command, but lets fix this for you first. Since your script does the downloading, you don't need the systemd files. You don't need a script in /etc/init.d, but you do need a link that points to /etc/thinstation.packages, so go to your etc/init.d folder remove everything, then ln -sf /etc/thinstation.packages start_my_script, go to the cmd folder and mv start_my_script start_my_script.global. In thinstation.conf.buildtime, add SESSION_4_TYPE="start_my_script" SESSION_4_AUTOSTART=true SESSION_4_ICON=OFF

Theknight2015 commented 2 hours ago

After I rm -rf start_my_script in the init.d folder I run ln -sf /etc/thinstation.packages start_my_script and then do a ls and I have the following in the init.d directory now: start_my_script and it's highlighted in red. If I nano the file it is empty. I then move up one directory and then cd cmd into the cmd directory and run mv start_my_script start_my_script.global' which leaves me with astart_my_script.global` file in my cmd directory. The original README file I remove just because.

Is that correct? My package still does not launch on boot? And just to verify I am running the sudo ./setup-chroot command then cd build followed by ./build after I've changed all the files.

Theknight2015 commented 2 hours ago

I also looked at the thinstation.package file of the thin client after it was booted. That file is located in etc/ and after reviewing the file I find no mention ofstart_my_script anywhere. Not sure if that matters at all or what that's supposed to do. There is also no thinstation.package file in /home/myusername/thinstation/etc of the server.

Thinstation commented 1 hour ago

thinstation.packages is a generic package script that figures out what package to run by figuring out how it was called. When we link /etc/init.d/start_my_script to it, it know that it is going to launch start_my_script according to the files in /etc/cmd. Early in boot, the thinstation.conf files are parsed for apps to run, and a list is made. After X starts, that list of apps is started. If all your files and links are correct, from a terminal you should be able to run pkg window start_my_script to test the pipeline.

Theknight2015 commented 1 hour ago

When I run pkg window start_my_script on the thin client it runs the download process and opens the python script. So if that's working why isn't it doing it automatically when the system boots up? I must be missing something right?

Thinstation commented 1 hour ago

SESSION_4_TYPE="start_my_script" SESSION_4_AUTOSTART=true SESSION_4_ICON=OFF

Thinstation commented 1 hour ago

My bad, it needs to be SESSION_4_AUTOSTART=on not true. I just looked at the code and thats one of the rare places where not every affirmative word works.

Theknight2015 commented 1 hour ago

Ahhhhh okay. That worked. Now the python script opens when I boot up on the client that has the session set to start_my_script. Thank you!

Theknight2015 commented 1 hour ago

When I close the python script a box pops up asking if I want to reconnect. If I say yes it opens the python script again and if I say no everything goes black and the thin client turns off. Is there a way to prevent that?

Thinstation commented 1 hour ago

To disable the reconnect dialog, you can set RECONNECT_PROMPT=off, to keep the prompt but not do anything if the user says no, set NO_SESSION=""

Theknight2015 commented 1 hour ago

Perfect thank you!