github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/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 }