github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/sysconfig/sysconfig.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2020 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 sysconfig 21 22 import ( 23 "path/filepath" 24 25 "github.com/snapcore/snapd/gadget" 26 ) 27 28 // See https://github.com/snapcore/core20/pull/46 29 const writableDefaultsDir = "_writable_defaults" 30 31 // Options is the set of options used to configure the run system 32 type Options struct { 33 // CloudInitSrcDir is where to find the cloud-init data when installing it, 34 // i.e. in early boot install mode it could be something like 35 // filepath.Join(boot.InitramfsUbuntuSeedDir,"data") 36 CloudInitSrcDir string 37 38 // TargetRootDir is the root directory where to install configure 39 // data, i.e. for cloud-init during the initramfs it will be something like 40 // boot.InstallHostWritableDir 41 TargetRootDir string 42 43 // AllowCloudInit is whether to allow cloud-init to run or not in the 44 // TargetRootDir. 45 AllowCloudInit bool 46 47 // GadgetDir is the path of the mounted gadget snap. 48 GadgetDir string 49 } 50 51 // FilesystemOnlyApplyOptions is the set of options for 52 // ApplyFilesystemOnlyDefaults. 53 type FilesystemOnlyApplyOptions struct { 54 // Classic is true when the system in rootdir is a classic system 55 Classic bool 56 } 57 58 // ApplyFilesystemOnlyDefaultsImpl is initialized by init() of configcore. 59 var ApplyFilesystemOnlyDefaultsImpl = func(rootDir string, defaults map[string]interface{}, options *FilesystemOnlyApplyOptions) error { 60 panic("ApplyFilesystemOnlyDefaultsImpl is unset, import overlord/configstate/configcore") 61 } 62 63 // ApplyFilesystemOnlyDefaults applies (via configcore.filesystemOnlyApply()) 64 // filesystem modifications under rootDir, according to the defaults. 65 // This is a subset of core config options that is important 66 // early during boot, before all the configuration is applied as part of 67 // normal execution of configure hook. 68 func ApplyFilesystemOnlyDefaults(rootDir string, defaults map[string]interface{}, options *FilesystemOnlyApplyOptions) error { 69 return ApplyFilesystemOnlyDefaultsImpl(rootDir, defaults, options) 70 } 71 72 // ConfigureRunSystem configures the ubuntu-data partition with any 73 // configuration needed from e.g. the gadget or for cloud-init (and also for 74 // cloud-init from the gadget). 75 func ConfigureRunSystem(opts *Options) error { 76 if err := configureCloudInit(opts); err != nil { 77 return err 78 } 79 80 if opts.GadgetDir != "" { 81 ginf, err := gadget.ReadInfo(opts.GadgetDir, nil) 82 if err != nil { 83 return err 84 } 85 defaults := gadget.SystemDefaults(ginf.Defaults) 86 if len(defaults) > 0 { 87 // options are nil which implies core system 88 var options *FilesystemOnlyApplyOptions 89 if err := ApplyFilesystemOnlyDefaults(WritableDefaultsDir(opts.TargetRootDir), defaults, options); err != nil { 90 return err 91 } 92 } 93 } 94 95 return nil 96 } 97 98 // WritableDefaultsDir returns the full path of the joined subdir under the 99 // subtree for default content for system data living at rootdir, 100 // i.e. rootdir/_writable_defaults/subdir... 101 func WritableDefaultsDir(rootdir string, subdir ...string) string { 102 return filepath.Join(rootdir, writableDefaultsDir, filepath.Join(subdir...)) 103 }