<commit_before>// Package klientsvc implements means to install, start
// and stop klient process as a system service.
package klientsvc

import (
	"io"
	"log"
	"os"
	"path/filepath"

	"koding/kites/config"
	"koding/klient/tunnel/tlsproxy"
	"koding/klient/uploader"

	"github.com/koding/service"
)

// DefaultService is a default klient service
// deployed within Koding.
var DefaultService = &Service{
	InstallDir: "/opt/kite/klient",
	KlientBin:  os.Args[0],
	Username:   config.CurrentUser.Username,
}

// Service is a klient-specific wrapper for
// a generic service.
type Service struct {
	InstallDir string
	KlientBin  string
	Username   string
}

// Install installs the service.
func (s *Service) Install() error {
	fr, err := os.Open(s.KlientBin)
	if err != nil {
		return err
	}
	defer fr.Close()

	cfg := s.config()

	fw, err := os.OpenFile(cfg.Executable, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0755)
	if err != nil {
		return err
	}

	_, err = io.Copy(fw, fr)
	if err := nonil(err, fw.Close()); err != nil {
		return err
	}

	svc, err := service.New(nopService{}, cfg)
	if err != nil {
		return err
	}

	// All the following are best-effort methods
	// to either ensure log files have proper
	// permissions so klient can upload them,
	// or sets static routes for local routing
	// webterm optimizations.
	//
	// Ignore the errors as they're not vital.
	_ = uploader.FixPerms()
	_ = tlsproxy.Init()
	_ = svc.Uninstall()

	return svc.Install()
}

// Start starts the service.
func (s *Service) Start() error {
	svc, err := service.New(nopService{}, s.config())
	if err != nil {
		return err
	}

	return svc.Start()
}

// Stop stops the service.
func (s *Service) Stop() error {
	svc, err := service.New(nopService{}, s.config())
	if err != nil {
		return err
	}

	return svc.Stop()
}

// Uninstall uninstalls the service.
func (s *Service) Uninstall() error {
	svc, err := service.New(nopService{}, s.config())
	if err != nil {
		return err
	}

	return svc.Uninstall()<commit_msg>klient: try to stop first before uninstalling<commit_after>// Package klientsvc implements means to install, start
// and stop klient process as a system service.
package klientsvc

import (
	"io"
	"log"
	"os"
	"path/filepath"

	"koding/kites/config"
	"koding/klient/tunnel/tlsproxy"
	"koding/klient/uploader"

	"github.com/koding/service"
)

// DefaultService is a default klient service
// deployed within Koding.
var DefaultService = &Service{
	InstallDir: "/opt/kite/klient",
	KlientBin:  os.Args[0],
	Username:   config.CurrentUser.Username,
}

// Service is a klient-specific wrapper for
// a generic service.
type Service struct {
	InstallDir string
	KlientBin  string
	Username   string
}

// Install installs the service.
func (s *Service) Install() error {
	fr, err := os.Open(s.KlientBin)
	if err != nil {
		return err
	}
	defer fr.Close()

	cfg := s.config()

	fw, err := os.OpenFile(cfg.Executable, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0755)
	if err != nil {
		return err
	}

	_, err = io.Copy(fw, fr)
	if err := nonil(err, fw.Close()); err != nil {
		return err
	}

	svc, err := service.New(nopService{}, cfg)
	if err != nil {
		return err
	}

	// All the following are best-effort methods
	// to either ensure log files have proper
	// permissions so klient can upload them,
	// or sets static routes for local routing
	// webterm optimizations.
	//
	// Ignore the errors as they're not vital.
	_ = uploader.FixPerms()
	_ = tlsproxy.Init()
	_ = svc.Uninstall()

	return svc.Install()
}

// Start starts the service.
func (s *Service) Start() error {
	svc, err := service.New(nopService{}, s.config())
	if err != nil {
		return err
	}

	return svc.Start()
}

// Stop stops the service.
func (s *Service) Stop() error {
	svc, err := service.New(nopService{}, s.config())
	if err != nil {
		return err
	}

	return svc.Stop()
}

// Uninstall uninstalls the service.
func (s *Service) Uninstall() error {
	svc, err := service.New(nopService{}, s.config())
	if err != nil {
		return err
	}

	_ = svc.Stop()

	return svc.Uninstall()
{'fraction_non_alphanumeric': 0.1352692975924547, 'fraction_numerical': 0.002482005460412013, 'mean_word_length': 3.3661971830985915, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2483251', 'n_tokens_mistral': 1493, 'n_tokens_neox': 1433, 'n_words': 434}