github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/gadget/validate.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 gadget 21 22 import ( 23 "fmt" 24 "path/filepath" 25 "strings" 26 27 "github.com/snapcore/snapd/osutil" 28 ) 29 30 func validateVolumeContentsPresence(gadgetSnapRootDir string, vol *LaidOutVolume) error { 31 // bare structure content is checked to exist during layout 32 // make sure that filesystem content source paths exist as well 33 for _, s := range vol.LaidOutStructure { 34 if !s.HasFilesystem() { 35 continue 36 } 37 for _, c := range s.Content { 38 realSource := filepath.Join(gadgetSnapRootDir, c.Source) 39 if !osutil.FileExists(realSource) { 40 return fmt.Errorf("structure %v, content %v: source path does not exist", s, c) 41 } 42 if strings.HasSuffix(c.Source, "/") { 43 // expecting a directory 44 if err := checkSourceIsDir(realSource + "/"); err != nil { 45 return fmt.Errorf("structure %v, content %v: %v", s, c, err) 46 } 47 } 48 } 49 } 50 return nil 51 } 52 53 // Validate checks whether the given directory contains valid gadget snap 54 // metadata and a matching content, under the provided model constraints, which 55 // are handled identically to ReadInfo(). 56 func Validate(gadgetSnapRootDir string, model Model) error { 57 info, err := ReadInfo(gadgetSnapRootDir, model) 58 if err != nil { 59 return fmt.Errorf("invalid gadget metadata: %v", err) 60 } 61 62 for name, vol := range info.Volumes { 63 lv, err := LayoutVolume(gadgetSnapRootDir, &vol, defaultConstraints) 64 if err != nil { 65 return fmt.Errorf("invalid layout of volume %q: %v", name, err) 66 } 67 if err := validateVolumeContentsPresence(gadgetSnapRootDir, lv); err != nil { 68 return fmt.Errorf("invalid volume %q: %v", name, err) 69 } 70 } 71 72 return nil 73 }