mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fix 0.3.3 OTA update flow for pi (#2048)
* feat: Conver from the copy all bytes over to file-file transer * use pi-beep * fix minor mistakes * recursive rm * add fs resize Co-authored-by: BluJ <mogulslayer@gmail.com>
This commit is contained in:
7
Makefile
7
Makefile
@@ -62,11 +62,11 @@ format:
|
||||
sdk:
|
||||
cd backend/ && ./install-sdk.sh
|
||||
|
||||
embassyos-raspi.img: all raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast
|
||||
embassyos-raspi.img: all raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep
|
||||
! test -f embassyos-raspi.img || rm embassyos-raspi.img
|
||||
./build/raspberry-pi/make-image.sh
|
||||
|
||||
lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $(BUILD_SRC) eos.raspberrypi.squashfs
|
||||
lite-upgrade.img: raspios.img cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $(BUILD_SRC) eos.raspberrypi.squashfs
|
||||
! test -f lite-upgrade.img || rm lite-upgrade.img
|
||||
./build/raspberry-pi/make-upgrade-image.sh
|
||||
|
||||
@@ -176,3 +176,6 @@ backend: $(EMBASSY_BINS)
|
||||
|
||||
cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast:
|
||||
./build-cargo-dep.sh nc-broadcast
|
||||
|
||||
cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep:
|
||||
./build-cargo-dep.sh pi-beep
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::path::Path;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
|
||||
use divrem::DivRem;
|
||||
use proptest_derive::Arbitrary;
|
||||
@@ -8,92 +7,24 @@ use tokio::process::Command;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::util::{FileLock, Invoke};
|
||||
use crate::{Error, ErrorKind, ResultExt};
|
||||
use crate::{Error, ErrorKind};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref SEMITONE_K: f64 = 2f64.powf(1f64 / 12f64);
|
||||
static ref A_4: f64 = 440f64;
|
||||
static ref C_0: f64 = *A_4 / SEMITONE_K.powf(9f64) / 2f64.powf(4f64);
|
||||
static ref EXPORT_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/export");
|
||||
static ref UNEXPORT_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/unexport");
|
||||
static ref PERIOD_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/period");
|
||||
static ref DUTY_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/duty_cycle");
|
||||
static ref SWITCH_FILE: &'static Path = Path::new("/sys/class/pwm/pwmchip0/pwm0/enable");
|
||||
}
|
||||
|
||||
pub const SOUND_LOCK_FILE: &'static str = "/etc/embassy/sound.lock";
|
||||
|
||||
struct SoundInterface {
|
||||
use_beep: bool,
|
||||
guard: Option<FileLock>,
|
||||
}
|
||||
impl SoundInterface {
|
||||
#[instrument]
|
||||
pub async fn lease() -> Result<Self, Error> {
|
||||
let guard = FileLock::new(SOUND_LOCK_FILE, true).await?;
|
||||
if Command::new("which")
|
||||
.arg("beep")
|
||||
.invoke(ErrorKind::NotFound)
|
||||
.await
|
||||
.is_ok()
|
||||
{
|
||||
Ok(SoundInterface {
|
||||
use_beep: true,
|
||||
guard: Some(guard),
|
||||
})
|
||||
} else {
|
||||
tokio::fs::write(&*EXPORT_FILE, "0")
|
||||
.await
|
||||
.or_else(|e| {
|
||||
if e.raw_os_error() == Some(16) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
})
|
||||
.with_ctx(|_| (ErrorKind::SoundError, EXPORT_FILE.to_string_lossy()))?;
|
||||
let instant = Instant::now();
|
||||
while tokio::fs::metadata(&*PERIOD_FILE).await.is_err()
|
||||
&& instant.elapsed() < Duration::from_secs(1)
|
||||
{
|
||||
tokio::time::sleep(Duration::from_millis(1)).await;
|
||||
}
|
||||
Ok(SoundInterface {
|
||||
use_beep: false,
|
||||
guard: Some(guard),
|
||||
})
|
||||
}
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
async fn play_pwm(&mut self, note: &Note) -> Result<(), Error> {
|
||||
let curr_period = tokio::fs::read_to_string(&*PERIOD_FILE)
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?;
|
||||
if curr_period == "0\n" {
|
||||
tokio::fs::write(&*PERIOD_FILE, "1000")
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?;
|
||||
}
|
||||
let new_period = ((1.0 / note.frequency()) * 1_000_000_000.0).round() as u64;
|
||||
tokio::fs::write(&*DUTY_FILE, "0")
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, DUTY_FILE.to_string_lossy()))?;
|
||||
tokio::fs::write(&*PERIOD_FILE, format!("{}", new_period))
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, PERIOD_FILE.to_string_lossy()))?;
|
||||
tokio::fs::write(&*DUTY_FILE, format!("{}", new_period / 2))
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, DUTY_FILE.to_string_lossy()))?;
|
||||
tokio::fs::write(&*SWITCH_FILE, "1")
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, SWITCH_FILE.to_string_lossy()))?;
|
||||
Ok(())
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
async fn stop_pwm(&mut self) -> Result<(), Error> {
|
||||
tokio::fs::write(&*SWITCH_FILE, "0")
|
||||
.await
|
||||
.with_ctx(|_| (ErrorKind::SoundError, SWITCH_FILE.to_string_lossy()))
|
||||
Ok(SoundInterface { guard: Some(guard) })
|
||||
}
|
||||
#[instrument(skip(self))]
|
||||
pub async fn close(mut self) -> Result<(), Error> {
|
||||
@@ -109,29 +40,13 @@ impl SoundInterface {
|
||||
note: &Note,
|
||||
time_slice: &TimeSlice,
|
||||
) -> Result<(), Error> {
|
||||
if self.use_beep {
|
||||
Command::new("beep")
|
||||
.arg("-f")
|
||||
.arg(note.frequency().to_string())
|
||||
.arg("-l")
|
||||
.arg(time_slice.to_duration(tempo_qpm).as_millis().to_string())
|
||||
.invoke(ErrorKind::SoundError)
|
||||
.await?;
|
||||
} else {
|
||||
if let Err(e) = async {
|
||||
self.play_pwm(note).await?;
|
||||
tokio::time::sleep(time_slice.to_duration(tempo_qpm) * 19 / 20).await;
|
||||
self.stop_pwm().await?;
|
||||
tokio::time::sleep(time_slice.to_duration(tempo_qpm) / 20).await;
|
||||
Ok::<_, Error>(())
|
||||
}
|
||||
.await
|
||||
{
|
||||
// we could catch this error and propagate but I'd much prefer the original error bubble up
|
||||
let _mute = self.stop_pwm().await;
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
Command::new("beep")
|
||||
.arg("-f")
|
||||
.arg(note.frequency().to_string())
|
||||
.arg("-l")
|
||||
.arg(time_slice.to_duration(tempo_qpm).as_millis().to_string())
|
||||
.invoke(ErrorKind::SoundError)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -164,15 +79,8 @@ where
|
||||
|
||||
impl Drop for SoundInterface {
|
||||
fn drop(&mut self) {
|
||||
let use_beep = self.use_beep;
|
||||
let guard = self.guard.take();
|
||||
tokio::spawn(async move {
|
||||
if !use_beep {
|
||||
if let Err(e) = tokio::fs::write(&*UNEXPORT_FILE, "0").await {
|
||||
tracing::error!("Failed to Unexport Sound Interface: {}", e);
|
||||
tracing::debug!("{:?}", e);
|
||||
}
|
||||
}
|
||||
if let Some(guard) = guard {
|
||||
if let Err(e) = guard.unlock().await {
|
||||
tracing::error!("Failed to drop Sound Interface File Lock: {}", e);
|
||||
|
||||
@@ -2,10 +2,30 @@
|
||||
|
||||
set -e
|
||||
|
||||
(
|
||||
while true; do
|
||||
beep -r 2 -l 80 -d 20
|
||||
sleep 60
|
||||
done
|
||||
) &
|
||||
|
||||
if grep 'cb15ae4d-03' /boot/cmdline.txt; then
|
||||
BLOCK_COUNT=$(tune2fs -l /dev/mmcblk0p3 | grep "^Block count:" | awk '{print $3}')
|
||||
BLOCK_SIZE=$(tune2fs -l /dev/mmcblk0p3 | grep "^Block size:" | awk '{print $3}')
|
||||
cat /dev/mmcblk0p3 | head -c $[$BLOCK_COUNT * $BLOCK_SIZE] > /dev/mmcblk0p4
|
||||
echo Transfer files across
|
||||
e2fsck -f -y /dev/mmcblk0p4
|
||||
while ! resize2fs /dev/mmcblk0p4; do
|
||||
e2fsck -f -y /dev/mmcblk0p4
|
||||
done
|
||||
mkdir -p /media/origin
|
||||
mkdir -p /media/dest
|
||||
mount -r /dev/mmcblk0p3 /media/origin
|
||||
mount -w /dev/mmcblk0p4 /media/dest
|
||||
rsync -acvAXUH --info=progress2 --delete --force /media/origin/ /media/dest/
|
||||
umount /media/origin
|
||||
umount /media/dest
|
||||
rm -rf /media/origin
|
||||
rm -rf /media/dest
|
||||
|
||||
echo Setting up boot to use other partition
|
||||
sed -i 's/PARTUUID=cb15ae4d-03/PARTUUID=cb15ae4d-04/g' /boot/cmdline.txt
|
||||
sync
|
||||
reboot
|
||||
|
||||
@@ -26,9 +26,11 @@ sudo mount $TARGET_NAME $TMPDIR/
|
||||
|
||||
sudo mkdir -p $TMPDIR/update
|
||||
sudo unsquashfs -f -d $TMPDIR/update eos.raspberrypi.squashfs
|
||||
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep
|
||||
sudo cp ./build/raspberry-pi/033-upgrade.sh $TMPDIR/usr/local/bin/033-upgrade.sh
|
||||
sudo cp ./build/raspberry-pi/033-upgrade.service $TMPDIR/etc/systemd/system/033-upgrade.service
|
||||
sudo ln -s /etc/systemd/system/033-upgrade.service $TMPDIR/etc/systemd/system/multi-user.target.wants/033-upgrade.service
|
||||
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin
|
||||
sudo cp ./build/raspberry-pi/nc-broadcast.service $TMPDIR/etc/systemd/system/nc-broadcast.service
|
||||
sudo ln -s /etc/systemd/system/nc-broadcast.service $TMPDIR/etc/systemd/system/multi-user.target.wants/nc-broadcast.service
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ sudo mkdir $TMPDIR/media/embassy/
|
||||
sudo ENVIRONMENT=$ENVIRONMENT make V=1 install ARCH=aarch64 OS_ARCH=raspberrypi DESTDIR=$TMPDIR --debug
|
||||
sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hostname
|
||||
sudo sed -i 's/raspberrypi/embassy/g' $TMPDIR/etc/hosts
|
||||
sudo cp ./cargo-deps/aarch64-unknown-linux-gnu/release/pi-beep $TMPDIR/usr/local/bin/beep
|
||||
sudo cp cargo-deps/aarch64-unknown-linux-gnu/release/nc-broadcast $TMPDIR/usr/local/bin
|
||||
sudo cp backend/*.service $TMPDIR/etc/systemd/system/
|
||||
sudo mkdir -p $TMPDIR/etc/embassy
|
||||
|
||||
Reference in New Issue
Block a user