diff --git a/README.md b/README.md index 0dfd88c..3176109 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ ## 计划结构 -- 设备客户端:用于在家庭硬件设备上运行,提供部分运维能力(上报系统负载、watch dog) +- DDNS 设备客户端:已迁移到 `life_tools/cli/cq_ddns_client`,独立安装和运行。 - 服务端:系统主体部分 - 前端:提供管理员用户界面 ## 计划能力 -- DDNS: 用于动态 dns 注册,由于小米路由器尚未具备 ipv6 的 ddns 能力,home server 可以为家庭硬件设备提供 ddns 能力; +- DDNS:服务端保留原有 HTTP 接口;设备定时更新 Cloudflare DNS 的能力由 `life_tools` 中的 `cq_ddns_client` 提供。 - Watch Dog: 或者叫 heart beat,用于记录设备心跳数据,包含一些辅助数据,可以快速发现设备是否掉线; - 家庭图书管理能力: 以 isbn 为基础,快速管理家庭中的纸质书及电子书; - WebDAV: 使用同一套账号体系,通过 WebDAV 协议实现外部文档访问,地址为 [https://www.server.com:port/webdav](https://www.server.com:port/webdav); @@ -41,22 +41,27 @@ npm run build ### home_server -执行 `./build.sh` 构建 server 和 client 的二进制文件。 +执行 `./build.sh` 构建服务端二进制文件。构建前准备 `config/config.yaml`;不再需要客户端配置。 -### home_client -1. 运行 `./build.sh`,编译程序; -2. 仿照 `client/config_example.yaml` 编写一份自己的配置文件; -3. 将二进制文件复制到指定文件夹 `sudo cp/bin/home_client /usr/local/bin/home_client`; -4. 将配置文件放在指定文件 `/etc/home_server/client_config.yaml`; -5. 将 systemd 配置文件复制到指定路径 `sudo cp script/systemd/home_client.service /etc/systemd/system` -6. 启动 `sudo systemctl start home_client.service` +### DDNS 客户端迁移 -#### 查看日志 +`home_client` 已迁移到 [life_tools 的 cq_ddns_client](https://github.com/mcoder2014/life_tools/blob/master/docs/cli/cq_ddns_client.md)。客户端源码、构建产物和 systemd 模板统一在 `life_tools` 维护,服务端 DDNS HTTP 接口保持兼容。 -```shell -sudo journalctl --unit home_client.service +| 项目 | 旧入口 | 新入口 | +|---|---|---| +| 命令 | `home_client` | `cq_ddns_client` | +| 默认配置 | 部署时通过 `-conf` 指定 YAML | `/etc/life_tools/cq_ddns_client.json` | +| 配置参数 | `-conf` | `-config`,保留 `-conf` 别名及 `.yaml/.yml` 读取 | +| systemd | `home_client.service` | `cq_ddns_client.service` | + +旧二进制和正在运行的服务不会因源码迁移自动替换。先安装新客户端,用旧配置执行只读预检,再按迁移文档转换 JSON、验证新服务并切换;不能同时长期运行两个客户端。 + +```bash +cq_ddns_client -conf /etc/home_server/client_config.yaml -dry-run ``` +回滚时停用新服务,再启动原 `home_client.service`。切换验证完成前保留旧二进制、配置和 unit。 + ## 网页托管 ### 使用方式 diff --git a/build.sh b/build.sh index c7d06a0..a283646 100755 --- a/build.sh +++ b/build.sh @@ -1,18 +1,14 @@ #!/bin/bash SERVER_NAME="home_server" -CLIENT_NAME="home_client" mkdir -p output/bin mkdir -p output/testdata cp -r script/* output cp config/config.yaml output -cp client/config/config.yaml output/client_config.yaml chmod a+x output/boot_server.sh -chmod a+x output/boot_client.sh # 构建程序 go build -v -o output/bin/$SERVER_NAME ./ -go build -v -o output/bin/$CLIENT_NAME ./client \ No newline at end of file diff --git a/client/biz/ddns/ddns.go b/client/biz/ddns/ddns.go deleted file mode 100644 index 98f1ee1..0000000 --- a/client/biz/ddns/ddns.go +++ /dev/null @@ -1,126 +0,0 @@ -package ddns - -import ( - "context" - "fmt" - "strings" - "time" - - "github.com/cloudflare/cloudflare-go" - "github.com/mcoder2014/home_server/client/config" - "github.com/mcoder2014/home_server/client/rpc" - myErrors "github.com/mcoder2014/home_server/errors" - serverRpc "github.com/mcoder2014/home_server/rpc" - "github.com/mcoder2014/home_server/utils" - "github.com/mcoder2014/home_server/utils/log" - "github.com/sirupsen/logrus" -) - -func StartDDNSRoutine() { - logrus.Infof("StartDDNSRoutine") - RefreshOnce(context.Background()) - ticker := time.NewTicker(120 * time.Second) - for range ticker.C { - ctx := log.GetCtxWithLogID(context.Background()) - RefreshOnce(ctx) - } -} - -func RefreshOnce(ctx context.Context) { - defer utils.Recovery(ctx) - log.Ctx(ctx).Infof("DDNS refresh once start") - - // 处理 DDNS - ddnsConfs := config.Global().DDNSConfig - if len(ddnsConfs) == 0 { - log.Ctx(ctx).Infof("ddns config len 0, continue") - return - } - - log.Ctx(ctx).Infof("get ddns configs: len(%d)", len(ddnsConfs)) - // 查询 ddns record - records, err := rpc.GetAllDNSRecord(ctx, config.Global().Cloudflare.Zone) - recordMap := convertToDNSRecordMap(records) - if err != nil { - log.Ctx(ctx).WithError(err).Errorf("GetAllDNSRecord failed") - return - } - - for _, domainConfig := range ddnsConfs { - err = domainCheck(ctx, domainConfig, recordMap) - if err != nil { - log.Ctx(ctx).WithError(err).Errorf("ddns check domain %v failed", domainConfig.Domain) - } - } -} - -func domainCheck(ctx context.Context, domainConfig *config.DomainConfig, recordMap map[string]*cloudflare.DNSRecord) (err error) { - ipAddress, err := getIp(ctx, domainConfig) - if err != nil { - return err - } - log.Ctx(ctx).Infof("get current ip type = %s ip = %s", domainConfig.IPVersion, ipAddress) - - // check records - record, ok := recordMap[domainConfig.Domain] - if !ok { - // create - log.Ctx(ctx).Infof("domain:%v has no record, prepare to create new record", domainConfig.Domain) - err = createNewRecord(ctx, domainConfig, ipAddress) - if err != nil { - log.Ctx(ctx).WithError(err).Errorf("domain:%v has no record, create new record failed", domainConfig.Domain) - return err - } - log.Ctx(ctx).Infof("domain:%s has no record, create record, ip=%s , create new record success", domainConfig.Domain, ipAddress) - return nil - } - - // update - if strings.EqualFold(ipAddress, record.Content) { - log.Ctx(ctx).Infof("domain=%s ip=%s address not change, skip update", domainConfig.Domain, ipAddress) - return nil - } - - return updateNewRecord(ctx, domainConfig, ipAddress, *record) -} - -func getIp(ctx context.Context, domainConfig *config.DomainConfig) (ipAddress string, err error) { - // check ip address - if domainConfig.IPVersion == config.IPV4 { - ipAddress, err = serverRpc.GetDefaultIpv4(ctx) - - } else if domainConfig.IPVersion == config.IPV6 { - ipAddress, err = serverRpc.GetDefaultIpv6(ctx) - } else { - return "", fmt.Errorf("client config ip version is not support, domain:%v version:%v", domainConfig.Domain, domainConfig.IPVersion) - } - if err != nil { - return "", myErrors.Wrapf(err, myErrors.ErrorCodeRpcFailed, "domainCheck get ip address failed") - } - return -} - -func updateNewRecord(ctx context.Context, domainConfig *config.DomainConfig, ipAddr string, record cloudflare.DNSRecord) error { - log.Ctx(ctx).Infof("domain %v has changed from %v to %v, prepare to update", domainConfig.Domain, record.Content, ipAddr) - record.Content = ipAddr - - err := rpc.UpdateRecord(ctx, config.Global().Cloudflare.Zone, record.ID, record) - if err != nil { - log.Ctx(ctx).WithError(err).Errorf("domain %v update failed", domainConfig.Domain) - return err - } - log.Ctx(ctx).Infof("domain %v update success", domainConfig.Domain) - return nil -} - -func createNewRecord(ctx context.Context, domainConfig *config.DomainConfig, ipAddr string) error { - record := cloudflare.DNSRecord{ - Name: domainConfig.Domain, - Type: getDNSRecordType(domainConfig.IPVersion), - Content: ipAddr, - Proxied: utils.Bool(false), - TTL: 300, - } - - return rpc.CreateRecord(ctx, config.Global().Cloudflare.Zone, record) -} diff --git a/client/biz/ddns/ddns_test.go b/client/biz/ddns/ddns_test.go deleted file mode 100644 index 474e8b4..0000000 --- a/client/biz/ddns/ddns_test.go +++ /dev/null @@ -1,160 +0,0 @@ -package ddns - -import ( - "context" - "testing" - - "github.com/mcoder2014/home_server/client/config" - "github.com/mcoder2014/home_server/client/rpc" - "github.com/mcoder2014/home_server/client/testutil" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" -) - -func TestMain(t *testing.M) { - _ = testutil.Init() - t.Run() -} - -func Test_createNewRecord(t *testing.T) { - ctx := context.Background() - - tests := []struct { - name string - domainConfig *config.DomainConfig - ipAddr string - wantErr bool - }{ - { - name: "test", - domainConfig: &config.DomainConfig{ - Domain: "a.mcoder.cc", - IPVersion: config.IPV4, - }, - ipAddr: "192.168.31.10", - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := createNewRecord(ctx, tt.domainConfig, tt.ipAddr) - require.Equalf(t, tt.wantErr, err != nil, "createNewRecord failed") - }) - } -} - -func TestUpdateRecord(t *testing.T) { - ctx := context.Background() - records, err := rpc.GetAllDNSRecord(context.Background(), config.Global().Cloudflare.Zone) - require.Nil(t, err) - recordMap := convertToDNSRecordMap(records) - - tests := []struct { - name string - domainConfig *config.DomainConfig - ipAddr string - wantErr bool - }{ - { - name: "normal", - domainConfig: &config.DomainConfig{ - Domain: "a.mcoder.cc", - IPVersion: config.IPV4, - }, - ipAddr: "115.206.152.5", - wantErr: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - - record, ok := recordMap[tt.domainConfig.Domain] - require.True(t, ok) - - err = updateNewRecord(ctx, tt.domainConfig, tt.ipAddr, *record) - require.Equalf(t, tt.wantErr, err != nil, "createNewRecord failed") - }) - } - -} - -func Test_getIp(t *testing.T) { - ctx := context.Background() - - tests := []struct { - name string - domainConfig *config.DomainConfig - wantErr bool - }{ - { - name: "normal ipv4", - domainConfig: &config.DomainConfig{ - IPVersion: "ipv4", - }, - }, - { - name: "normal ipv6", - domainConfig: &config.DomainConfig{ - IPVersion: "ipv6", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - gotIpAddress, err := getIp(ctx, tt.domainConfig) - require.Equal(t, tt.wantErr, err != nil) - require.NotEmpty(t, gotIpAddress) - logrus.Infof("ip addr %v", gotIpAddress) - }) - } -} - -func Test_domainCheck(t *testing.T) { - - ctx := context.Background() - records, err := rpc.GetAllDNSRecord(context.Background(), config.Global().Cloudflare.Zone) - require.Nil(t, err) - recordMap := convertToDNSRecordMap(records) - - tests := []struct { - name string - domainConfig *config.DomainConfig - wantErr bool - }{ - { - name: "normal existed ipv4", - domainConfig: &config.DomainConfig{ - Domain: "a.mcoder.cc", - IPVersion: "ipv4", - }, - }, - { - name: "normal not existed ipv4", - domainConfig: &config.DomainConfig{ - Domain: "a4.mcoder.cc", - IPVersion: "ipv4", - }, - }, - { - name: "normal existed ipv6", - domainConfig: &config.DomainConfig{ - Domain: "aaaa.mcoder.cc", - IPVersion: "ipv6", - }, - }, - { - name: "normal not existed ipv6", - domainConfig: &config.DomainConfig{ - Domain: "a6.mcoder.cc", - IPVersion: "ipv6", - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := domainCheck(ctx, tt.domainConfig, recordMap) - require.Equal(t, tt.wantErr, err != nil) - }) - } -} diff --git a/client/biz/ddns/helper.go b/client/biz/ddns/helper.go deleted file mode 100644 index 86cbdf0..0000000 --- a/client/biz/ddns/helper.go +++ /dev/null @@ -1,28 +0,0 @@ -package ddns - -import ( - "github.com/cloudflare/cloudflare-go" - "github.com/mcoder2014/home_server/client/config" -) - -func convertToDNSRecordMap(records []cloudflare.DNSRecord) map[string]*cloudflare.DNSRecord { - if len(records) == 0 { - return nil - } - var res = make(map[string]*cloudflare.DNSRecord) - for _, record := range records { - tmpRecord := record - res[record.Name] = &tmpRecord - } - return res -} - -func getDNSRecordType(ipVersion config.IpVersion) string { - recordType := "TXT" - if ipVersion == config.IPV4 { - recordType = "A" - } else if ipVersion == config.IPV6 { - recordType = "AAAA" - } - return recordType -} diff --git a/client/config/.gitignore b/client/config/.gitignore deleted file mode 100644 index a539470..0000000 --- a/client/config/.gitignore +++ /dev/null @@ -1 +0,0 @@ -config.yaml \ No newline at end of file diff --git a/client/config/config.go b/client/config/config.go deleted file mode 100644 index 977cdc3..0000000 --- a/client/config/config.go +++ /dev/null @@ -1,69 +0,0 @@ -package config - -import ( - "fmt" - - "github.com/mcoder2014/home_server/utils" - "github.com/sirupsen/logrus" -) - -type ClientConfig struct { - DDNSConfig []*DomainConfig `json:"ddns_config" yaml:"ddns_config"` - Cloudflare *CloudflareConfig `json:"cloudflare" yaml:"cloudflare"` -} - -// CloudflareConfig 相关的配置,用于配置域名 -type CloudflareConfig struct { - APIToken string `json:"api_token" yaml:"api_token"` - Zone string `json:"zone" yaml:"zone"` - Debug bool `json:"debug" yaml:"debug"` - Proxy string `json:"proxy" yaml:"proxy"` // 通过代理访问 cloudflare -} - -func (c *CloudflareConfig) String() string { - if c == nil { - return "" - } - return fmt.Sprintf("%+v", *c) -} - -type DomainConfig struct { - // 对应的 DDNS 域名 - Domain string `json:"domain" yaml:"domain"` - IPVersion IpVersion `json:"ip_version" yaml:"ip_version"` -} - -func (d *DomainConfig) String() string { - if d == nil { - return "" - } - return fmt.Sprintf("%+v", *d) -} - -type IpVersion string - -const ( - IPV4 IpVersion = "ipv4" - IPV6 = "ipv6" -) - -// 全局配置 -var globalConfig = ClientConfig{} - -func Global() ClientConfig { - return globalConfig -} - -func SetGlobalConfig(c ClientConfig) { - globalConfig = c -} - -// InitGlobalConfig 从指定配置文件中读取配置信息 -func InitGlobalConfig(filepath string) error { - err := utils.BindConfig(filepath, &globalConfig) - if err != nil { - return err - } - logrus.Infof("InitGlobalConfig config file path: %v", filepath) - return nil -} diff --git a/client/config/config_example.yaml b/client/config/config_example.yaml deleted file mode 100644 index 58ecb94..0000000 --- a/client/config/config_example.yaml +++ /dev/null @@ -1,12 +0,0 @@ -cloudflare: - api_token: - zone: - debug: true - -ddns_config: - - - domain: a.example.org - ip_version: ipv4 - - - domain: a6.example.org - ip_version: ipv6 \ No newline at end of file diff --git a/client/main.go b/client/main.go deleted file mode 100644 index 40431e5..0000000 --- a/client/main.go +++ /dev/null @@ -1,72 +0,0 @@ -package main - -import ( - "flag" - "os" - "os/signal" - "syscall" - "time" - - "github.com/mcoder2014/home_server/client/biz/ddns" - "github.com/mcoder2014/home_server/client/config" - "github.com/sirupsen/logrus" -) - -func main() { - logrus.SetFormatter(&logrus.TextFormatter{ - DisableColors: false, - FullTimestamp: true, - TimestampFormat: "2006-01-02T15:04:05.000000", - }) - - cliConfig := GetConfig() - err := config.InitGlobalConfig(cliConfig.ConfigPath) - if err != nil { - logrus.WithError(err).Errorf("config.InitGlobalConfig failed") - os.Exit(1) - } - - logrus.Infof("load config:%+v", config.Global()) - - // 监听 ctrl c 信号 - exitChan := make(chan os.Signal) - signal.Notify(exitChan, os.Interrupt, os.Kill, syscall.SIGTERM) - - // 业务 routine - go ddns.StartDDNSRoutine() - - // 阻塞主线程 - exitHandle(exitChan) - logrus.Infof("program end.") -} - -func exitHandle(exitChan chan os.Signal) { - for { - select { - case sig := <-exitChan: - logrus.Infof("Get Signal: %v from sys, stop program", sig) - time.Sleep(3 * time.Second) - logrus.Infof("Force Exit") - os.Exit(1) //如果ctrl+c 关不掉程序,使用os.Exit强行关掉 - } - } -} - -type CliArgsConfig struct { - - // 配置文件路径 - ConfigPath string -} - -// GetConfig 读取命令行配置 -func GetConfig() *CliArgsConfig { - conf := &CliArgsConfig{} - - flag.StringVar(&conf.ConfigPath, "conf", "/etc/home_server/conf.yaml", "配置文件路径") - - // 从arguments中解析注册的flag。必须在所有flag都注册好而未访问其值时执行。未注册却使用flag -help时,会返回ErrHelp。 - flag.Parse() - - logrus.Infof("Got Cli Args: %v", *conf) - return conf -} diff --git a/client/rpc/cloudflare.go b/client/rpc/cloudflare.go deleted file mode 100644 index cc33d26..0000000 --- a/client/rpc/cloudflare.go +++ /dev/null @@ -1,117 +0,0 @@ -package rpc - -import ( - "context" - "fmt" - "log" - "net/http" - "strings" - "time" - - "github.com/cloudflare/cloudflare-go" - "github.com/mcoder2014/home_server/client/config" - "github.com/sirupsen/logrus" - "golang.org/x/net/proxy" -) - -func getApi() (*cloudflare.API, error) { - if config.Global().Cloudflare == nil { - return nil, fmt.Errorf("cloudflare config is nil") - } - apiToken := config.Global().Cloudflare.APIToken - var opts []cloudflare.Option - proxyStr := config.Global().Cloudflare.Proxy // 格式 "127.0.0.1:1080" - if proxyStr != "" { - // 1. 创建一个 SOCKS5 proxy - dialer, err := proxy.SOCKS5("tcp", proxyStr, nil, proxy.Direct) - if err != nil { - log.Fatalf("Failed to create SOCKS5 dialer: %v", err) - } - - // 2. 将 proxy 转换为 DialContext 类型,以便在 http.Transport 中使用 - dialContext, ok := dialer.(proxy.ContextDialer) - if !ok { - log.Fatal("SOCKS5 dialer does not implement ContextDialer") - } - - // 3. 创建一个自定义的 http.Transport,并设置其 DialContext - transport := &http.Transport{ - DialContext: dialContext.DialContext, - // 你可以根据需要设置其他 Transport 字段,例如 TLSClientConfig, MaxIdleConns 等 - // 注意:不要在这里设置 Proxy 字段,因为我们已经用 DialContext 接管了连接 - } - - // 4. 使用自定义的 Transport 创建 http.Client - httpClient := &http.Client{ - Transport: transport, - Timeout: 20 * time.Second, // 设置一个超时时间 - } - opts = append(opts, cloudflare.HTTPClient(httpClient)) - logrus.Infof("get cloudflare api using proxy=%s", proxyStr) - } - - api, err := cloudflare.NewWithAPIToken(apiToken, opts...) - if err != nil { - return nil, err - } - api.Debug = config.Global().Cloudflare.Debug - return api, nil -} - -func GetAllDNSRecord(ctx context.Context, zone string) ([]cloudflare.DNSRecord, error) { - api, err := getApi() - if err != nil { - return nil, err - } - - //// Fetch the zone ID for zone example.org - //zoneID, err := api.ZoneIDByName(zone) - //if err != nil { - // return nil, err - //} - - // Fetch all DNS records for example.org - records, err := api.DNSRecords(context.Background(), zone, cloudflare.DNSRecord{}) - if err != nil { - return nil, err - } - - var sb strings.Builder - for _, record := range records { - sb.WriteString("[domain=") - sb.WriteString(record.Name) - sb.WriteString(" type=") - sb.WriteString(record.Type) - sb.WriteString(" content=") - sb.WriteString(record.Content) - sb.WriteString("],\t") - } - logrus.Infof("get ddns configs: len(%d), content=%s", len(records), sb.String()) - - return records, nil -} - -func CreateRecord(ctx context.Context, zone string, record cloudflare.DNSRecord) error { - api, err := getApi() - if err != nil { - return err - } - - resp, err := api.CreateDNSRecord(ctx, zone, record) - if err != nil { - return err - } - if !resp.Success { - return fmt.Errorf("create dns record failed: %+v", resp) - } - return nil -} - -func UpdateRecord(ctx context.Context, zone string, recordID string, record cloudflare.DNSRecord) error { - api, err := getApi() - if err != nil { - return err - } - err = api.UpdateDNSRecord(ctx, zone, recordID, record) - return err -} diff --git a/client/rpc/cloudflare_test.go b/client/rpc/cloudflare_test.go deleted file mode 100644 index 6807afc..0000000 --- a/client/rpc/cloudflare_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package rpc - -import ( - "context" - "fmt" - "testing" - - "github.com/mcoder2014/home_server/client/testutil" - "github.com/stretchr/testify/require" -) - -func TestMain(t *testing.M) { - _ = testutil.Init() - t.Run() -} - -func TestGetAllDNSRecord(t *testing.T) { - records, err := GetAllDNSRecord(context.Background(), "mcoder.cc") - require.Nil(t, err) - fmt.Printf("records: \t%+v\n", records) -} diff --git a/client/testutil/ut.go b/client/testutil/ut.go deleted file mode 100644 index a0105a5..0000000 --- a/client/testutil/ut.go +++ /dev/null @@ -1,27 +0,0 @@ -package testutil - -import ( - "os" - - "github.com/mcoder2014/home_server/client/config" - "github.com/mcoder2014/home_server/utils/routine" -) - -func Init() error { - configPath := "config/config.yaml" - - if path, ok := os.LookupEnv("TEST_CONFIG_PATH"); ok { - configPath = path - } - - // go - routine.Init() - - // 读取 config 信息 - err := config.InitGlobalConfig(configPath) - if err != nil { - return err - } - - return nil -} diff --git a/config/systemd/home_client.service b/config/systemd/home_client.service deleted file mode 100644 index a34ceb4..0000000 --- a/config/systemd/home_client.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=Home client service -Documentation=https://www.mcoder.cc -After=network.target nss-lookup.target -Wants=network.target - -[Service] -User=nobody -CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE -AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE -NoNewPrivileges=true -ExecStart=home_client -conf /etc/home_server/client_config.yaml -Restart=on-failure - -[Install] -WantedBy=multi-user.target -Alias=home_client.service \ No newline at end of file diff --git a/script/boot_client.sh b/script/boot_client.sh deleted file mode 100644 index 4f35dcd..0000000 --- a/script/boot_client.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -PROGRAM_NAME="home_client" -CURDIR=$(cd $(dirname $0); pwd) - -export GIN_MODE=release - -exec $CURDIR/bin/$PROGRAM_NAME -conf $CURDIR/client_config.yaml \ No newline at end of file diff --git a/script/systemd/home_client.service b/script/systemd/home_client.service deleted file mode 100644 index b14a9d3..0000000 --- a/script/systemd/home_client.service +++ /dev/null @@ -1,17 +0,0 @@ -[Unit] -Description=Home client service -Documentation=https://github.com/mcoder2014/home_server -After=network.target nss-lookup.target -Wants=network.target - -[Service] -User=nobody -CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE -AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE -NoNewPrivileges=true -ExecStart=home_client -conf /etc/home_server/client_config.yaml -Restart=on-failure - -[Install] -WantedBy=multi-user.target -Alias=home_client.service \ No newline at end of file