fix: rename binary to ssm
This commit is contained in:
14
.drone.yml
14
.drone.yml
@ -16,19 +16,19 @@ steps:
|
|||||||
CGO_ENABLED: "0"
|
CGO_ENABLED: "0"
|
||||||
commands:
|
commands:
|
||||||
- mkdir -p dist/linux-amd64 dist/darwin-arm64 dist/windows-amd64
|
- mkdir -p dist/linux-amd64 dist/darwin-arm64 dist/windows-amd64
|
||||||
- GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w -X gitea.epss.net.cn/klesh/ss/internal/cli.Version=${DRONE_TAG}" -o dist/linux-amd64/ss ./cmd/ss
|
- GOOS=linux GOARCH=amd64 go build -trimpath -ldflags "-s -w -X gitea.epss.net.cn/klesh/ss/internal/cli.Version=${DRONE_TAG}" -o dist/linux-amd64/ssm ./cmd/ssm
|
||||||
- GOOS=darwin GOARCH=arm64 go build -trimpath -ldflags "-s -w -X gitea.epss.net.cn/klesh/ss/internal/cli.Version=${DRONE_TAG}" -o dist/darwin-arm64/ss ./cmd/ss
|
- GOOS=darwin GOARCH=arm64 go build -trimpath -ldflags "-s -w -X gitea.epss.net.cn/klesh/ss/internal/cli.Version=${DRONE_TAG}" -o dist/darwin-arm64/ssm ./cmd/ssm
|
||||||
- GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "-s -w -X gitea.epss.net.cn/klesh/ss/internal/cli.Version=${DRONE_TAG}" -o dist/windows-amd64/ss.exe ./cmd/ss
|
- GOOS=windows GOARCH=amd64 go build -trimpath -ldflags "-s -w -X gitea.epss.net.cn/klesh/ss/internal/cli.Version=${DRONE_TAG}" -o dist/windows-amd64/ssm.exe ./cmd/ssm
|
||||||
|
|
||||||
- name: package
|
- name: package
|
||||||
image: golang:1.26
|
image: golang:1.26
|
||||||
commands:
|
commands:
|
||||||
- apt-get update -qq && apt-get install -qq -y zip > /dev/null
|
- apt-get update -qq && apt-get install -qq -y zip > /dev/null
|
||||||
- cd dist
|
- cd dist
|
||||||
- tar -C linux-amd64 -czf ss-${DRONE_TAG}-linux-amd64.tar.gz ss
|
- tar -C linux-amd64 -czf ssm-${DRONE_TAG}-linux-amd64.tar.gz ssm
|
||||||
- tar -C darwin-arm64 -czf ss-${DRONE_TAG}-darwin-arm64.tar.gz ss
|
- tar -C darwin-arm64 -czf ssm-${DRONE_TAG}-darwin-arm64.tar.gz ssm
|
||||||
- (cd windows-amd64 && zip -q ../ss-${DRONE_TAG}-windows-amd64.zip ss.exe)
|
- (cd windows-amd64 && zip -q ../ssm-${DRONE_TAG}-windows-amd64.zip ssm.exe)
|
||||||
- sha256sum ss-${DRONE_TAG}-linux-amd64.tar.gz ss-${DRONE_TAG}-darwin-arm64.tar.gz ss-${DRONE_TAG}-windows-amd64.zip > checksums.txt
|
- sha256sum ssm-${DRONE_TAG}-linux-amd64.tar.gz ssm-${DRONE_TAG}-darwin-arm64.tar.gz ssm-${DRONE_TAG}-windows-amd64.zip > checksums.txt
|
||||||
- rm -rf linux-amd64 darwin-arm64 windows-amd64
|
- rm -rf linux-amd64 darwin-arm64 windows-amd64
|
||||||
- ls -la
|
- ls -la
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@ -3,8 +3,8 @@
|
|||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This document describes the internal "agents" (manager components) of the
|
This document describes the internal "agents" (manager components) of the
|
||||||
scientific-surfing (`ss`) CLI and their roles. The CLI is a single Go binary
|
scientific-surfing (`ssm`) CLI and their roles. The CLI is a single Go binary
|
||||||
(`cmd/ss`); each agent below is a package under `internal/`.
|
(`cmd/ssm`); each agent below is a package under `internal/`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ scientific-surfing (`ss`) CLI and their roles. The CLI is a single Go binary
|
|||||||
- **Key Methods:** `Update`, `InstallService`, `UninstallService`, `StartService`, `StopService`, `RestartService`, `GetServiceStatus`, `ReloadService`
|
- **Key Methods:** `Update`, `InstallService`, `UninstallService`, `StartService`, `StopService`, `RestartService`, `GetServiceStatus`, `ReloadService`
|
||||||
|
|
||||||
### 5. Service Manager (`internal/service`)
|
### 5. Service Manager (`internal/service`)
|
||||||
- **Purpose:** Cross-platform system service integration — systemd on Linux, launchd on macOS, and a native Windows Service (via `golang.org/x/sys/windows/svc`) on Windows. On macOS and Windows, this same `ss` binary is what the generated service definition invokes (hidden `service run-macos` / `service run-windows` commands), rather than a separate wrapper process.
|
- **Purpose:** Cross-platform system service integration — systemd on Linux, launchd on macOS, and a native Windows Service (via `golang.org/x/sys/windows/svc`) on Windows. On macOS and Windows, this same `ssm` binary is what the generated service definition invokes (hidden `service run-macos` / `service run-windows` commands), rather than a separate wrapper process.
|
||||||
- **Key Methods:** `Install`, `Uninstall`, `Start`, `Stop`, `Restart`, `Status`
|
- **Key Methods:** `Install`, `Uninstall`, `Start`, `Stop`, `Restart`, `Status`
|
||||||
|
|
||||||
### 6. Hook Manager (`internal/hook`)
|
### 6. Hook Manager (`internal/hook`)
|
||||||
|
|||||||
64
README.md
64
README.md
@ -17,10 +17,10 @@ A CLI for surfing the internet scientifically, written in Go.
|
|||||||
```bash
|
```bash
|
||||||
git clone ssh://git@gitea.epss.net.cn:2223/klesh/ss.git
|
git clone ssh://git@gitea.epss.net.cn:2223/klesh/ss.git
|
||||||
cd ss
|
cd ss
|
||||||
go build -o ss ./cmd/ss
|
go build -o ssm ./cmd/ssm
|
||||||
```
|
```
|
||||||
|
|
||||||
This produces a single `ss` (or `ss.exe` on Windows) binary with no runtime dependencies — templates and hook scripts are embedded in the binary.
|
This produces a single `ssm` (or `ssm.exe` on Windows) binary with no runtime dependencies — templates and hook scripts are embedded in the binary.
|
||||||
|
|
||||||
### 2. Add the binary to your system PATH
|
### 2. Add the binary to your system PATH
|
||||||
|
|
||||||
@ -29,72 +29,72 @@ This produces a single `ss` (or `ss.exe` on Windows) binary with no runtime depe
|
|||||||
### Subscription Management
|
### Subscription Management
|
||||||
```bash
|
```bash
|
||||||
# add a subscription
|
# add a subscription
|
||||||
ss subscription add <name> <clash-rss-subscription-url>
|
ssm subscription add <name> <clash-rss-subscription-url>
|
||||||
|
|
||||||
# refresh a subscription (with optional backup)
|
# refresh a subscription (with optional backup)
|
||||||
ss subscription refresh <name> [--backup]
|
ssm subscription refresh <name> [--backup]
|
||||||
|
|
||||||
# delete a subscription
|
# delete a subscription
|
||||||
ss subscription rm <name>
|
ssm subscription rm <name>
|
||||||
|
|
||||||
# rename a subscription
|
# rename a subscription
|
||||||
ss subscription rename <name> <new-name>
|
ssm subscription rename <name> <new-name>
|
||||||
|
|
||||||
# update subscription URL
|
# update subscription URL
|
||||||
ss subscription set-url <name> <new-url>
|
ssm subscription set-url <name> <new-url>
|
||||||
|
|
||||||
# show the URL for a subscription
|
# show the URL for a subscription
|
||||||
ss subscription get-url <name>
|
ssm subscription get-url <name>
|
||||||
|
|
||||||
# activate a subscription
|
# activate a subscription
|
||||||
ss subscription activate <name>
|
ssm subscription activate <name>
|
||||||
|
|
||||||
# list all subscriptions
|
# list all subscriptions
|
||||||
ss subscription list
|
ssm subscription list
|
||||||
|
|
||||||
# show storage information
|
# show storage information
|
||||||
ss subscription storage
|
ssm subscription storage
|
||||||
```
|
```
|
||||||
|
|
||||||
### Hook Management
|
### Hook Management
|
||||||
```bash
|
```bash
|
||||||
# initialize hooks directory with template scripts
|
# initialize hooks directory with template scripts
|
||||||
ss hook init
|
ssm hook init
|
||||||
|
|
||||||
# show hooks directory location and list all scripts
|
# show hooks directory location and list all scripts
|
||||||
ss hook list
|
ssm hook list
|
||||||
|
|
||||||
# edit a hook script with system editor
|
# edit a hook script with system editor
|
||||||
ss hook edit <script-name>
|
ssm hook edit <script-name>
|
||||||
|
|
||||||
# remove a hook script
|
# remove a hook script
|
||||||
ss hook rm <script-name>
|
ssm hook rm <script-name>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Core Configuration Management
|
### Core Configuration Management
|
||||||
```bash
|
```bash
|
||||||
# import configuration from file
|
# import configuration from file
|
||||||
ss config import <file-path> [--config-file <config.yaml>]
|
ssm config import <file-path> [--config-file <config.yaml>]
|
||||||
|
|
||||||
# export configuration to file
|
# export configuration to file
|
||||||
ss config export <file-path> [--config-file <config.yaml>]
|
ssm config export <file-path> [--config-file <config.yaml>]
|
||||||
|
|
||||||
# edit configuration with system editor
|
# edit configuration with system editor
|
||||||
ss config edit [--config-file <config.yaml>]
|
ssm config edit [--config-file <config.yaml>]
|
||||||
|
|
||||||
# reset configuration to default values
|
# reset configuration to default values
|
||||||
ss config reset [--config-file <config.yaml>]
|
ssm config reset [--config-file <config.yaml>]
|
||||||
|
|
||||||
# show current configuration
|
# show current configuration
|
||||||
ss config show [--config-file <config.yaml>]
|
ssm config show [--config-file <config.yaml>]
|
||||||
|
|
||||||
# apply subscription to generate final config (with advanced options)
|
# apply subscription to generate final config (with advanced options)
|
||||||
ss config apply \
|
ssm config apply \
|
||||||
[--config-file <config.yaml>] \
|
[--config-file <config.yaml>] \
|
||||||
[--output-file <output.yaml>] \
|
[--output-file <output.yaml>] \
|
||||||
[--subscription <subscription-name>]
|
[--subscription <subscription-name>]
|
||||||
```
|
```
|
||||||
**Options** (available on every `ss config` subcommand):
|
**Options** (available on every `ssm config` subcommand):
|
||||||
- `--config-file <config.yaml>`: Use a custom config file instead of the default.
|
- `--config-file <config.yaml>`: Use a custom config file instead of the default.
|
||||||
- `--output-file <output.yaml>`: Specify the output path for the generated config file.
|
- `--output-file <output.yaml>`: Specify the output path for the generated config file.
|
||||||
- `--subscription <subscription-name>`: Use a specific subscription (not just the active one) for config generation.
|
- `--subscription <subscription-name>`: Use a specific subscription (not just the active one) for config generation.
|
||||||
@ -102,24 +102,24 @@ ss config apply \
|
|||||||
### Core Management
|
### Core Management
|
||||||
```bash
|
```bash
|
||||||
# update mihomo core binary
|
# update mihomo core binary
|
||||||
ss core update [--version <version>] [--force]
|
ssm core update [--version <version>] [--force]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Service Management
|
### Service Management
|
||||||
```bash
|
```bash
|
||||||
ss service install [--name <name>] [--description <description>]
|
ssm service install [--name <name>] [--description <description>]
|
||||||
ss service uninstall [--name <name>]
|
ssm service uninstall [--name <name>]
|
||||||
ss service start [--name <name>]
|
ssm service start [--name <name>]
|
||||||
ss service stop [--name <name>]
|
ssm service stop [--name <name>]
|
||||||
ss service restart [--name <name>]
|
ssm service restart [--name <name>]
|
||||||
ss service reload [--name <name>] # reload config via mihomo's API, no restart
|
ssm service reload [--name <name>] # reload config via mihomo's API, no restart
|
||||||
ss service status [--name <name>]
|
ssm service status [--name <name>]
|
||||||
```
|
```
|
||||||
|
|
||||||
`install`/`uninstall`/`start`/`stop`/`restart` need root/admin privileges:
|
`install`/`uninstall`/`start`/`stop`/`restart` need root/admin privileges:
|
||||||
|
|
||||||
- **Linux / macOS**: just run the command directly — `ss` re-execs itself under `sudo` automatically, prompting for your password if needed.
|
- **Linux / macOS**: just run the command directly — `ssm` re-execs itself under `sudo` automatically, prompting for your password if needed.
|
||||||
- **Windows**: run from an elevated/Administrator shell — `ss.exe service install`.
|
- **Windows**: run from an elevated/Administrator shell — `ssm.exe service install`.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Command ss is the CLI for scientific-surfing.
|
// Command ssm is the CLI for scientific-surfing.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "gitea.epss.net.cn/klesh/ss/internal/cli"
|
import "gitea.epss.net.cn/klesh/ss/internal/cli"
|
||||||
@ -1,4 +1,4 @@
|
|||||||
// Package cli wires up the ss command-line interface, mirroring cli.py's
|
// Package cli wires up the ssm command-line interface, mirroring cli.py's
|
||||||
// argparse-based command tree with cobra.
|
// argparse-based command tree with cobra.
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
@ -59,15 +59,15 @@ func newManagers(configFile, outputFile, subscriptionName string) (*managers, er
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version is the ss build version, injected at build time via
|
// Version is the ssm build version, injected at build time via
|
||||||
// -ldflags "-X gitea.epss.net.cn/klesh/ss/internal/cli.Version=vX.Y.Z"
|
// -ldflags "-X gitea.epss.net.cn/klesh/ss/internal/cli.Version=vX.Y.Z"
|
||||||
// (see .drone.yml). Defaults to "dev" for local/unversioned builds.
|
// (see .drone.yml). Defaults to "dev" for local/unversioned builds.
|
||||||
var Version = "dev"
|
var Version = "dev"
|
||||||
|
|
||||||
// Execute runs the ss CLI. It is the Go equivalent of cli.py's main().
|
// Execute runs the ssm CLI. It is the Go equivalent of cli.py's main().
|
||||||
func Execute() {
|
func Execute() {
|
||||||
root := &cobra.Command{
|
root := &cobra.Command{
|
||||||
Use: "ss",
|
Use: "ssm",
|
||||||
Short: "Scientific Surfing - CLI for managing clash RSS subscriptions",
|
Short: "Scientific Surfing - CLI for managing clash RSS subscriptions",
|
||||||
Version: Version,
|
Version: Version,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
|
|||||||
@ -17,7 +17,7 @@ func newPlatformManager(configDir string) (platformManager, error) {
|
|||||||
// macosServiceManager manages services via launchd. Direct port of
|
// macosServiceManager manages services via launchd. Direct port of
|
||||||
// MacOSServiceManager in service_manager.py. Unlike the Python version
|
// MacOSServiceManager in service_manager.py. Unlike the Python version
|
||||||
// (which shells out to a separate macos_service_wrapper.py for DNS
|
// (which shells out to a separate macos_service_wrapper.py for DNS
|
||||||
// handling), the generated plist invokes this same ss binary in
|
// handling), the generated plist invokes this same ssm binary in
|
||||||
// "service run-macos" mode (see wrapper_darwin.go) — no second script file
|
// "service run-macos" mode (see wrapper_darwin.go) — no second script file
|
||||||
// is needed.
|
// is needed.
|
||||||
type macosServiceManager struct {
|
type macosServiceManager struct {
|
||||||
@ -31,7 +31,7 @@ func (d *macosServiceManager) launchdPath(name string) string {
|
|||||||
func (d *macosServiceManager) createLaunchdPlist(cfg Config) error {
|
func (d *macosServiceManager) createLaunchdPlist(cfg Config) error {
|
||||||
selfPath, err := os.Executable()
|
selfPath, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to determine ss executable path: %w", err)
|
return fmt.Errorf("failed to determine ssm executable path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
workingDir := filepath.Dir(cfg.ExecutablePath)
|
workingDir := filepath.Dir(cfg.ExecutablePath)
|
||||||
|
|||||||
@ -16,7 +16,7 @@ func newPlatformManager(configDir string) (platformManager, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// windowsServiceManager manages services via sc.exe, with the service
|
// windowsServiceManager manages services via sc.exe, with the service
|
||||||
// binPath pointing back at this same ss executable in
|
// binPath pointing back at this same ssm executable in
|
||||||
// "service run-windows" mode (see wrapper_windows.go) instead of a separate
|
// "service run-windows" mode (see wrapper_windows.go) instead of a separate
|
||||||
// pywin32-based wrapper process. Direct port of WindowsServiceManager in
|
// pywin32-based wrapper process. Direct port of WindowsServiceManager in
|
||||||
// service_manager.py, minus the pywin32/JSON-config-file indirection.
|
// service_manager.py, minus the pywin32/JSON-config-file indirection.
|
||||||
@ -85,7 +85,7 @@ func runAsAdmin(cmdArgs []string, description string) error {
|
|||||||
func (w *windowsServiceManager) Install(cfg Config) error {
|
func (w *windowsServiceManager) Install(cfg Config) error {
|
||||||
selfPath, err := os.Executable()
|
selfPath, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to determine ss executable path: %w", err)
|
return fmt.Errorf("failed to determine ssm executable path: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceCmd := fmt.Sprintf(`"%s" service run-windows --name "%s" --bin "%s" --args "%s"`,
|
serviceCmd := fmt.Sprintf(`"%s" service run-windows --name "%s" --bin "%s" --args "%s"`,
|
||||||
|
|||||||
@ -163,7 +163,7 @@ func (w *mihomoWrapper) run() {
|
|||||||
|
|
||||||
// RunMacOSWrapper runs the mihomo process with DNS management, blocking
|
// RunMacOSWrapper runs the mihomo process with DNS management, blocking
|
||||||
// until it exits or a termination signal is received. Invoked by the
|
// until it exits or a termination signal is received. Invoked by the
|
||||||
// hidden `ss service run-macos <executable> <configDir> [args...]` command
|
// hidden `ssm service run-macos <executable> <configDir> [args...]` command
|
||||||
// that the generated launchd plist points at (see service_darwin.go),
|
// that the generated launchd plist points at (see service_darwin.go),
|
||||||
// replacing the standalone macos_service_wrapper.py script.
|
// replacing the standalone macos_service_wrapper.py script.
|
||||||
func RunMacOSWrapper(executable, configDir string, args []string) error {
|
func RunMacOSWrapper(executable, configDir string, args []string) error {
|
||||||
|
|||||||
@ -15,10 +15,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// windowsServiceHandler implements svc.Handler, hosting the mihomo
|
// windowsServiceHandler implements svc.Handler, hosting the mihomo
|
||||||
// subprocess directly inside the ss binary. Replaces
|
// subprocess directly inside the ssm binary. Replaces
|
||||||
// windows_service_wrapper.py + pywin32 + the per-service JSON config file:
|
// windows_service_wrapper.py + pywin32 + the per-service JSON config file:
|
||||||
// the equivalent configuration (bin path + args) is now passed as command
|
// the equivalent configuration (bin path + args) is now passed as command
|
||||||
// line flags to `ss service run-windows`, and this same binary registers
|
// line flags to `ssm service run-windows`, and this same binary registers
|
||||||
// itself as the service via golang.org/x/sys/windows/svc.
|
// itself as the service via golang.org/x/sys/windows/svc.
|
||||||
type windowsServiceHandler struct {
|
type windowsServiceHandler struct {
|
||||||
name string
|
name string
|
||||||
@ -119,7 +119,7 @@ func (w *logWriter) Write(p []byte) (int, error) {
|
|||||||
|
|
||||||
// RunWindowsService registers this process as the named Windows service and
|
// RunWindowsService registers this process as the named Windows service and
|
||||||
// blocks until the service control manager stops it. Invoked via the hidden
|
// blocks until the service control manager stops it. Invoked via the hidden
|
||||||
// `ss service run-windows --name <name> --bin <binPath> --args <args>`
|
// `ssm service run-windows --name <name> --bin <binPath> --args <args>`
|
||||||
// command that Install() points sc.exe's binPath= at.
|
// command that Install() points sc.exe's binPath= at.
|
||||||
func RunWindowsService(name, binPath, args string) error {
|
func RunWindowsService(name, binPath, args string) error {
|
||||||
logPath := filepath.Join(filepath.Dir(binPath), name+"_service.log")
|
logPath := filepath.Join(filepath.Dir(binPath), name+"_service.log")
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
// Package templates embeds the default core config and hook script
|
// Package templates embeds the default core config and hook script
|
||||||
// templates into the ss binary, replacing the Python version's
|
// templates into the ssm binary, replacing the Python version's
|
||||||
// Path(__file__).parent / "templates" lookup.
|
// Path(__file__).parent / "templates" lookup.
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user