• 1 Post
  • 892 Comments
Joined 2 years ago
cake
Cake day: June 12th, 2023

help-circle
  • It’s really quite simple - but works pretty well. There are 3 components:

    Kiosk service

    A simple systemd service that starts a kiosk script.

    [Unit]
    Description=Kiosk
    Wants=graphical.target
    After=graphical.target
    
    [Service]
    Environment=DISPLAY=:0.0
    Environment=XAUTHORITY=/home/pi/.Xauthority
    Type=simple
    ExecStart=/bin/bash /home/pi/kiosk.sh
    Restart=on-abort
    User=pi
    Group=pi
    
    [Install]
    WantedBy=graphical.target
    

    Kiosk script

    The script in /home/pi/kiosk.sh just starts a web browser in full-screen mode pointed at my home assistant instance:

    #!/bin/bash
    
    xset s noblank
    xset s off
    xset -dpms
    
    export DISPLAY=:0.0 
    
    echo 0 > /sys/class/backlight/rpi_backlight/bl_power
    
    LANDING_PAGE="https://homeassistant.example.com/"
    
    unclutter -idle 0.5 -root &
    
    /usr/bin/chromium-browser --noerrdialogs --disable-infobars --kiosk $LANDING_PAGE
    
    

    Display service

    I have a very simple python/flask service that runs and exposes an endpoint that lets you turn on/off the display. It’s called by a homeassistant automation for when the motion detector senses or hasn’t sensed movement.

    Here’s the python - I have this started from another “kiosk.service” systemd service as well.

    #!/usr/bin/env python3
    import subprocess
    
    from flask import Flask
    from flask_restful import Api, Resource
    
    def turn_off_display():
        with(open(backlight_dev, 'w')) as dev:
            dev.write("1")
    
    
    def turn_on_display():
        with(open(backlight_dev, 'w')) as dev:
            dev.write("0")
    
    
    class DisplayController(Resource):
        def get(self, state):
            if state == 'off':
                turn_off_display()
            elif state == 'on':
                turn_on_display()
            else:
                return {'message': f'Unknown state {state} - should be off/on'}, 500
            return {"message": "Success"}
    
    
    def init():
        turn_on_display()
    
    
    if __name__ == "__main__":
        init()
        app = Flask(__name__)
        api = Api(app)
        api.add_resource(DisplayController, '/display/<string:state>')
        app.run(debug=False, host='0.0.0.0', port=3000)
    

    You can then have the HA rest action call this with “http://pidisplay:3000/display/on” or off.


  • Sure thing - one thing I’ll often do for stuff like this is spin up a VM. You can throw 4x1GiB virtual drives in it and play around with creating and managing a raid using whatever you like. You can try out md, ZFS, and BTRFS without any risk - even unraid.

    Another variable to consider as well - different RAID systems have different flexibility for reshaping the RAID. For example - if you wanted to add a disk later, or swap out old drives for new ones to increase space. It’s yet another rabbit hole to go down, but something to keep in mind. When we start talking about 10’s of terrabytes of data you start to lose somewhere to temporarily put it all if you need to recreate your raid to change your raid layout. :-)


  • Yeah - that’s fair. I may have oversimplified a tad… The concepts behind RAID, the theory, implementations, etc. are pretty complicated. And there are many tools that do “raid-like-things” with many options about raid types… So the landscape has a lot of options.

    But once you’ve made a choice the actual “setting it up” is usually pretty simple, and there’s no real on-going support or management you need to do beyond just basic health monitoring which you’d want to do even without a RAID (e.g. smartd). Any Linux system can create and use a RAID - you don’t need anything special like Unraid. My old early-to-mid-2010’s Debian box manages a RAID with NFS just fine.

    If you decide you want a RAID you first decide which “level” you want before talking about any specific implementations. This drives all of your future decisions including which software you use. This basically focuses on 2 questions - how much budget do you have and what is your fault tolerance?

    e.g. I have a RAID5 because I’m cheap and wanted biggest bang-for-the-buck with some failure resiliency. RAID5 lets me lose one drive and recover, and I get the storage space of N-1 drives (1 drive is redundant). Minimum size for a RAID5 is 3 drives. Wikipedia lists the standard RAID levels which are “basically” standardized even though implementations vary.

    I could have gone with RAID6 (minimum 4 disks) which can suffer a 2 drive outage. I have off-site backups so I’ve decided that the low-probability of a 2 drive failure means this option isn’t necessary for me. If I’m that unlucky I’ll restore from BackBlaze. In 10+ years of managing my own fileserver I’ve never had more than 1 drive fail at a time. I’ve definitely had drives fail though (replaced one 2 weeks ago - was basically a non-issue to fix).

    Some folks are paranoid and go with RAID1 and friends (RAID1, RAID10, etc.) which involves basically full duplication of drives. Very safe, very expensive for the same amount of usable storage. But RAID1 can work with a minimum of 2 drives. It just mirrors them so you get half the storage.

    Next the question becomes - what RAID software to use? Here there are lots of options and where things can get confusing. Many people have become oddly tribal about it as well. There’s the traditional Linux “md” RAID which I use that operates under the filesystems. It basically takes my 4 disks and creates a new block device (/dev/md0) where I create my filesystems. It’s “just a disk” so you can put anything you want on it - I do LVM + ext4. You could put btrfs on it, zfs, etc. It’s “just a disk” as far as the OS is concerned.

    These days the trend is to let the filesystems handle your disk pooling rather than a separate layer. BTRFS will create a RAID (but cautions against RAID5), as does ZFS. These filesystems basically implement the functionality I get from md and lvm into the filesystem itself.

    But there are also tools like Unraid that will provide a nice GUI and handle the details for you. I don’t know much about it though.



  • atzanteol@sh.itjust.workstoLinux@lemmy.mlUse arguments in shell script with apt
    link
    fedilink
    English
    arrow-up
    6
    arrow-down
    2
    ·
    edit-2
    4 days ago

    For apt to install a local file I think you need either a fully qualified path or to use “./” at the start for a relative path.

    So “./$1/opensnitch_${1}_amd64.deb”

    apt install 1.6.5/opensnitch_1.6.5_amd64.deb 1.6.5/python3-opensnitch-ui_1.6.5_all.deb

    Edit: Here’s a better example of what I think you would want:

    #!/bin/bash
    # Often good to assign a numbered parameter to a variable
    VER="${1}"
    apt install "./${VER}/opensnitch_${VER}_amd64.deb" "./${VER}/python3-opensnitch-ui_${VER}_all.deb"
    

    Also - when debugging bash scripts it’s often helpful to just put “echo” before the line you’re questioning to see what exactly is being run. e.g.:

    #!/bin/bash
    VER="${1}"
    echo apt install "./${VER}/opensnitch_${VER}_amd64.deb" "./${VER}/python3-opensnitch-ui_${VER}_all.deb"
    

    That will show the the command that would have run rather than running it, then you can inspect it for errors and even copy/paste it to run it by hand.




  • I used to do this frequently “back in the day”…

    dd will create a complete bit-for-bit copy of the drive and put its contents into a file. All the way down to the boot sector, partitions, etc. Filesystem doesn’t even matter a little.

    I used to do something like “dd /dev/sda bs=1M | nc remote.server 1234” and then on the remote server “nc -l 1234 -p > file.img </dev/null”. I was swapping back and forth between Linux and Windows on a work laptop that I was using for non-work related things on the weekend, at conferences, etc.

    Wasn’t perhaps my most intelligent moment, but it worked!



  • It requires a near obsessive understanding of the architecture being emulated, but generally the process is “relatively straightforward” (though not necessarily “easy”). A CPU is a relatively simple device compared to the software built on it. Your basic steps are:

    1. Read an instruction
    2. Perform the instruction
    3. Jump to the next instruction

    Throw that in a loop and voilà! You have an emulator. Granted I’ve handwaved over a lot of complexity (I don’t mean to trivialize the effort)…

    To translate a binary is very different. Compilers optimize output to behave in a specific way for the target CPU that simply may not work on the new CPU. What do you do, for example, if the code was compiled for a platform that had 12 registers but the new one only has 6? You’d need to re-write the logic to work with fewer registers. That’s difficult to do in a way that is generic for any program. An emulator can just present the program with the 12 registers it expects (emulated in memory at the expense of performance).




  • I have an alias set up and SDKs enabled. The experience is indistinguishable from a regular install.

    That’s not indistinguishable - that’s you working around the problem of running flatpak run some.domain.IForget(which - BONUS is case sensitive which is awesome) to run neovim.

    Snaps install a binary you can run. Flatpaks make you remember the 3 part domain to run things. So you setup aliases after installing things to run them, and if you uninstall them you need to remove your aliases. It’s a complete own-goal by the flatpak developers that this mess exists and is completely unnecessary. Simply providing an option to create and manage a script in .local/bin or something would be all it takes to make flatpaks usable from the CLI in a way that isn’t obnoxious.