There have been multiple accounts created with the sole purpose of posting advertisement posts or replies containing unsolicited advertising.

Accounts which solely post advertisements, or persistently post them may be terminated.

lemmy.world

SeatBeeSate , to cat in Subscribe To His OnlyKitties 😹

!subscribe

Ravenlord , to aww in My boy Charles in his safe place

Make sure to keep an eye on the spring that’s inside that tunnel. One end popped out of its fabric on mine and got my cats eye. $1700 emergency vet visit later and she’s doing great, but I’ll always give people the warning so they don’t have to go through it.

Steveanonymous , to aww in My boy Charles making his mark on Lemmy!
@Steveanonymous@lemmy.world avatar

Chuck’s a good boy!

czardestructo OP , to selfhosted in Ghost Pi - an unconventional backup solution
@czardestructo@lemmy.world avatar

Sorry, I forgot to post the scripts. I’m a meathead electrical engineer so I don’t use GIT or anything so here is the code dump. To summarize the setup’s software:

  • cron to run the script that turns the ethernet on and runs rsync to pull data from the server. I have 12 cron entries for the various months/dates/times to run.
  • python script to monitor the button presses for manually running a backup or turning the ethernet port back on
  • bash script that runs the rsync job to pull data from the primary server

The backup script is fairly boring, just runs rsync and pushes the rsync log files back to the primary server. If it fails it sends me an email before turning the ethernet back off and going black.

#So here is my python code that runs the button press:

<pre style="background-color:#ffffff;">
<span style="color:#323232;">#!/usr/bin/env python
</span><span style="color:#323232;">
</span><span style="color:#323232;">import RPi.GPIO as GPIO
</span><span style="color:#323232;">import subprocess
</span><span style="color:#323232;">import time
</span><span style="color:#323232;">from multiprocessing import Process
</span><span style="color:#323232;">
</span><span style="color:#323232;">
</span><span style="color:#323232;">#when this script first runs, at boot, disable ethernet
</span><span style="color:#323232;">time.sleep(5) #wait 5 seconds for system to boot, then try and disable ethernet.
</span><span style="color:#323232;">subprocess.call(['/home/pi/ethernet_updown.sh'], shell=False)
</span><span style="color:#323232;">
</span><span style="color:#323232;">GPIO.setmode(GPIO.BCM)
</span><span style="color:#323232;">GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
</span><span style="color:#323232;">GPIO.setup(22, GPIO.OUT) #controls TFT display backlight
</span><span style="color:#323232;">GPIO.setup(23, GPIO.IN) #pull up or down is optional, the TFT display buttons have a hardware 10k pull up. Measure low tranisitions 
</span><span style="color:#323232;">GPIO.setup(24, GPIO.IN)
</span><span style="color:#323232;">
</span><span style="color:#323232;">
</span><span style="color:#323232;">#watches the button mounted above the USB port, in the Pi's case. 
</span><span style="color:#323232;">def case_button_watch():
</span><span style="color:#323232;">    while True:
</span><span style="color:#323232;">        GPIO.wait_for_edge(3, GPIO.FALLING)
</span><span style="color:#323232;">        #wait 100ms then check if its still low, debounce timer
</span><span style="color:#323232;">        time.sleep(.100)
</span><span style="color:#323232;">        if GPIO.input(3) == GPIO.LOW:
</span><span style="color:#323232;">            #do something as it's a button press
</span><span style="color:#323232;">            print('Button is pressed!')
</span><span style="color:#323232;">            time.sleep(.900)
</span><span style="color:#323232;">            if GPIO.input(3) == GPIO.LOW:
</span><span style="color:#323232;">                #if the button is pressed for over 1 second its a long press. Run the backup script
</span><span style="color:#323232;">                print('Button long press (greater than 1 second), running an unscheduled backup')
</span><span style="color:#323232;">                subprocess.call(['/home/pi/backup.sh'], shell=False)
</span><span style="color:#323232;">            else:
</span><span style="color:#323232;">                #the press was greater than 100mS but less than 1000mS, just toggle the ethernet
</span><span style="color:#323232;">                print('Button short press (less than 1 second), toggling the ethernet')
</span><span style="color:#323232;">                subprocess.call(['/home/pi/ethernet_updown.sh'], shell=False)
</span><span style="color:#323232;">        else:
</span><span style="color:#323232;">            #do nothing as its interference
</span><span style="color:#323232;">            print('GPIO3 debounce failed, it was noise')
</span><span style="color:#323232;">
</span><span style="color:#323232;">#watches the buttons in the TFT display 
</span><span style="color:#323232;">def TFT_display_button1():
</span><span style="color:#323232;">    while True:
</span><span style="color:#323232;">        GPIO.wait_for_edge(23, GPIO.FALLING)
</span><span style="color:#323232;">        #wait 100ms then check if its still low, debounce timer
</span><span style="color:#323232;">        time.sleep(.100)
</span><span style="color:#323232;">        if GPIO.input(23) == GPIO.LOW:
</span><span style="color:#323232;">            #do something as it's a button press
</span><span style="color:#323232;">            print('Button GPIO23 is pressed!')
</span><span style="color:#323232;">            GPIO.output(22, GPIO.HIGH) #turn the backlight ON
</span><span style="color:#323232;">        else:
</span><span style="color:#323232;">            #do nothing as its interference
</span><span style="color:#323232;">            print('GPIO23 debounce failed, it was noise')
</span><span style="color:#323232;">
</span><span style="color:#323232;">#watches the buttons in the TFT display
</span><span style="color:#323232;">def TFT_display_button2():
</span><span style="color:#323232;">    while True:
</span><span style="color:#323232;">        GPIO.wait_for_edge(24, GPIO.FALLING)
</span><span style="color:#323232;">        #wait 100ms then check if its still low, debounce timer
</span><span style="color:#323232;">        time.sleep(.100)
</span><span style="color:#323232;">        if GPIO.input(24) == GPIO.LOW:
</span><span style="color:#323232;">            #do something as it's a button press
</span><span style="color:#323232;">            print('Button GPIO24 is pressed!')
</span><span style="color:#323232;">            GPIO.output(22, GPIO.LOW) #turn the backlight OFF
</span><span style="color:#323232;">        else:
</span><span style="color:#323232;">            #do nothing as its interference
</span><span style="color:#323232;">            print('GPIO24 debounce failed, it was noise')
</span><span style="color:#323232;">
</span><span style="color:#323232;">if __name__ == '__main__':
</span><span style="color:#323232;">
</span><span style="color:#323232;">    #run three parallel processes to watch all three buttons with software debounce
</span><span style="color:#323232;">    proc1 = Process(target=case_button_watch)
</span><span style="color:#323232;">    proc1.start()
</span><span style="color:#323232;">
</span><span style="color:#323232;">    proc2 = Process(target=TFT_display_button1)
</span><span style="color:#323232;">    proc2.start()
</span><span style="color:#323232;">
</span><span style="color:#323232;">    proc3 = Process(target=TFT_display_button2)
</span><span style="color:#323232;">    proc3.start()
</span>

