11 Commits

Author SHA1 Message Date
matmoul c56aec350d docs: tighten project conventions for mtm-ddwipe 2026-04-27 23:46:51 +02:00
matmoul 956cfd7325 fix: tighten mtm-ddwipe usage and device checks
Add an explicit mounted-device check with findmnt, shorten confirmation prompts, and align the usage text and log wording with the current script name.
2026-04-27 23:40:28 +02:00
matmoul 55c55a4a08 feat: strengthen wipe safety checks and confirmation flow
Add mounted/in-use device detection, show detailed device info before confirmation, and require an exact wipe phrase to proceed. Also move status output to stderr and refresh the usage warnings for clearer destructive-action guidance.
2026-04-27 23:37:40 +02:00
matmoul ecc6e5b038 fix: harden mtm-ddwipe confirmation and wipe flow
Add strict shell options, root and block-device validation, and a typed-device confirmation prompt before wiping. Preserve the fallback wipe sequence through secure discard, zero discard, and dd, while tightening error handling and keeping messages concise.
2026-04-27 23:32:45 +02:00
matmoul 7011426381 docs: clarify mtm-ddwipe safety and prompt conventions 2026-04-27 23:20:07 +02:00
matmoul b01e72cba6 fix: improve mtm-ddwipe argument handling and timing output 2026-04-27 23:17:16 +02:00
matmoul 08d6ccde0d docs: tighten mtm-ddwipe help and project guidance 2026-04-27 23:05:22 +02:00
matmoul 7321d7e087 docs: update project rules for safer wipe behavior 2026-04-27 23:02:14 +02:00
matmoul 7609bf9c17 feat: improve release script with dry-run and version increments 2026-04-27 22:57:08 +02:00
matmoul 80c87e282b Some infos update 2024-05-07 02:23:49 +02:00
matmoul 4922d1e369 Some infos update 2024-05-07 02:23:06 +02:00
3 changed files with 297 additions and 72 deletions
+23
View File
@@ -0,0 +1,23 @@
---
description: mtm-ddwipe project conventions
---
# Project conventions
- Use English.
- Use Bash for shell scripts.
- Keep `mtm-ddwipe` focused on wiping block devices.
- Keep `mtm-ddwipe` interactive by default.
- Require explicit confirmation before destructive actions.
- Validate real block devices and refuse mounted or in-use targets.
- Show clear device details before confirmation.
- Keep destructive safeguards strict and explicit.
- Keep messages short and clear.
- Keep help concise, usage-first, and warning-focused.
- Preserve the fallback wipe flow: secure discard, zero discard, then `dd` zero-fill.
- Keep changes minimal and preserve intent.
- Keep `./continue/rules/project.md` aligned and concise.
- If non-interactive support is added, make it an opt-in safety flag.
# Project identity
- Main script: `mtm-ddwipe`
- License: GNU GPL v3
+112 -9
View File
@@ -1,32 +1,135 @@
#!/bin/bash
declare -r VERSION=${1}
declare -r MESSAGE=${2}
set -euo pipefail
declare -r TAGBRANCH=main
declare CURRENTBRANCH=""
declare ORIGBRANCH=""
declare -r ARG1="${1:-}"
declare -r ARG2="${2:-}"
declare is_dry_run=false
declare release_input=""
showHelp() {
echo makerelease version
cat <<'EOF'
Usage:
makerelease.sh VERSION
makerelease.sh +0.0.1
makerelease.sh +0.1
makerelease.sh +1
makerelease.sh --dry-run VERSION
makerelease.sh --dry-run +0.0.1
makerelease.sh --dry-run +0.1
makerelease.sh --dry-run +1
Creates an annotated Git tag from the current dev branch.
If VERSION starts with +, it is treated as an increment:
- +0.0.1 increments patch
- +0.1 increments minor
- +1 increments major
Use --dry-run to show the computed release version without running Git actions.
Requirements:
- run from a clean Git working tree
- current branch must be dev for real releases
- main branch must exist locally
EOF
}
if [ "${VERSION}" == "" ]; then
cleanup() {
if [ -n "${ORIGBRANCH}" ] && [ "${CURRENTBRANCH}" != "${ORIGBRANCH}" ]; then
git checkout "${ORIGBRANCH}" >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT
if [ "${ARG1}" = "--dry-run" ] || [ "${ARG1}" = "-n" ]; then
is_dry_run=true
release_input="${ARG2:-}"
else
release_input="${ARG1}"
fi
if [ -z "${release_input}" ]; then
showHelp
echo ""
echo "no version provided!"
exit 1
fi
CURRENTBRANCH=$(git rev-parse --abbrev-ref HEAD)
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
echo "You are not inside a Git repository!"
exit 1
fi
if [ ! "${CURRENTBRANCH}" == "dev" ]; then
if [ -n "$(git status --porcelain)" ]; then
echo "Working tree is not clean!"
echo "Commit or stash your changes before creating a release."
exit 1
fi
CURRENTBRANCH=$(git rev-parse --abbrev-ref HEAD)
ORIGBRANCH="${CURRENTBRANCH}"
if [ "${is_dry_run}" = false ] && [ "${CURRENTBRANCH}" != "dev" ]; then
echo "You are not in dev branch!"
echo "Use dev branch to make a release!"
exit 1
fi
release_tag="${release_input}"
if [ "${release_input}" != "${release_input#+}" ]; then
current_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)"
if [ -z "${current_tag}" ]; then
echo "No existing tag found to increment from!"
exit 1
fi
case "${release_input}" in
+1)
release_tag="$(printf '%s' "${current_tag}" | awk -F. 'BEGIN{OFS="."} { $1+=1; $2=0; $3=0; print }')"
;;
+0.1)
release_tag="$(printf '%s' "${current_tag}" | awk -F. 'BEGIN{OFS="."} { $2+=1; $3=0; print }')"
;;
+0.0.1)
release_tag="$(printf '%s' "${current_tag}" | awk -F. 'BEGIN{OFS="."} { $3+=1; print }')"
;;
*)
echo "Unsupported increment syntax: ${release_input}"
exit 1
;;
esac
fi
if git rev-parse -q --verify "refs/tags/${release_tag}" >/dev/null; then
echo "Tag ${release_tag} already exists!"
exit 1
fi
if [ "${is_dry_run}" = true ]; then
echo "Dry run: computed release tag ${release_tag}"
exit 0
fi
echo "Release tag selected: ${release_tag}"
read -r -p "Proceed with release? [y/N] " confirm
case "${confirm}" in
y|Y)
;;
*)
echo "Release cancelled."
exit 1
;;
esac
git checkout "${TAGBRANCH}"
git merge "${CURRENTBRANCH}"
CURRENTBRANCH="${TAGBRANCH}"
git merge "${ORIGBRANCH}"
git push
git tag -a "${VERSION}" -m "${MESSAGE}"
git tag -a "${release_tag}" -m "Release ${release_tag}"
git push --tags
git checkout "${CURRENTBRANCH}"
echo "Created release tag ${release_tag}"
Executable → Regular
+162 -63
View File
@@ -1,88 +1,187 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
declare -r DEV="${1}"
declare STARTDATE=""
VERSION="0.0.4"
STARTDATE=0
STARTDATESTRING=""
show_help() {
echo "ddwipe dev (/dev/sdX)"
echo ""
echo "Version : 0.0.3"
usage() {
cat <<EOF
Usage: mtm-ddwipe DEVICE
Wipe a block device.
Warnings:
- This is destructive and irreversible.
- The target device must not be mounted or in use.
- blkdiscard support depends on the device and firmware.
- dd fallback may take a long time.
Version: ${VERSION}
EOF
}
log() {
echo "$*" >&2
}
die() {
echo "Error: $*" >&2
exit 1
}
check_args() {
if [ "${1}" == "" ]; then
show_help
if [ $# -ne 1 ]; then
usage
exit 1
fi
}
check_dev_exist() {
if [ ! -e "${1}" ]; then
echo "${1} is missing."
exit 1
fi
}
confirm_wipe() {
lsblk "${1}"
echo ""
read -r -p "Wipe ${1} (y/[n])?" CHOICE
case "${CHOICE}" in
y|Y ) echo "";;
* )
echo "Canceled"
exit 1
case "$1" in
-h|--help)
usage
exit 0
;;
-*)
die "Invalid option."
;;
esac
}
wipe_dev() {
STARTDATE="$(date)"
echo "Begin wiping device ${1}"
echo ""
echo "Start date :"
echo "${STARTDATE}"
echo ""
echo "blkdiscard secure"
if ! blkdiscard -f -p 500M -s -v "${1}"; then
echo ""
echo "blkdiscard zero"
if ! blkdiscard -f -p 500M -z -v "${1}"; then
echo ""
echo "dd zero"
if ! dd if=/dev/zero of="${1}" bs=1M status=progress; then
# Need check if dd has all writed, if yes, return no error
# echo "Error wiping device ${1}, use phisical destroy !"
echo "Wiped with dd, check if full size is writed."
echo "Otherwise use a mechanical destruction of the device."
print_time
exit 1
fi
check_device() {
local dev="$1"
[ -e "$dev" ] || die "Missing device: $dev"
[ -b "$dev" ] || die "Not a block device: $dev"
}
check_device_not_in_use() {
local dev="$1"
if findmnt -rn --target "$dev" >/dev/null 2>&1; then
die "Device is mounted: $dev"
fi
if lsblk -nrpo NAME,MOUNTPOINT "$dev" | awk '$2 != "" { found=1 } END { exit !found }'; then
die "Device or child is mounted: $dev"
fi
}
confirm_wipe() {
local dev="$1"
local choice=""
echo "Device:"
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,MODEL,SERIAL "$dev"
echo ""
echo "Device ${1} wipped !"
echo "Type exactly: WIPE $dev"
read -r -p "Confirm: " choice
[ "$choice" = "WIPE $dev" ] || die "Canceled"
echo ""
}
confirm_root() {
if [ "${EUID:-$(id -u)}" -ne 0 ]; then
die "This tool must be run as root."
fi
}
format_duration() {
local total="$1"
local hours minutes seconds
hours=$((total / 3600))
minutes=$(((total % 3600) / 60))
seconds=$((total % 60))
printf '%02d:%02d:%02d\n' "$hours" "$minutes" "$seconds"
}
print_time() {
echo ""
echo "Start date :"
echo "${STARTDATE}"
local enddate calctime
ENDDATE=$(date +%s)
echo ""
echo "End date :"
date
log "Start date :"
log "$STARTDATESTRING"
enddate=$(date +%s)
calctime=$((enddate - STARTDATE))
CALCTIME=$((ENDDATE-STARTDATE))
echo ""
echo "Total time :"
date -d@${CALCTIME} -u +%H:%M:%S
log "End date :"
date >&2
echo ""
log "Total time :"
format_duration "$calctime" >&2
}
check_args "${DEV}"
check_dev_exist "${DEV}"
confirm_wipe "${DEV}"
STARTDATE=$(date +%s)
wipe_dev "${DEV}"
print_time
wipe_with_blkdiscard_secure() {
local dev="$1"
log "blkdiscard secure"
blkdiscard -f -p 500M -s -v "$dev"
}
wipe_with_blkdiscard_zero() {
local dev="$1"
log "blkdiscard zero"
blkdiscard -f -p 500M -z -v "$dev"
}
wipe_with_dd() {
local dev="$1"
log "dd zero"
dd if=/dev/zero of="$dev" bs=1M status=progress conv=fsync
log "Wiped with dd, check if full size is written."
log "Otherwise use a mechanical destruction of the device."
}
wipe_dev() {
local dev="$1"
STARTDATE=$(date +%s)
STARTDATESTRING="$(date)"
log "Begin wiping: $dev"
echo ""
log "Start date :"
log "$STARTDATESTRING"
echo ""
if wipe_with_blkdiscard_secure "$dev"; then
echo ""
log "Device $dev wiped."
return
fi
echo ""
if wipe_with_blkdiscard_zero "$dev"; then
echo ""
log "Device $dev wiped."
return
fi
echo ""
if wipe_with_dd "$dev"; then
echo ""
log "Device $dev wiped."
return
fi
die "Wipe failed. The device may not be fully overwritten."
}
main() {
check_args "$@"
confirm_root
check_device "$1"
check_device_not_in_use "$1"
confirm_wipe "$1"
wipe_dev "$1"
print_time
}
main "$@"