Merge pull request #574 from eylenburg/timesync

Add a function to sync time in Windows after Linux host is suspended (sleeping)
This commit is contained in:
Oskar Manhart
2025-09-08 09:11:46 +02:00
committed by GitHub
3 changed files with 96 additions and 0 deletions

View File

@@ -27,6 +27,8 @@ readonly CONFIG_PATH="${HOME}/.config/winapps/winapps.conf"
readonly COMPOSE_PATH="${HOME}/.config/winapps/compose.yaml"
# shellcheck disable=SC2155 # Silence warnings regarding masking return values through simultaneous declaration and assignment.
readonly SCRIPT_DIR_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
readonly SLEEP_DETECT_PATH="${APPDATA_PATH}/last_activity"
readonly SLEEP_MARKER="${APPDATA_PATH}/sleep_marker"
# OTHER
readonly CONTAINER_NAME="WinApps" # FOR 'docker' AND 'podman' ONLY
@@ -736,6 +738,50 @@ function waCheckIdle() {
fi
}
# Name: 'waTimeSync'
# Role: Detect if system went to sleep by comparing uptime progression, then sync time in Windows VM
function waTimeSync() {
local CURRENT_TIME
local CURRENT_UPTIME
local STORED_TIME=0
local STORED_UPTIME=0
local EXPECTED_UPTIME=0
local UPTIME_DIFF=0
CURRENT_TIME=$(date +%s)
CURRENT_UPTIME=$(awk '{print int($1)}' /proc/uptime)
# Read stored values if file exists
if [ -f "$SLEEP_DETECT_PATH" ]; then
STORED_TIME=$(head -n1 "$SLEEP_DETECT_PATH" 2>/dev/null || echo 0)
STORED_UPTIME=$(tail -n1 "$SLEEP_DETECT_PATH" 2>/dev/null || echo 0)
fi
if [ "$STORED_TIME" -gt 0 ] && [ "$STORED_UPTIME" -gt 0 ]; then
# Calculate what uptime should be now
EXPECTED_UPTIME=$((STORED_UPTIME + CURRENT_TIME - STORED_TIME))
UPTIME_DIFF=$((EXPECTED_UPTIME - CURRENT_UPTIME))
dprint "UPTIME_DIFF: ${UPTIME_DIFF} seconds"
# If uptime is significantly less than expected, system likely slept
if [[ "$UPTIME_DIFF" -gt 30 && ! -f "$SLEEP_MARKER" ]]; then
dprint "DETECTED SLEEP/WAKE CYCLE (uptime gap: ${UPTIME_DIFF}s). CREATING SLEEP MARKER TO SYNC WINDOWS TIME."
# Create sleep marker which will be monitored by Windows VM to trigger time sync
touch "$SLEEP_MARKER"
dprint "CREATED SLEEP MARKER"
fi
fi
# Store current values
{
echo "$CURRENT_TIME"
echo "$CURRENT_UPTIME"
} > "$SLEEP_DETECT_PATH"
}
### MAIN LOGIC ###
#set -x # Enable for debugging.
dprint "START"
@@ -765,6 +811,7 @@ else
fi
waCheckPortOpen
waTimeSync
waRunCommand "$@"
if [[ "$AUTOPAUSE" == "on" ]]; then

32
oem/TimeSync.ps1 Normal file
View File

@@ -0,0 +1,32 @@
# Script to monitor if there is a sleep_marker created by WinApps (indicating the Linux host was suspended) in order to trigger a time sync as the time in the Windows VM will otherwise drift while Linux is suspended.
# Define the path to monitor. Make sure this matches the location for the sleep_marker in the Winapps script (need to match the APPDATA path).
$filePath = "\\tsclient\home\.local\share\winapps\sleep_marker"
$networkPath = "\\tsclient\home"
# Function to check and handle file
function Monitor-File {
while ($true) {
# Check if network location is available
try {
$null = Test-Path -Path $networkPath -ErrorAction Stop
# Check if file exists
if (Test-Path -Path $filePath) {
# Run time resync silently
w32tm /resync /quiet
# Remove the file
Remove-Item -Path $filePath -Force
}
}
catch {
# Network location not available, continue monitoring silently
}
# Wait 5 minutes before next check
Start-Sleep -Seconds 3000
}
}
# Start monitoring silently
Monitor-File

View File

@@ -77,3 +77,20 @@ if %ERRORLEVEL% neq 0 (
echo [ERROR] Failed to create scheduled task "%taskname%".
)
)
REM Create time sync task to be run by the user at login
copy %~dp0\TimeSync.ps1 %windir%
set "taskname2=TimeSync"
set "command2=powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -File \"%windir%\TimeSync.ps1\""
schtasks /query /tn "%taskname2%" >nul
if %ERRORLEVEL% equ 0 (
echo %DATE% %TIME% Task "%taskname2%" already exists, skipping creation.
) else (
schtasks /create /tn "%taskname2%" /tr "%command2%" /sc onlogon /rl HIGHEST /f
if %ERRORLEVEL% equ 0 (
echo %DATE% %TIME% Scheduled task "%taskname2%" created successfully.
) else (
echo %DATE% %TIME% Failed to create scheduled task %taskname2%.
)
)