feat: adguard-shield als globalen CLI-Befehl registrieren + Doku
This commit is contained in:
@@ -20,6 +20,7 @@ const (
|
||||
DefaultInstallDir = "/opt/adguard-shield"
|
||||
DefaultStateDir = "/var/lib/adguard-shield"
|
||||
DefaultLogFile = "/var/log/adguard-shield.log"
|
||||
CLICommandPath = "/usr/local/bin/adguard-shield"
|
||||
ServiceName = "adguard-shield.service"
|
||||
ServicePath = "/etc/systemd/system/adguard-shield.service"
|
||||
)
|
||||
@@ -30,19 +31,22 @@ type Options struct {
|
||||
Enable bool
|
||||
SkipDeps bool
|
||||
KeepConfig bool
|
||||
RegisterCLI bool
|
||||
}
|
||||
|
||||
type Status struct {
|
||||
InstallDir string
|
||||
BinaryPath string
|
||||
ConfigPath string
|
||||
BinaryExists bool
|
||||
ConfigExists bool
|
||||
ServiceExists bool
|
||||
ServiceEnabled bool
|
||||
ServiceActive bool
|
||||
Version string
|
||||
LegacyFindings []string
|
||||
InstallDir string
|
||||
BinaryPath string
|
||||
ConfigPath string
|
||||
CLICommandPath string
|
||||
BinaryExists bool
|
||||
ConfigExists bool
|
||||
CLICommandInstalled bool
|
||||
ServiceExists bool
|
||||
ServiceEnabled bool
|
||||
ServiceActive bool
|
||||
Version string
|
||||
LegacyFindings []string
|
||||
}
|
||||
|
||||
type LegacyError struct {
|
||||
@@ -54,30 +58,30 @@ func (e *LegacyError) Error() string {
|
||||
}
|
||||
|
||||
func DefaultOptions() Options {
|
||||
return Options{InstallDir: DefaultInstallDir, Enable: true}
|
||||
return Options{InstallDir: DefaultInstallDir, Enable: true, RegisterCLI: true}
|
||||
}
|
||||
|
||||
func Install(opts Options) error {
|
||||
opts = normalize(opts)
|
||||
fmt.Println("AdGuard Shield Go-Installation")
|
||||
fmt.Printf("Installationspfad: %s\n", opts.InstallDir)
|
||||
fmt.Println("1/9 Pruefe Betriebssystem und root-Rechte ...")
|
||||
fmt.Println("1/10 Pruefe Betriebssystem und root-Rechte ...")
|
||||
if err := requireLinuxRoot(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("2/9 Pruefe auf scriptbasierte Altinstallation ...")
|
||||
fmt.Println("2/10 Pruefe auf scriptbasierte Altinstallation ...")
|
||||
if findings := DetectLegacy(opts.InstallDir); len(findings) > 0 {
|
||||
return &LegacyError{Findings: findings}
|
||||
}
|
||||
if !opts.SkipDeps {
|
||||
fmt.Println("3/9 Pruefe System-Abhaengigkeiten ...")
|
||||
fmt.Println("3/10 Pruefe System-Abhaengigkeiten ...")
|
||||
if err := ensureDependencies(); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("3/9 System-Abhaengigkeiten uebersprungen (--skip-deps)")
|
||||
fmt.Println("3/10 System-Abhaengigkeiten uebersprungen (--skip-deps)")
|
||||
}
|
||||
fmt.Println("4/9 Erstelle Verzeichnisse ...")
|
||||
fmt.Println("4/10 Erstelle Verzeichnisse ...")
|
||||
if err := os.MkdirAll(opts.InstallDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -87,23 +91,31 @@ func Install(opts Options) error {
|
||||
if err := os.MkdirAll(filepath.Join(opts.InstallDir, "geoip"), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("5/9 Installiere Binary ...")
|
||||
fmt.Println("5/10 Installiere Binary ...")
|
||||
if err := copySelf(filepath.Join(opts.InstallDir, "adguard-shield")); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("6/9 Installiere Report-Templates ...")
|
||||
if opts.RegisterCLI {
|
||||
fmt.Printf("6/10 Registriere CLI-Befehl (%s) ...\n", CLICommandPath)
|
||||
if err := registerCLICommand(opts.InstallDir); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fmt.Println("6/10 CLI-Registrierung uebersprungen (--no-register)")
|
||||
}
|
||||
fmt.Println("7/10 Installiere Report-Templates ...")
|
||||
if err := report.InstallTemplates(filepath.Join(opts.InstallDir, "templates")); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("7/9 Installiere oder migriere Konfiguration ...")
|
||||
fmt.Println("8/10 Installiere oder migriere Konfiguration ...")
|
||||
if err := ensureConfig(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("8/9 Schreibe systemd-Service ...")
|
||||
fmt.Println("9/10 Schreibe systemd-Service ...")
|
||||
if err := writeService(opts.InstallDir); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("9/9 Aktualisiere systemd ...")
|
||||
fmt.Println("10/10 Aktualisiere systemd ...")
|
||||
_ = run("systemctl", "daemon-reload")
|
||||
if opts.Enable {
|
||||
fmt.Println("Aktiviere Autostart ...")
|
||||
@@ -144,6 +156,7 @@ func Uninstall(opts Options) error {
|
||||
}
|
||||
_ = os.Remove(ServicePath)
|
||||
_ = run("systemctl", "daemon-reload")
|
||||
_ = unregisterCLICommand(opts.InstallDir)
|
||||
if opts.KeepConfig {
|
||||
for _, p := range []string{
|
||||
filepath.Join(opts.InstallDir, "adguard-shield"),
|
||||
@@ -166,13 +179,15 @@ func GetStatus(installDir string) Status {
|
||||
bin := filepath.Join(installDir, "adguard-shield")
|
||||
conf := filepath.Join(installDir, "adguard-shield.conf")
|
||||
st := Status{
|
||||
InstallDir: installDir,
|
||||
BinaryPath: bin,
|
||||
ConfigPath: conf,
|
||||
BinaryExists: fileExists(bin),
|
||||
ConfigExists: fileExists(conf),
|
||||
ServiceExists: fileExists(ServicePath),
|
||||
LegacyFindings: DetectLegacy(installDir),
|
||||
InstallDir: installDir,
|
||||
BinaryPath: bin,
|
||||
ConfigPath: conf,
|
||||
CLICommandPath: CLICommandPath,
|
||||
BinaryExists: fileExists(bin),
|
||||
ConfigExists: fileExists(conf),
|
||||
CLICommandInstalled: cliCommandInstalled(installDir),
|
||||
ServiceExists: fileExists(ServicePath),
|
||||
LegacyFindings: DetectLegacy(installDir),
|
||||
}
|
||||
if st.BinaryExists {
|
||||
if out, err := exec.Command(bin, "version").Output(); err == nil {
|
||||
@@ -253,6 +268,7 @@ func PrintStatus(st Status) string {
|
||||
if st.Version != "" {
|
||||
b.WriteString(fmt.Sprintf("Version: %s\n", st.Version))
|
||||
}
|
||||
b.WriteString(fmt.Sprintf("CLI-Befehl (%s): %s\n", st.CLICommandPath, yesNo(st.CLICommandInstalled)))
|
||||
b.WriteString(fmt.Sprintf("Konfiguration: %s\n", yesNo(st.ConfigExists)))
|
||||
b.WriteString(fmt.Sprintf("systemd Service: %s\n", yesNo(st.ServiceExists)))
|
||||
b.WriteString(fmt.Sprintf("Autostart: %s\n", yesNo(st.ServiceEnabled)))
|
||||
@@ -391,6 +407,62 @@ func sameFile(a, b string) bool {
|
||||
return errA == nil && errB == nil && os.SameFile(ai, bi)
|
||||
}
|
||||
|
||||
func registerCLICommand(installDir string) error {
|
||||
target := filepath.Join(installDir, "adguard-shield")
|
||||
if err := os.MkdirAll(filepath.Dir(CLICommandPath), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
if existingTarget, err := os.Readlink(CLICommandPath); err == nil {
|
||||
resolved := resolveLinkTarget(CLICommandPath, existingTarget)
|
||||
if filepath.Clean(resolved) == filepath.Clean(target) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("%s existiert bereits und verweist auf %s", CLICommandPath, existingTarget)
|
||||
} else if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if fileExists(CLICommandPath) {
|
||||
return fmt.Errorf("%s existiert bereits und ist kein Symlink", CLICommandPath)
|
||||
}
|
||||
return os.Symlink(target, CLICommandPath)
|
||||
}
|
||||
|
||||
func unregisterCLICommand(installDir string) error {
|
||||
existingTarget, err := os.Readlink(CLICommandPath)
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
target := filepath.Join(installDir, "adguard-shield")
|
||||
resolved := resolveLinkTarget(CLICommandPath, existingTarget)
|
||||
if filepath.Clean(resolved) != filepath.Clean(target) {
|
||||
return nil
|
||||
}
|
||||
return os.Remove(CLICommandPath)
|
||||
}
|
||||
|
||||
func cliCommandInstalled(installDir string) bool {
|
||||
existingTarget, err := os.Readlink(CLICommandPath)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
target := filepath.Join(installDir, "adguard-shield")
|
||||
if !fileExists(target) {
|
||||
return false
|
||||
}
|
||||
resolved := resolveLinkTarget(CLICommandPath, existingTarget)
|
||||
return filepath.Clean(resolved) == filepath.Clean(target)
|
||||
}
|
||||
|
||||
func resolveLinkTarget(linkPath, target string) string {
|
||||
if filepath.IsAbs(target) {
|
||||
return target
|
||||
}
|
||||
return filepath.Join(filepath.Dir(linkPath), target)
|
||||
}
|
||||
|
||||
func ensureConfig(opts Options) error {
|
||||
target := filepath.Join(opts.InstallDir, "adguard-shield.conf")
|
||||
defaults := []byte(defaultConfig)
|
||||
|
||||
Reference in New Issue
Block a user