gitee.com/mysnapcore/mysnapd@v0.1.0/cmd/snap-update-ns/main.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2017 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 27 "github.com/jessevdk/go-flags" 28 29 "gitee.com/mysnapcore/mysnapd/logger" 30 ) 31 32 var opts struct { 33 FromSnapConfine bool `long:"from-snap-confine"` 34 UserMounts bool `long:"user-mounts"` 35 UserID int `short:"u"` 36 Positionals struct { 37 SnapName string `positional-arg-name:"SNAP_NAME" required:"yes"` 38 } `positional-args:"true"` 39 } 40 41 // IMPORTANT: all the code in main() until bootstrap is finished may be run 42 // with elevated privileges when invoking snap-update-ns from the setuid 43 // snap-confine. 44 45 func main() { 46 logger.SimpleSetup() 47 if err := run(); err != nil { 48 fmt.Printf("cannot update snap namespace: %s\n", err) 49 os.Exit(1) 50 } 51 // END IMPORTANT 52 } 53 54 func parseArgs(args []string) error { 55 parser := flags.NewParser(&opts, flags.HelpFlag|flags.PassDoubleDash|flags.PassAfterNonOption) 56 _, err := parser.ParseArgs(args) 57 return err 58 } 59 60 // IMPORTANT: all the code in run() until BootStrapError() is finished may 61 // be run with elevated privileges when invoking snap-update-ns from 62 // the setuid snap-confine. 63 64 func run() error { 65 // There is some C code that runs before main() is started. 66 // That code always runs and sets an error condition if it fails. 67 // Here we just check for the error. 68 if err := BootstrapError(); err != nil { 69 // If there is no mount namespace to transition to let's just quit 70 // instantly without any errors as there is nothing to do anymore. 71 if err == ErrNoNamespace { 72 logger.Debugf("no preserved mount namespace, nothing to update") 73 return nil 74 } 75 return err 76 } 77 // END IMPORTANT 78 79 if err := parseArgs(os.Args[1:]); err != nil { 80 return err 81 } 82 83 // Explicitly set the umask to 0 to prevent permission bits 84 // being masked out when creating files and directories. 85 // 86 // While snap-confine already does this for us, we inherit 87 // snapd's umask when it invokes us. 88 syscall.Umask(0) 89 90 var upCtx MountProfileUpdateContext 91 if opts.UserMounts { 92 upCtx = NewUserProfileUpdateContext(opts.Positionals.SnapName, opts.FromSnapConfine, os.Getuid()) 93 } else { 94 upCtx = NewSystemProfileUpdateContext(opts.Positionals.SnapName, opts.FromSnapConfine) 95 } 96 return executeMountProfileUpdate(upCtx) 97 }