Skip to content

Commit

Permalink
Add zed event system_boot add more ps1 scripts
Browse files Browse the repository at this point in the history
Attempt to mimic Unix zed.d scripts with
equivalent for powershell.

Add new script system_boot.ps1 to import
pools if zpool.cache file exists.

Signed-off-by: Jorgen Lundman <lundman@lundman.net>
  • Loading branch information
lundman committed Nov 22, 2024
1 parent f655c6e commit e9ca6cb
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 193 deletions.
39 changes: 39 additions & 0 deletions cmd/zed/os/windows/zed.d/system_boot.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/powershell
# shellcheck disable=SC2154
#
# Log all environment variables to ZED_DEBUG_LOG.
#
# This can be a useful aid when developing/debugging ZEDLETs since it shows the
# environment variables defined for each zevent.

if (Test-Path "$env:ZED_ZEDLET_DIR\zed.rc") {
. "$env:ZED_ZEDLET_DIR\zed.rc"
}
if (Test-Path "$env:ZED_ZEDLET_DIR\zed-functions.ps1") {
. "$env:ZED_ZEDLET_DIR\zed-functions.ps1"
}

#
# system_boot.ps1
#

# Define the path to the zpool.cache file
$zpoolCachePath = "C:\Windows\System32\Drivers\zpool.cache"

# Check if the zpool.cache file exists
if (Test-Path $zpoolCachePath) {
Write-Host "zpool.cache found. Importing ZFS pools..."
zed_log_msg(LOG_NOTICE, "zpool.cache found. Importing ZFS pools");

# Import ZFS pools using the zpool command and the cache file
$zpoolImportCommand = "$env:ZPOOL import -c $zpoolCachePath"

# Execute the command
$result = Invoke-Expression $zpoolImportCommand

# Optionally, log the result or handle any output
Write-Host "ZFS Pools Imported: $result"
zed_notify("ZFS Pools Imported", "path");
} else {
Write-Host "zpool.cache not found. No pools imported."
}
225 changes: 172 additions & 53 deletions cmd/zed/os/windows/zed.d/zed-functions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,71 +3,72 @@
# 2024 Jorgen Lundman <lundman@lundman.net>
#

