Add CampusNAS menu bar agent
Native macOS agent that keeps the office VPN and the NAS shares working without the shell wrapper it replaces. - VPN: full port of the `ovpn` script — host-route pinning, gateway discovery via networksetup, tunnel liveness by address plus pushed route, startup grace, restart of a wedged daemon. Root steps are batched into one system authorization prompt. - SMB: mounts via NetFS, discovers shares from the server, detects mounts event-driven through NSWorkspace, matches the host by resolved alias so externally created mounts are recognised. - Credentials never pass through the process: the VPN auth file is written by `security` straight to disk, and the password is stored via SecItemAdd rather than a command line visible in ps. - UI: status window, settings editor, ⌘+/⌘− zoom that re-lays out rather than scaling a bitmap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
# Builds a transferable bundle: the universal .app, the sources to rebuild it,
|
||||
# and install instructions.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
NAME="CampusNAS"
|
||||
STAMP="$(date +%Y%m%d)"
|
||||
OUT="dist/${NAME}-${STAMP}"
|
||||
|
||||
echo "==> universal build"
|
||||
UNIVERSAL=1 ./build.sh >/dev/null
|
||||
|
||||
ARCHS="$(lipo -archs "build/${NAME}.app/Contents/MacOS/${NAME}")"
|
||||
echo " architectures: ${ARCHS}"
|
||||
|
||||
rm -rf "$OUT"
|
||||
mkdir -p "${OUT}/source"
|
||||
|
||||
echo "==> collecting"
|
||||
# ditto keeps the bundle structure and the ad-hoc signature intact; cp -R does
|
||||
# not always preserve extended attributes on a signed bundle.
|
||||
ditto "build/${NAME}.app" "${OUT}/${NAME}.app"
|
||||
|
||||
cp -R Sources Package.swift build.sh package.sh README.md "${OUT}/source/"
|
||||
|
||||
cat > "${OUT}/INSTALL.md" <<'DOC'
|
||||
# CampusNAS — установка на другой Mac
|
||||
|
||||
## Что внутри
|
||||
|
||||
- `CampusNAS.app` — готовое приложение, universal (Apple Silicon + Intel)
|
||||
- `source/` — исходники, чтобы пересобрать при необходимости
|
||||
- `README.md` в `source/` — как всё устроено и почему
|
||||
|
||||
## Установка
|
||||
|
||||
```bash
|
||||
cp -R CampusNAS.app /Applications/
|
||||
xattr -dr com.apple.quarantine /Applications/CampusNAS.app
|
||||
open /Applications/CampusNAS.app
|
||||
```
|
||||
|
||||
Вторая строка обязательна. Приложение подписано ad-hoc, без Developer ID,
|
||||
поэтому файл, приехавший с другой машины, помечается карантином и Gatekeeper
|
||||
его не пустит. Команда снимает эту метку.
|
||||
|
||||
Иконка появится в меню-баре. Окно — повторный запуск приложения либо
|
||||
«Показать окно» в меню.
|
||||
|
||||
## Настройка
|
||||
|
||||
Меню-бар → **Настройки…** (⌘,):
|
||||
|
||||
- путь к профилю `.ovpn` и к бинарю `openvpn`
|
||||
- IP VPN-сервера, сеть туннеля, офисная сеть
|
||||
- запись Keychain, логин и пароль VPN
|
||||
- логин SMB
|
||||
|
||||
Адрес NAS и список шар правятся в `~/.config/campusnas-monitor/config.json`,
|
||||
он создаётся при первом запуске.
|
||||
|
||||
## Что нужно на целевой машине
|
||||
|
||||
- **openvpn** — `brew install openvpn`. Приложение само проверит наличие и
|
||||
покажет кнопку установки, если не найдёт.
|
||||
- **профиль `.ovpn`** — скопировать отдельно, в комплект он не входит: там
|
||||
сертификаты.
|
||||
- **пароль VPN** — ввести в окне настроек, он ляжет в Keychain.
|
||||
- **пароль SMB** — спросит сам macOS при первом монтировании. Поставьте галку
|
||||
«Запомнить пароль в связке ключей», иначе автомонтирование работать не будет.
|
||||
|
||||
Если NAS доступен только по имени, а DNS его не отдаёт — добавьте запись:
|
||||
|
||||
```bash
|
||||
printf '192.168.77.43\tCAMPUSNAS\n' | sudo tee -a /etc/hosts
|
||||
```
|
||||
|
||||
## Пересборка
|
||||
|
||||
```bash
|
||||
cd source
|
||||
UNIVERSAL=1 ./build.sh
|
||||
```
|
||||
|
||||
Нужен Xcode с командными утилитами. Собирается за несколько секунд.
|
||||
|
||||
## Чего приложение не делает
|
||||
|
||||
Не хранит паролей. Пароль VPN пишется прямо в Keychain и читается оттуда
|
||||
системной утилитой при подключении. Пароль SMB приложение не видит вообще —
|
||||
им занимается macOS.
|
||||
DOC
|
||||
|
||||
echo "==> archiving"
|
||||
cd dist
|
||||
ditto -c -k --sequesterRsrc --keepParent "${NAME}-${STAMP}" "${NAME}-${STAMP}.zip"
|
||||
cd ..
|
||||
|
||||
SIZE="$(du -h "dist/${NAME}-${STAMP}.zip" | cut -f1)"
|
||||
echo
|
||||
echo "Готово: $(pwd)/dist/${NAME}-${STAMP}.zip (${SIZE})"
|
||||
Reference in New Issue
Block a user