#bash script that toggles the ethernet - if its on, it turns it off. if its off, it turns it on:

<pre style="background-color:#ffffff;">
<span style="color:#323232;">#!/bin/bash
</span><span style="color:#323232;">
</span><span style="color:#323232;">if sudo ifconfig | grep 'eth0' | grep 'RUNNING' > /dev/null; 
</span><span style="color:#323232;">then 
</span><span style="color:#323232;">    wall -n "$(date +"%Y%m%d_%H%M%S"):Ethernet going down"
</span><span style="color:#323232;">    sudo ifconfig eth0 down	
</span><span style="color:#323232;">else 
</span><span style="color:#323232;">    wall -n "$(date +"%Y%m%d_%H%M%S"):Ethernet going up"
</span><span style="color:#323232;">    sudo ifconfig eth0 up
</span><span style="color:#323232;">fi
</span>
ANotSoSlyLawnTurtle ,

I very much feel the desire to stay away from Git repos for singular scripts like this. Maybe consider making it a gist though. Easier to keep track of by starring it in GitHub and perhaps even iterate on it in the future. :)

czardestructo OP ,
@czardestructo@lemmy.world avatar

I use Joplin notes to track my code revisions. It’s incredibly crude but it works and keeps my documention private and is also my wiki for each server so I know what the heck I setup and did.

randint , to fediverse in Lemmy active users grew by an astounding 1600% in June
@randint@lemmy.world avatar

Awesome!

Vaulter , to android in Boost for Lemmy is happening!
@Vaulter@lemmy.world avatar

Super keen, boost was the only app that gets any proper use on my phone

Amilo159 , to fediverse in Lemmy active users grew by an astounding 1600% in June
@Amilo159@lemmy.world avatar

I didn't know what Lemmy is but since Reddit killed my Baconreader, I couldn't go support their garbage app. So this seems nice.

Staark , to mildlyinfuriating in The price of a cinema ticket in this day and age. No wonder people aren't going to the cinema anymore.

Those prices are wild, but what the hell is a convenience fee? Is that just some bull that they've come up with to charge more?

Son_of_dad , to mildlyinfuriating in The price of a cinema ticket in this day and age. No wonder people aren't going to the cinema anymore.

Movies are releasing into streaming at record pace these days too, so I skip the cinema altogether now. Used to be you’d wait half a year for a movie to go from theaters to video, now it’s up on a streaming service the moment its theater run is finished.

