github.com/stolowski/snapd@v0.0.0-20210407085831-115137ce5a22/overlord/configstate/configcore/picfg.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 configcore 21 22 import ( 23 "fmt" 24 "os" 25 "path/filepath" 26 "strings" 27 28 "github.com/snapcore/snapd/dirs" 29 "github.com/snapcore/snapd/osutil" 30 "github.com/snapcore/snapd/overlord/configstate/config" 31 ) 32 33 // valid pi config keys 34 var piConfigKeys = map[string]bool{ 35 "disable_overscan": true, 36 "force_turbo": true, 37 "framebuffer_width": true, 38 "framebuffer_height": true, 39 "framebuffer_depth": true, 40 "framebuffer_ignore_alpha": true, 41 "overscan_left": true, 42 "overscan_right": true, 43 "overscan_top": true, 44 "overscan_bottom": true, 45 "overscan_scale": true, 46 "display_rotate": true, 47 "hdmi_cvt": true, 48 "hdmi_group": true, 49 "hdmi_mode": true, 50 "hdmi_timings": true, 51 "hdmi_drive": true, 52 "avoid_warnings": true, 53 "gpu_mem_256": true, 54 "gpu_mem_512": true, 55 "gpu_mem": true, 56 "sdtv_aspect": true, 57 "config_hdmi_boost": true, 58 "hdmi_force_hotplug": true, 59 "start_x": true, 60 } 61 62 func init() { 63 // add supported config keys 64 for k := range piConfigKeys { 65 s := fmt.Sprintf("core.pi-config.%s", strings.Replace(k, "_", "-", -1)) 66 supportedConfigurations[s] = true 67 } 68 } 69 70 func updatePiConfig(path string, config map[string]string) error { 71 f, err := os.Open(path) 72 if err != nil { 73 return err 74 } 75 defer f.Close() 76 77 toWrite, err := updateKeyValueStream(f, piConfigKeys, config) 78 if err != nil { 79 return err 80 } 81 82 if toWrite != nil { 83 s := strings.Join(toWrite, "\n") 84 // ensure we have a final newline in the file 85 s += "\n" 86 return osutil.AtomicWriteFile(path, []byte(s), 0644, 0) 87 } 88 89 return nil 90 } 91 92 func piConfigFile(opts *fsOnlyContext) string { 93 rootDir := dirs.GlobalRootDir 94 if opts != nil { 95 rootDir = opts.RootDir 96 } 97 return filepath.Join(rootDir, "/boot/uboot/config.txt") 98 } 99 100 func handlePiConfiguration(tr config.ConfGetter, opts *fsOnlyContext) error { 101 if osutil.FileExists(piConfigFile(opts)) { 102 // snapctl can actually give us the whole dict in 103 // JSON, in a single call; use that instead of this. 104 config := map[string]string{} 105 for key := range piConfigKeys { 106 output, err := coreCfg(tr, fmt.Sprintf("pi-config.%s", strings.Replace(key, "_", "-", -1))) 107 if err != nil { 108 return err 109 } 110 config[key] = output 111 } 112 if err := updatePiConfig(piConfigFile(opts), config); err != nil { 113 return err 114 } 115 } 116 return nil 117 }