Compare commits
6 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 772e38fb05 | |||
| 816cc9a459 | |||
| 88f282f1e0 | |||
| 33c28128b8 | |||
| 97fed974fc | |||
| e8910f0f02 |
8 changed files with 29 additions and 19 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -7,7 +7,10 @@ dist/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
||||||
# Distribution staging folders (built per-version, attached to GitHub Releases)
|
# Local build cache (prod/test/old portable folders per version)
|
||||||
|
builds/
|
||||||
|
|
||||||
|
# Legacy staging folders (kept for compatibility with old checkouts)
|
||||||
portable-v*/
|
portable-v*/
|
||||||
|
|
||||||
# Local backup of release archives (kept locally for history, not in repo)
|
# Local backup of release archives (kept locally for history, not in repo)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.2.1] - 2026-05-18
|
||||||
|
### Changed
|
||||||
|
- The `Update available (vX.Y.Z)` hint in the header is now a clickable hyperlink that opens the GitHub releases page (OSC 8 terminal hyperlink). Modern terminals (Windows Terminal, VS Code, WezTerm, most Linux/macOS terminals) render it as a link — `Ctrl+Click` to follow. Older consoles show the plain text, so nothing breaks.
|
||||||
|
- Russian tagline tightened: dropped the `для инженера` phrase, the wording was carried over from an earlier draft and felt out of place.
|
||||||
|
|
||||||
## [1.2.0] - 2026-05-18
|
## [1.2.0] - 2026-05-18
|
||||||
### Added
|
### Added
|
||||||
- Russian UI translation. On first launch the application asks which language to use (`1) English`, `2) Русский`) and writes the answer to a fresh `config.ini` next to `dhcpsrv.exe`. To change the language later, edit `language = en` / `language = ru` in that file — the comment at the top of the file explains how, in both languages.
|
- Russian UI translation. On first launch the application asks which language to use (`1) English`, `2) Русский`) and writes the answer to a fresh `config.ini` next to `dhcpsrv.exe`. To change the language later, edit `language = en` / `language = ru` in that file — the comment at the top of the file explains how, in both languages.
|
||||||
|
|
@ -46,7 +51,8 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
||||||
- Scrollback cleared on startup so mouse-wheel doesn't expose pre-launch text.
|
- Scrollback cleared on startup so mouse-wheel doesn't expose pre-launch text.
|
||||||
- MIT licensed.
|
- MIT licensed.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.2.0...HEAD
|
[Unreleased]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.2.1...HEAD
|
||||||
|
[1.2.1]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.2.0...v1.2.1
|
||||||
[1.2.0]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.1.3...v1.2.0
|
[1.2.0]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.1.3...v1.2.0
|
||||||
[1.1.3]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.1.2...v1.1.3
|
[1.1.3]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.1.2...v1.1.3
|
||||||
[1.1.2]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.1.1...v1.1.2
|
[1.1.2]: https://github.com/Engelgardt23/dhcpsrv/compare/v1.1.1...v1.1.2
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[](https://github.com/Engelgardt23/dhcpsrv/releases/latest)
|
[](https://github.com/Engelgardt23/dhcpsrv/releases/latest)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
🇬🇧 English | [🇷🇺 На русском](README.ru.md)
|
🇺🇸 English | [🇷🇺 Русский](README.ru.md)
|
||||||
|
|
||||||
A tiny portable **DHCP server** for the laptop of a storage/server engineer.
|
A tiny portable **DHCP server** for the laptop of a storage/server engineer.
|
||||||
One double-click — pick a NIC — done. Live table of clients, ping status, packet counters. No install, no Python required on the target machine.
|
One double-click — pick a NIC — done. Live table of clients, ping status, packet counters. No install, no Python required on the target machine.
|
||||||
|
|
@ -45,8 +45,8 @@ The asset is `dhcpsrv-portable-vX.Y.Z.zip` (~12 MB).
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
┌─ Clients ───────────────────────────────────────────────────────────────┐
|
┌─ Clients ───────────────────────────────────────────────────────────────┐
|
||||||
│ # │ IP │ Hostname │ MAC │ Last seen │ Ping │
|
│ # │ IP │ Hostname │ MAC │ Last seen │ Ping │
|
||||||
│ 1 │ 10.10.10.2 │ vegman-r120 │ a0:c5:f2:13:57:46 │ 17:42:18 │ OK │
|
│ 1 │ 10.10.10.2 │ server-01 │ a0:c5:f2:13:57:46 │ 17:42:18 │ OK │
|
||||||
│ 2 │ 10.10.10.3 │ vegman-s220 │ 70:b3:d5:11:22:33 │ 17:42:21 │ -- │
|
│ 2 │ 10.10.10.3 │ server-02 │ 70:b3:d5:11:22:33 │ 17:42:21 │ -- │
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
┌─ Events ────────────────────────────────────────────────────────────────┐
|
┌─ Events ────────────────────────────────────────────────────────────────┐
|
||||||
│ [17:42:18] DISCOVER a0:c5:f2:13:57:46 → OFFER 10.10.10.2 │
|
│ [17:42:18] DISCOVER a0:c5:f2:13:57:46 → OFFER 10.10.10.2 │
|
||||||
|
|
@ -56,7 +56,7 @@ The asset is `dhcpsrv-portable-vX.Y.Z.zip` (~12 MB).
|
||||||
|
|
||||||
## Typical scenarios
|
## Typical scenarios
|
||||||
|
|
||||||
- **VEGMAN with shared LOM** — one cable into the BMC/host port, BMC and the host OS both get IPs from this DHCP.
|
- **Server with shared LOM** — one cable into the BMC/host port, BMC and the host OS both get IPs from this DHCP.
|
||||||
- **8-port switch** — laptop on one port, up to 7 servers on the rest; the 50-address pool covers everyone.
|
- **8-port switch** — laptop on one port, up to 7 servers on the rest; the 50-address pool covers everyone.
|
||||||
- **Direct cable into a dedicated Mgmt port** — single client (the BMC).
|
- **Direct cable into a dedicated Mgmt port** — single client (the BMC).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
[](https://github.com/Engelgardt23/dhcpsrv/releases/latest)
|
[](https://github.com/Engelgardt23/dhcpsrv/releases/latest)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
[🇬🇧 English](README.md) | 🇷🇺 На русском
|
[🇺🇸 English](README.md) | 🇷🇺 Русский
|
||||||
|
|
||||||
Маленький портативный **DHCP-сервер** для ноутбука инженера хранения / серверов.
|
Маленький портативный **DHCP-сервер** для ноутбука инженера хранения / серверов.
|
||||||
Двойной клик — выбрал сетевую — готово. Живая таблица клиентов, статус ping, счётчики пакетов. Ничего не устанавливается, Python на целевой машине не нужен.
|
Двойной клик — выбрал сетевую — готово. Живая таблица клиентов, статус ping, счётчики пакетов. Ничего не устанавливается, Python на целевой машине не нужен.
|
||||||
|
|
@ -46,8 +46,8 @@
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
┌─ Клиенты ───────────────────────────────────────────────────────────────┐
|
┌─ Клиенты ───────────────────────────────────────────────────────────────┐
|
||||||
│ # │ IP │ Имя хоста │ MAC │ Последний │ Пинг │
|
│ # │ IP │ Имя хоста │ MAC │ Последний │ Пинг │
|
||||||
│ 1 │ 10.10.10.2 │ vegman-r120 │ a0:c5:f2:13:57:46 │ 17:42:18 │ OK │
|
│ 1 │ 10.10.10.2 │ server-01 │ a0:c5:f2:13:57:46 │ 17:42:18 │ OK │
|
||||||
│ 2 │ 10.10.10.3 │ vegman-s220 │ 70:b3:d5:11:22:33 │ 17:42:21 │ -- │
|
│ 2 │ 10.10.10.3 │ server-02 │ 70:b3:d5:11:22:33 │ 17:42:21 │ -- │
|
||||||
└─────────────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
┌─ События ───────────────────────────────────────────────────────────────┐
|
┌─ События ───────────────────────────────────────────────────────────────┐
|
||||||
│ [17:42:18] DISCOVER a0:c5:f2:13:57:46 → OFFER 10.10.10.2 │
|
│ [17:42:18] DISCOVER a0:c5:f2:13:57:46 → OFFER 10.10.10.2 │
|
||||||
|
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
## Типичные сценарии
|
## Типичные сценарии
|
||||||
|
|
||||||
- **VEGMAN с общим LOM** — один кабель в порт BMC/host, и BMC и хост-ОС получают IP с этого DHCP.
|
- **Сервер с общим LOM** — один кабель в порт BMC/host, и BMC и хост-ОС получают IP с этого DHCP.
|
||||||
- **8-портовый свитч** — ноут на одном порту, до 7 серверов на остальных; пул из 50 адресов покрывает всех.
|
- **8-портовый свитч** — ноут на одном порту, до 7 серверов на остальных; пул из 50 адресов покрывает всех.
|
||||||
- **Прямой кабель в выделенный Mgmt-порт** — один клиент (BMC).
|
- **Прямой кабель в выделенный Mgmt-порт** — один клиент (BMC).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,5 @@ The single source of truth for the project version. Bump this before tagging
|
||||||
a release; CI reads the tag, the code reads this constant.
|
a release; CI reads the tag, the code reads this constant.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = "1.2.0"
|
__version__ = "1.2.2"
|
||||||
GITHUB_REPO = "Engelgardt23/dhcpsrv"
|
GITHUB_REPO = "engel/dhcpsrv" # на Forgejo (git.engelgardt23.ru)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ from rich.console import Console
|
||||||
from rich.prompt import Confirm, Prompt
|
from rich.prompt import Confirm, Prompt
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
|
|
||||||
from . import __version__
|
from . import __version__, GITHUB_REPO
|
||||||
from .platform_win import enable_vt, require_admin
|
from .platform_win import enable_vt, require_admin
|
||||||
from .update_check import check_for_update
|
from .update_check import check_for_update
|
||||||
from .network import list_adapters, set_static_ip, revert_to_dhcp
|
from .network import list_adapters, set_static_ip, revert_to_dhcp
|
||||||
|
|
@ -53,10 +53,12 @@ def main() -> None:
|
||||||
title = f"[bold cyan]dhcpsrv v{__version__}[/] {t('tagline')}"
|
title = f"[bold cyan]dhcpsrv v{__version__}[/] {t('tagline')}"
|
||||||
latest = check_for_update()
|
latest = check_for_update()
|
||||||
if latest:
|
if latest:
|
||||||
|
release_url = f"https://git.engelgardt23.ru/{GITHUB_REPO}/releases/latest"
|
||||||
|
notice = t("update_available", tag=latest)
|
||||||
header = Table.grid(expand=True)
|
header = Table.grid(expand=True)
|
||||||
header.add_column(justify="left", ratio=1)
|
header.add_column(justify="left", ratio=1)
|
||||||
header.add_column(justify="right")
|
header.add_column(justify="right")
|
||||||
header.add_row(title, f"[dim]{t('update_available', tag=latest)}[/]")
|
header.add_row(title, f"[dim][link={release_url}]{notice}[/link][/]")
|
||||||
console.print(header)
|
console.print(header)
|
||||||
else:
|
else:
|
||||||
console.print(title)
|
console.print(title)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ STRINGS: dict[str, dict[str, str]] = {
|
||||||
"en": {
|
"en": {
|
||||||
# app.py / startup
|
# app.py / startup
|
||||||
"tagline": "- portable laptop-side DHCP server",
|
"tagline": "- portable laptop-side DHCP server",
|
||||||
"update_available": "update available ({tag})",
|
"update_available": "Update available ({tag})",
|
||||||
"available_adapters": "Available adapters",
|
"available_adapters": "Available adapters",
|
||||||
"no_adapters": "No suitable wired adapters found.",
|
"no_adapters": "No suitable wired adapters found.",
|
||||||
"select_adapter": "Select adapter number",
|
"select_adapter": "Select adapter number",
|
||||||
|
|
@ -56,8 +56,8 @@ STRINGS: dict[str, dict[str, str]] = {
|
||||||
"no_events": "(no events yet)",
|
"no_events": "(no events yet)",
|
||||||
},
|
},
|
||||||
"ru": {
|
"ru": {
|
||||||
"tagline": "— портативный DHCP-сервер для инженера",
|
"tagline": "— портативный DHCP-сервер",
|
||||||
"update_available": "доступно обновление ({tag})",
|
"update_available": "Доступно обновление ({tag})",
|
||||||
"available_adapters": "Доступные адаптеры",
|
"available_adapters": "Доступные адаптеры",
|
||||||
"no_adapters": "Подходящие проводные адаптеры не найдены.",
|
"no_adapters": "Подходящие проводные адаптеры не найдены.",
|
||||||
"select_adapter": "Введите номер адаптера",
|
"select_adapter": "Введите номер адаптера",
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,8 @@ def check_for_update() -> str | None:
|
||||||
currently running version. Returns None when up to date, offline, or on
|
currently running version. Returns None when up to date, offline, or on
|
||||||
any error — the caller decides how (or whether) to render the hint."""
|
any error — the caller decides how (or whether) to render the hint."""
|
||||||
try:
|
try:
|
||||||
url = f"https://api.github.com/repos/{GITHUB_REPO}/releases/latest"
|
url = f"https://git.engelgardt23.ru/api/v1/repos/{GITHUB_REPO}/releases/latest"
|
||||||
req = urllib.request.Request(url, headers={
|
req = urllib.request.Request(url, headers={
|
||||||
"Accept": "application/vnd.github+json",
|
|
||||||
"User-Agent": f"dhcpsrv/{__version__}",
|
"User-Agent": f"dhcpsrv/{__version__}",
|
||||||
})
|
})
|
||||||
with urllib.request.urlopen(req, timeout=3) as r:
|
with urllib.request.urlopen(req, timeout=3) as r:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue