@@ -25,6 +25,9 @@ func runApp(app *cli.App, graceShutdownC chan struct{}) {
2525 Name : "install" ,
2626 Usage : "Install cloudflared as a system service" ,
2727 Action : cliutil .ConfiguredAction (installLinuxService ),
28+ Flags : []cli.Flag {
29+ noUpdateServiceFlag ,
30+ },
2831 },
2932 {
3033 Name : "uninstall" ,
@@ -39,15 +42,17 @@ func runApp(app *cli.App, graceShutdownC chan struct{}) {
3942// The directory and files that are used by the service.
4043// These are hard-coded in the templates below.
4144const (
42- serviceConfigDir = "/etc/cloudflared"
43- serviceConfigFile = "config.yml"
44- serviceCredentialFile = "cert.pem"
45- serviceConfigPath = serviceConfigDir + "/" + serviceConfigFile
46- cloudflaredService = "cloudflared.service"
45+ serviceConfigDir = "/etc/cloudflared"
46+ serviceConfigFile = "config.yml"
47+ serviceCredentialFile = "cert.pem"
48+ serviceConfigPath = serviceConfigDir + "/" + serviceConfigFile
49+ cloudflaredService = "cloudflared.service"
50+ cloudflaredUpdateService = "cloudflared-update.service"
51+ cloudflaredUpdateTimer = "cloudflared-update.timer"
4752)
4853
49- var systemdTemplates = [ ]ServiceTemplate {
50- {
54+ var systemdAllTemplates = map [ string ]ServiceTemplate {
55+ cloudflaredService : {
5156 Path : fmt .Sprintf ("/etc/systemd/system/%s" , cloudflaredService ),
5257 Content : `[Unit]
5358Description=cloudflared
@@ -64,8 +69,8 @@ RestartSec=5s
6469WantedBy=multi-user.target
6570` ,
6671 },
67- {
68- Path : "/etc/systemd/system/cloudflared-update.service" ,
72+ cloudflaredUpdateService : {
73+ Path : fmt . Sprintf ( "/etc/systemd/system/%s" , cloudflaredUpdateService ) ,
6974 Content : `[Unit]
7075Description=Update cloudflared
7176After=network.target
@@ -74,8 +79,8 @@ After=network.target
7479ExecStart=/bin/bash -c '{{ .Path }} update; code=$?; if [ $code -eq 11 ]; then systemctl restart cloudflared; exit 0; fi; exit $code'
7580` ,
7681 },
77- {
78- Path : "/etc/systemd/system/cloudflared-update.timer" ,
82+ cloudflaredUpdateTimer : {
83+ Path : fmt . Sprintf ( "/etc/systemd/system/%s" , cloudflaredUpdateTimer ) ,
7984 Content : `[Unit]
8085Description=Update cloudflared
8186
@@ -106,7 +111,7 @@ var sysvTemplate = ServiceTemplate{
106111# Description: cloudflared agent
107112### END INIT INFO
108113name=$(basename $(readlink -f $0))
109- cmd="{{.Path}} --pidfile /var/run/$name.pid --autoupdate-freq 24h0m0s {{ range .ExtraArgs }} {{ . }}{{ end }}"
114+ cmd="{{.Path}} --pidfile /var/run/$name.pid {{ range .ExtraArgs }} {{ . }}{{ end }}"
110115pid_file="/var/run/$name.pid"
111116stdout_log="/var/log/$name.log"
112117stderr_log="/var/log/$name.err"
@@ -178,6 +183,14 @@ exit 0
178183` ,
179184}
180185
186+ var (
187+ noUpdateServiceFlag = & cli.BoolFlag {
188+ Name : "no-update-service" ,
189+ Usage : "Disable auto-update of the cloudflared linux service, which restarts the server to upgrade for new versions." ,
190+ Value : false ,
191+ }
192+ )
193+
181194func isSystemd () bool {
182195 if _ , err := os .Stat ("/run/systemd/system" ); err == nil {
183196 return true
@@ -196,6 +209,9 @@ func installLinuxService(c *cli.Context) error {
196209 Path : etPath ,
197210 }
198211
212+ // Check if the "no update flag" is set
213+ autoUpdate := ! c .IsSet (noUpdateServiceFlag .Name )
214+
199215 var extraArgsFunc func (c * cli.Context , log * zerolog.Logger ) ([]string , error )
200216 if c .NArg () == 0 {
201217 extraArgsFunc = buildArgsForConfig
@@ -213,10 +229,10 @@ func installLinuxService(c *cli.Context) error {
213229 switch {
214230 case isSystemd ():
215231 log .Info ().Msgf ("Using Systemd" )
216- err = installSystemd (& templateArgs , log )
232+ err = installSystemd (& templateArgs , autoUpdate , log )
217233 default :
218234 log .Info ().Msgf ("Using SysV" )
219- err = installSysv (& templateArgs , log )
235+ err = installSysv (& templateArgs , autoUpdate , log )
220236 }
221237
222238 if err == nil {
@@ -261,7 +277,20 @@ credentials-file: CREDENTIALS-FILE
261277 }, nil
262278}
263279
264- func installSystemd (templateArgs * ServiceTemplateArgs , log * zerolog.Logger ) error {
280+ func installSystemd (templateArgs * ServiceTemplateArgs , autoUpdate bool , log * zerolog.Logger ) error {
281+ var systemdTemplates []ServiceTemplate
282+ if autoUpdate {
283+ systemdTemplates = []ServiceTemplate {
284+ systemdAllTemplates [cloudflaredService ],
285+ systemdAllTemplates [cloudflaredUpdateService ],
286+ systemdAllTemplates [cloudflaredUpdateTimer ],
287+ }
288+ } else {
289+ systemdTemplates = []ServiceTemplate {
290+ systemdAllTemplates [cloudflaredService ],
291+ }
292+ }
293+
265294 for _ , serviceTemplate := range systemdTemplates {
266295 err := serviceTemplate .Generate (templateArgs )
267296 if err != nil {
@@ -273,23 +302,34 @@ func installSystemd(templateArgs *ServiceTemplateArgs, log *zerolog.Logger) erro
273302 log .Err (err ).Msgf ("systemctl enable %s error" , cloudflaredService )
274303 return err
275304 }
276- if err := runCommand ("systemctl" , "start" , "cloudflared-update.timer" ); err != nil {
277- log .Err (err ).Msg ("systemctl start cloudflared-update.timer error" )
278- return err
305+
306+ if autoUpdate {
307+ if err := runCommand ("systemctl" , "start" , cloudflaredUpdateTimer ); err != nil {
308+ log .Err (err ).Msgf ("systemctl start %s error" , cloudflaredUpdateTimer )
309+ return err
310+ }
279311 }
312+
280313 if err := runCommand ("systemctl" , "daemon-reload" ); err != nil {
281314 log .Err (err ).Msg ("systemctl daemon-reload error" )
282315 return err
283316 }
284317 return runCommand ("systemctl" , "start" , cloudflaredService )
285318}
286319
287- func installSysv (templateArgs * ServiceTemplateArgs , log * zerolog.Logger ) error {
320+ func installSysv (templateArgs * ServiceTemplateArgs , autoUpdate bool , log * zerolog.Logger ) error {
288321 confPath , err := sysvTemplate .ResolvePath ()
289322 if err != nil {
290323 log .Err (err ).Msg ("error resolving system path" )
291324 return err
292325 }
326+
327+ if autoUpdate {
328+ templateArgs .ExtraArgs = append ([]string {"--autoupdate-freq 24h0m0s" }, templateArgs .ExtraArgs ... )
329+ } else {
330+ templateArgs .ExtraArgs = append ([]string {"--no-autoupdate" }, templateArgs .ExtraArgs ... )
331+ }
332+
293333 if err := sysvTemplate .Generate (templateArgs ); err != nil {
294334 log .Err (err ).Msg ("error generating system template" )
295335 return err
@@ -327,19 +367,35 @@ func uninstallLinuxService(c *cli.Context) error {
327367}
328368
329369func uninstallSystemd (log * zerolog.Logger ) error {
330- if err := runCommand ("systemctl" , "disable" , cloudflaredService ); err != nil {
331- log .Err (err ).Msgf ("systemctl disable %s error" , cloudflaredService )
332- return err
370+ // Get only the installed services
371+ installedServices := make (map [string ]ServiceTemplate )
372+ for serviceName , serviceTemplate := range systemdAllTemplates {
373+ if err := runCommand ("systemctl" , "status" , serviceName ); err == nil {
374+ installedServices [serviceName ] = serviceTemplate
375+ } else {
376+ log .Info ().Msgf ("Service '%s' not installed, skipping its uninstall" , serviceName )
377+ }
333378 }
334- if err := runCommand ("systemctl" , "stop" , cloudflaredService ); err != nil {
335- log .Err (err ).Msgf ("systemctl stop %s error" , cloudflaredService )
336- return err
379+
380+ if _ , exists := installedServices [cloudflaredService ]; exists {
381+ if err := runCommand ("systemctl" , "disable" , cloudflaredService ); err != nil {
382+ log .Err (err ).Msgf ("systemctl disable %s error" , cloudflaredService )
383+ return err
384+ }
385+ if err := runCommand ("systemctl" , "stop" , cloudflaredService ); err != nil {
386+ log .Err (err ).Msgf ("systemctl stop %s error" , cloudflaredService )
387+ return err
388+ }
337389 }
338- if err := runCommand ("systemctl" , "stop" , "cloudflared-update.timer" ); err != nil {
339- log .Err (err ).Msg ("systemctl stop cloudflared-update.timer error" )
340- return err
390+
391+ if _ , exists := installedServices [cloudflaredUpdateTimer ]; exists {
392+ if err := runCommand ("systemctl" , "stop" , cloudflaredUpdateTimer ); err != nil {
393+ log .Err (err ).Msgf ("systemctl stop %s error" , cloudflaredUpdateTimer )
394+ return err
395+ }
341396 }
342- for _ , serviceTemplate := range systemdTemplates {
397+
398+ for _ , serviceTemplate := range installedServices {
343399 if err := serviceTemplate .Remove (); err != nil {
344400 log .Err (err ).Msg ("error removing service template" )
345401 return err
0 commit comments