github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/wrappers/binaries.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2014-2016 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  // Package wrappers is used to generate wrappers and service units and also desktop files for snap applications.
    21  package wrappers
    22  
    23  import (
    24  	"os"
    25  
    26  	"github.com/snapcore/snapd/dirs"
    27  	"github.com/snapcore/snapd/osutil"
    28  	"github.com/snapcore/snapd/snap"
    29  )
    30  
    31  // AddSnapBinaries writes the wrapper binaries for the applications from the snap which aren't services.
    32  func AddSnapBinaries(s *snap.Info) (err error) {
    33  	var created []string
    34  	defer func() {
    35  		if err == nil {
    36  			return
    37  		}
    38  		for _, fn := range created {
    39  			os.Remove(fn)
    40  		}
    41  	}()
    42  
    43  	if err := os.MkdirAll(dirs.SnapBinariesDir, 0755); err != nil {
    44  		return err
    45  	}
    46  
    47  	completeSh := dirs.CompleteShPath(s.Base)
    48  	noCompletion := !osutil.IsWritable(dirs.CompletersDir) || !osutil.FileExists(completeSh)
    49  	for _, app := range s.Apps {
    50  		if app.IsService() {
    51  			continue
    52  		}
    53  
    54  		wrapperPath := app.WrapperPath()
    55  		if err := os.Remove(wrapperPath); err != nil && !os.IsNotExist(err) {
    56  			return err
    57  		}
    58  		if err := os.Symlink("/usr/bin/snap", wrapperPath); err != nil {
    59  			return err
    60  		}
    61  		created = append(created, wrapperPath)
    62  
    63  		if noCompletion || app.Completer == "" {
    64  			continue
    65  		}
    66  		// symlink the completion snippet
    67  		compPath := app.CompleterPath()
    68  		if err := os.Symlink(completeSh, compPath); err == nil {
    69  			created = append(created, compPath)
    70  		} else if !os.IsExist(err) {
    71  			return err
    72  		}
    73  	}
    74  
    75  	return nil
    76  }
    77  
    78  // RemoveSnapBinaries removes the wrapper binaries for the applications from the snap which aren't services from.
    79  func RemoveSnapBinaries(s *snap.Info) error {
    80  	for _, app := range s.Apps {
    81  		os.Remove(app.WrapperPath())
    82  		if app.Completer == "" {
    83  			continue
    84  		}
    85  		compPath := app.CompleterPath()
    86  		if dirs.IsCompleteShSymlink(compPath) {
    87  			os.Remove(compPath)
    88  		}
    89  	}
    90  
    91  	return nil
    92  }