github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/supervisor/install/install_linux.go (about)

     1  /*
     2   * Copyright (C) 2020 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package install
    19  
    20  import (
    21  	"bytes"
    22  	"text/template"
    23  
    24  	"github.com/rs/zerolog/log"
    25  
    26  	"github.com/takama/daemon"
    27  )
    28  
    29  const daemonName = "myst_supervisor"
    30  const description = "Myst Supervisor"
    31  const descriptor = `
    32  [Unit]
    33  Description={{.Description}}
    34  Documentation=https://mysterium.network/
    35  
    36  [Service]
    37  PIDFile=/run/{{.Name}}.pid
    38  ExecStartPre=/bin/rm -f /run/{{.Name}}.pid
    39  ExecStart={{.Path}} {{.Args}}
    40  Restart=on-failure
    41  
    42  [Install]
    43  WantedBy=multi-user.target
    44  `
    45  
    46  // Install installs service for linux.
    47  func Install(options Options) error {
    48  	if !options.valid() {
    49  		return errInvalid
    50  	}
    51  
    52  	log.Info().Msg("Configuring Myst Supervisor")
    53  	dmn, err := mystSupervisorDaemon(options)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	log.Info().Msg("Cleaning up previous installation")
    59  	clean(dmn)
    60  
    61  	log.Info().Msg("Installing daemon")
    62  	err = execAndLog(func() (string, error) { return dmn.Install() })
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	err = execAndLog(dmn.Start)
    68  	return err
    69  }
    70  
    71  func mystSupervisorDaemon(options Options) (daemon.Daemon, error) {
    72  	dmn, err := daemon.New(daemonName, description, daemon.SystemDaemon)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	t, err := template.New("unit-descriptor").Parse(descriptor)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	buffer := new(bytes.Buffer)
    82  	err = t.Execute(buffer, map[string]string{
    83  		"Path":        options.SupervisorPath,
    84  		"Description": "{{.Description}}",
    85  		"Name":        "{{.Name}}",
    86  		"Args":        "{{.Args}}",
    87  	})
    88  	if err != nil {
    89  		return nil, err
    90  	}
    91  
    92  	err = dmn.SetTemplate(buffer.String())
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	return dmn, err
    97  }
    98  
    99  func clean(d daemon.Daemon) error {
   100  	execAndLog(d.Stop)
   101  	return execAndLog(d.Remove)
   102  }
   103  
   104  func execAndLog(action func() (string, error)) error {
   105  	output, err := action()
   106  	if err != nil {
   107  		log.Error().Msgf("%s\t%s", output, err)
   108  		return err
   109  	}
   110  	log.Info().Msg(output)
   111  	return nil
   112  }
   113  
   114  // Uninstall remove supervisor daemon
   115  func Uninstall() error {
   116  	log.Info().Msg("Uninstalling Myst Supervisor daemon")
   117  	dmn, err := daemon.New(daemonName, description, daemon.SystemDaemon)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	return clean(dmn)
   122  }