github.com/anonymouse64/snapd@v0.0.0-20210824153203-04c4c42d842d/cmd/snap/cmd_handle_link.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2018 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 main
    21  
    22  import (
    23  	"fmt"
    24  	"os"
    25  	"syscall"
    26  	"time"
    27  
    28  	"github.com/jessevdk/go-flags"
    29  
    30  	"github.com/snapcore/snapd/i18n"
    31  	"github.com/snapcore/snapd/usersession/userd/ui"
    32  )
    33  
    34  type cmdHandleLink struct {
    35  	waitMixin
    36  
    37  	Positional struct {
    38  		Uri string `positional-arg-name:"<uri>"`
    39  	} `positional-args:"yes" required:"yes"`
    40  }
    41  
    42  func init() {
    43  	cmd := addCommand("handle-link",
    44  		i18n.G("Handle a snap:// URI"),
    45  		i18n.G("The handle-link command installs the snap-store snap and then invokes it."),
    46  		func() flags.Commander {
    47  			return &cmdHandleLink{}
    48  		}, nil, nil)
    49  	cmd.hidden = true
    50  }
    51  
    52  func (x *cmdHandleLink) ensureSnapStoreInstalled() error {
    53  	// If the snap-store snap is installed, our work is done
    54  	if _, _, err := x.client.Snap("snap-store"); err == nil {
    55  		return nil
    56  	}
    57  
    58  	dialog, err := ui.New()
    59  	if err != nil {
    60  		return err
    61  	}
    62  	answeredYes := dialog.YesNo(
    63  		i18n.G("Install snap-aware Snap Store snap?"),
    64  		i18n.G("The Snap Store is required to open snaps from a web browser."),
    65  		&ui.DialogOptions{
    66  			Timeout: 5 * time.Minute,
    67  			Footer:  i18n.G("This dialog will close automatically after 5 minutes of inactivity."),
    68  		})
    69  	if !answeredYes {
    70  		return fmt.Errorf(i18n.G("Snap Store required"))
    71  	}
    72  
    73  	changeID, err := x.client.Install("snap-store", nil)
    74  	if err != nil {
    75  		return err
    76  	}
    77  	_, err = x.wait(changeID)
    78  	if err != nil && err != noWait {
    79  		return err
    80  	}
    81  	return nil
    82  }
    83  
    84  func (x *cmdHandleLink) Execute([]string) error {
    85  	if err := x.ensureSnapStoreInstalled(); err != nil {
    86  		return err
    87  	}
    88  
    89  	argv := []string{"snap", "run", "snap-store", x.Positional.Uri}
    90  	return syscall.Exec("/proc/self/exe", argv, os.Environ())
    91  }