# This one doesn't need any extra PS modules, but is
# ugly.
function Show-PlainToastNotification {
# zed_log_msg (msg, ...)
#
# Write all argument strings to the system log.
#
# Globals
# ZED_SYSLOG_PRIORITY
# ZED_SYSLOG_TAG
#
# Return
# nothing
#
function zed_log_msg {
param (
[string]$Title = "ZED Notification",
[string]$Message = "Default message"
[string]$priority,
[string]$tag,
[string]$message
)

# Load the required assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

# Create a form to act as a notification
$form = New-Object System.Windows.Forms.Form
$form.StartPosition = 'Manual'
$form.Location = New-Object System.Drawing.Point(0, 0)
$form.Size = New-Object System.Drawing.Size(300, 100)
$form.FormBorderStyle = 'None'
$form.BackColor = [System.Drawing.Color]::White
$form.TopMost = $true
$form.ShowInTaskbar = $false
$form.Opacity = 0.9

# Create a label for the title
$titleLabel = New-Object System.Windows.Forms.Label
$titleLabel.Text = $Title
$titleLabel.Font = New-Object System.Drawing.Font("Arial", 14, [System.Drawing.FontStyle]::Bold)
$titleLabel.AutoSize = $true
$titleLabel.Location = New-Object System.Drawing.Point(10, 10)

# Create a label for the message
$messageLabel = New-Object System.Windows.Forms.Label
$messageLabel.Text = $Message
$messageLabel.AutoSize = $true
$messageLabel.Location = New-Object System.Drawing.Point(10, 40)

# Add the labels to the form
$form.Controls.Add($titleLabel)
$form.Controls.Add($messageLabel)

# Show the form
$form.Show()

# Timer to close the notification after 5 seconds
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 5000 # milliseconds
$timer.Add_Tick({
$form.Close()
$timer.Stop()
})
$timer.Start()

# Run the form's message loop
[System.Windows.Forms.Application]::Run($form)
# Check if the event source exists, create it if not
$eventSource = "OpenZFS_zed"
if (-not (EventLog SourceExists $eventSource)) {
New-EventLog -LogName Application -Source $eventSource
}

# Create the log message with priority and tag
$logMessage = "[$priority] [$tag] $message"

# Log the message to the Windows Event Log
Write-EventLog -LogName Application -Source $eventSource -EntryType Information -EventId 1001 -Message $logMessage
}

function zed_log_err {
param (
[string]$priority,
[string]$tag,
[string]$message
)

# Create the log entry format
$logEntry = "$(Get-Date) [$priority] [$tag] $message"

# Check if the event source exists, create it if not
$eventSource = "ZED"
if (-not (EventLog SourceExists $eventSource)) {
New-EventLog -LogName Application -Source $eventSource
}

# Log to the Windows Event Log as an Error (higher priority)
Write-EventLog -LogName Application -Source $eventSource -EntryType Error -EventId 1002 -Message $logEntry
}


# For real notifications to work, run in powershell (Admin)
# "Install-Module -Name BurntToast -Force -AllowClobber"
# Failing that, fall back to a regular MessageBox
function Show-ToastNotification {
function zed_notify_burnttoast()
{
param (
[string]$Title = "Notification",
[string]$Message = "This is a test notification."
)

if (-not $env:ZED_BURNTTOAST_NOTIFICATIONS) {
return 2
}

# Check if the BurntToast module is available
if (Get-Module -ListAvailable -Name BurntToast) {
try {
Expand All @@ -90,8 +91,51 @@ function Show-ToastNotification {
}
}

function zed_notify_toast
{
param (
[string]$subject,
[string]$pathname
)

if (-not $env:ZED_TOAST_NOTIFICATIONS) {
return 2
}

# Check if the 'subject' (title) is provided, otherwise use a default
if (-not $subject) {
$subject = "OpenZFS Notification"
}

# Create the message text from the pathname or fallback to the subject
$message = if ($pathname) { "Details: $pathname" } else { "No additional details provided" }

# Create the Toast notification
$toastXml = @"
<toast>
<visual>
<binding template="ToastGeneric">
<text>$subject</text>
<text>$message</text>
</binding>
</visual>
</toast>
"@

# Create the Toast notification
$toast = [Windows.UI.Notifications.ToastNotification]::new([Windows.Data.Xml.Dom.XmlDocument]::new())
$toast.XmlDocument.LoadXml($toastXml)

# Display the Toast
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("ZFSNotificationApp").Show($toast)

# Return success (0)
return 0
}

# Function to show a message box
function Show-MessageBox {
function zed_notify_messagebox
{
param (
[string]$Message,
[string]$Title
Expand All @@ -104,4 +148,79 @@ function Show-MessageBox {
[System.Windows.Forms.MessageBox]::Show($Message, $Title)
}

zed_notify()
{
local subject="$1"
local pathname="$2"
local num_success=0
local num_failure=0

# Call zed_notify_toast (Windows-specific toast notification)
zed_notify_toast "$subject" "$pathname"
rv=$?
[ "$rv" -eq 0 ] && num_success=$((num_success + 1))
[ "$rv" -eq 1 ] && num_failure=$((num_failure + 1))

zed_notify_burnttoast "$subject" "$pathname"
rv=$?
[ "$rv" -eq 0 ] && num_success=$((num_success + 1))
[ "$rv" -eq 1 ] && num_failure=$((num_failure + 1))

# Additional notification methods could go here (email, pushbullet, etc.)

# If we had any success, return success code
if [ "$num_success" -gt 0 ]; then
return 0
fi

# If we had any failure, return failure code
if [ "$num_failure" -gt 0 ]; then
return 1
fi

# If no methods were configured, return 2
return 2
}


# zed_guid_to_pool (guid)
#
# Convert a pool GUID into its pool name (like "tank")
# Arguments
# guid: pool GUID (decimal or hex)
#
# Return
# Pool name
function zed_guid_to_pool
{
param (
[Parameter(Mandatory=$true)]
[string]$guid
)

if (-not $guid) {
return # Return nothing if no GUID is provided
}

# Check if the GUID is in hex format (starts with "0x")
if ($guid.StartsWith("0x", [StringComparison]::OrdinalIgnoreCase)) {
# Strip the "0x" prefix and convert it to a decimal number
$guid = [Convert]::ToUInt64($guid.Substring(2), 16)
}

# Run the zpool command to get the pool name for the GUID
try {
$poolName = & $env:ZPOOL get -H -ovalue,name guid | Where-Object { $_ -match "^$guid\s+(\S+)$" } | ForEach-Object { $_ -replace "^$guid\s+", "" }

if ($poolName) {
return $poolName
} else {
Write-Host "Pool not found for GUID: $guid"
return ""
}
}
catch {
Write-Error "Error querying zpool: $_"
return ""
}
}
13 changes: 13 additions & 0 deletions cmd/zed/os/windows/zed.d/zed.rc
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,16 @@ $env:ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"
# Gotify application associated with ZED_GOTIFY_APPTOKEN.
# Value is an integer 0 and up.
#$env:ZED_GOTIFY_PRIORITY=""

##
# Use Toast notification (optional)
# If defined, use system Toast notifications
# Value is an integer 0 and up.
$env:ZED_TOAST_NOTIFICATIONS = 1

##
# Use BurntToast notification(optional)
# If defined, use Burnt Toast notifications
# Installed with "Install-Module -Name BurntToast -Force -AllowClobber"
# Value is an integer 0 and up.
$env:ZED_BURNTTOAST_NOTIFICATIONS = 1
Loading

0 comments on commit e9ca6cb

Please sign in to comment.