github.com/rigado/snapd@v2.42.5-go-mod+incompatible/overlord/configstate/configcore/corecfg.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  
    26  	"github.com/snapcore/snapd/overlord/configstate/config"
    27  	"github.com/snapcore/snapd/release"
    28  )
    29  
    30  var (
    31  	Stdout = os.Stdout
    32  	Stderr = os.Stderr
    33  )
    34  
    35  // coreCfg returns the configuration value for the core snap.
    36  func coreCfg(tr config.Conf, key string) (result string, err error) {
    37  	var v interface{} = ""
    38  	if err := tr.Get("core", key, &v); err != nil && !config.IsNoOption(err) {
    39  		return "", err
    40  	}
    41  	// TODO: we could have a fully typed approach but at the
    42  	// moment we also always use "" to mean unset as well, this is
    43  	// the smallest change
    44  	return fmt.Sprintf("%v", v), nil
    45  }
    46  
    47  // supportedConfigurations contains a set of handled configuration keys.
    48  // The actual values are populated by `init()` functions in each module.
    49  var supportedConfigurations = make(map[string]bool, 32)
    50  
    51  func validateBoolFlag(tr config.Conf, flag string) error {
    52  	value, err := coreCfg(tr, flag)
    53  	if err != nil {
    54  		return err
    55  	}
    56  	switch value {
    57  	case "", "true", "false":
    58  		// noop
    59  	default:
    60  		return fmt.Errorf("%s can only be set to 'true' or 'false'", flag)
    61  	}
    62  	return nil
    63  }
    64  
    65  func Run(tr config.Conf) error {
    66  	// check if the changes
    67  	for _, k := range tr.Changes() {
    68  		if !supportedConfigurations[k] {
    69  			return fmt.Errorf("cannot set %q: unsupported system option", k)
    70  		}
    71  	}
    72  
    73  	if err := validateProxyStore(tr); err != nil {
    74  		return err
    75  	}
    76  	if err := validateRefreshSchedule(tr); err != nil {
    77  		return err
    78  	}
    79  	if err := validateRefreshRateLimit(tr); err != nil {
    80  		return err
    81  	}
    82  	if err := validateExperimentalSettings(tr); err != nil {
    83  		return err
    84  	}
    85  	if err := validateWatchdogOptions(tr); err != nil {
    86  		return err
    87  	}
    88  	if err := validateNetworkSettings(tr); err != nil {
    89  		return err
    90  	}
    91  	if err := validateAutomaticSnapshotsExpiration(tr); err != nil {
    92  		return err
    93  	}
    94  	// FIXME: ensure the user cannot set "core seed.loaded"
    95  
    96  	// capture cloud information
    97  	if err := setCloudInfoWhenSeeding(tr); err != nil {
    98  		return err
    99  	}
   100  
   101  	// Export experimental.* flags to a place easily accessible from snapd helpers.
   102  	if err := ExportExperimentalFlags(tr); err != nil {
   103  		return err
   104  	}
   105  
   106  	// see if it makes sense to run at all
   107  	if release.OnClassic {
   108  		// nothing to do
   109  		return nil
   110  	}
   111  	// TODO: consider allowing some of these on classic too?
   112  	// consider erroring on core-only options on classic?
   113  
   114  	// handle the various core config options:
   115  	// service.*.disable
   116  	if err := handleServiceDisableConfiguration(tr); err != nil {
   117  		return err
   118  	}
   119  	// system.power-key-action
   120  	if err := handlePowerButtonConfiguration(tr); err != nil {
   121  		return err
   122  	}
   123  	// pi-config.*
   124  	if err := handlePiConfiguration(tr); err != nil {
   125  		return err
   126  	}
   127  	// proxy.{http,https,ftp}
   128  	if err := handleProxyConfiguration(tr); err != nil {
   129  		return err
   130  	}
   131  	// watchdog.{runtime-timeout,shutdown-timeout}
   132  	if err := handleWatchdogConfiguration(tr); err != nil {
   133  		return err
   134  	}
   135  	// network.disable-ipv6
   136  	if err := handleNetworkConfiguration(tr); err != nil {
   137  		return err
   138  	}
   139  
   140  	return nil
   141  }