ThoseGDSquirrels , to futurama in To all the new(er) Reddit refugees!
@ThoseGDSquirrels@lemmy.world avatar

The world of tomorrow seems fun ! I really like it here

demesisx , to programmerhumor in works on my machine
@demesisx@lemmy.world avatar

How long until nix flakes go mainstream and fix this problem?

mea_rah ,

Replace “nix flakes” with “Docker” and you have your answer from almost decade ago.

demesisx ,
@demesisx@lemmy.world avatar

No offense but it sounds like you don’t actually understand nix flakes if you think they’re 1:1 equivalent to Docker.

They simply are not containers. They allow the declarative BUILD of any derivation at any time in the future. They hermetically lock all dependencies and build instructions which allows you to archive and reproduce the EXACT content-addressed dependency graph of the software. You can rebuild using a flake while Docker doesn’t actually allow that same hermetic reproducible guarantee whatsoever.

See here for a much better explanation of the glaring differences between the two: youtu.be/0uixRE8xlbY

You could even build a container with a flake though I’d recommend OCI instead because they’re an open standard…

mea_rah ,

This is programmerhumor so perhaps allow for a bit of hyperbole on my part. I wasn’t completely factual.

However the initial days of Docker were effectively promising to solve the exact same “it works on my laptop” problem. The idea was that developer builds docker image and pushes it to repository where it can pass through CI and eventually the same image gets to production.

As you can see, this effectively reproduces the EXACT content as well, because you transfer the files in a set of tar files.

It didn’t work for many reasons. One of which is the fact that it’s often not so much about the exact files, but the rest of the environment like DBs, proxies, networking, etc that is the problem. I’ve seen image misbehaving in production due to different kernel version/configuration.

demesisx ,
@demesisx@lemmy.world avatar

I know it’s a strange place for this conversation but the facts remain: docker images don’t do this and nix flakes actually do. As the video I linked demonstrates and you allude to, Docker files aren’t 100% hermetic (which means they’re not reproducible) while Nix flakes actually do achieve this. Watch the video I linked for more explanation which directly talks about how nix works with the goals of Docker that you mentioned in the head of your last comment. I hope my non-confrontational tone comes across somehow. This is all said with respect and in the spirit of science.

mea_rah ,

First of all. Thank you for civil discussion. As you say this is weird place to have such discussion, but it’s also true that these jokes often have some kernel of truth to them that makes these discussions happen organically.

So with that out of the way and with no bad intentions on my side:

I’ve noticed you use Dockerfiles and Docker Images interchangeably. And this might be the core of misunderstanding here. What I was describing is that:

  • Developer builds an image (using Dockerfile or otherwise) on their laptop and then pushes that image to a Docker repository.
  • This exact same image is then used in CI to do integration tests, scanning, whatever…
  • If all is good, this image is then deployed to production.

So if you compare sha of the image in production and on developers laptop, they are the same checksums. Files are identical. Nix arrives to this destination kind of from the other side. Arguably in more elegant way, but in both cases files are the same.

This was the promise (or one possibility) in the early days of Docker. Obviously there are some problems with this approach. Like what if CPU architecture of the laptop differs from production server? Well that wasn’t a problem back in 2014, because ARM servers just didn’t exist. (Not in any meaningful way) There’s also this disconnection between the code that generates the image and the image itself, that goes to production. How do you trust environment (laptop) where image is built. Etc… So it just didn’t stick as a deployment pattern.

Many of these things Nix solves. But in terms of “it works on my laptop” what I wrote in previous comment applies. The environment differences themselves rather than slightly different build artefacts is what’s frequently the problem. Nix is not going to solve the problem of slightly different databases because developer is runing MariaDB locally to test, but in production we use DB managed by AWS. Developer is not going to catch this quirky behavior of how his app responds to proxy, because they do not run AWS ELB on their laptop, but production is behind it. You get the idea.

When developer says it works okay on their laptop, what it usually means is the they do not have 100% copy of production locally (because obviously they don’t) and that as a result they didn’t encounter this specific failure mode.

Which is not to say, that Nix is bad idea. Nix is great. I’m just saying that there’s more to the “laptop problem” than just reproducible builds - we had those even before Docker Images.

Hope that makes sense. And again, thanks for civil discussion.

MikeFlame , to futurama in To all the new(er) Reddit refugees!
@MikeFlame@lemmy.world avatar

Came from RIF. Let’s gooooo

zhaozhaoer , to cat in Rascalina found a new box.

Aww look at that pink nose 🥰🥰🥰🥰🥰

anma , to cat in Subscribe To His OnlyKitties 😹
@anma@kbin.social avatar

@deepdivedylan Where face?? 😂

drewx0r , to aww in Cats in lanzarote

They’re both gorgeous, although the Siamese looks like it’s got evil intent!

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • lifeLocal
  • goranko
  • All magazines