github.com/Lephar/snapd@v0.0.0-20210825215435-c7fba9cef4d2/overlord/configstate/configcore/proxy.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  // +build !nomanagers
     3  
     4  /*
     5   * Copyright (C) 2017 Canonical Ltd
     6   *
     7   * This program is free software: you can redistribute it and/or modify
     8   * it under the terms of the GNU General Public License version 3 as
     9   * published by the Free Software Foundation.
    10   *
    11   * This program is distributed in the hope that it will be useful,
    12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14   * GNU General Public License for more details.
    15   *
    16   * You should have received a copy of the GNU General Public License
    17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18   *
    19   */
    20  
    21  package configcore
    22  
    23  import (
    24  	"fmt"
    25  	"io/ioutil"
    26  	"os"
    27  	"path/filepath"
    28  	"strings"
    29  
    30  	"github.com/snapcore/snapd/asserts"
    31  	"github.com/snapcore/snapd/dirs"
    32  	"github.com/snapcore/snapd/overlord/assertstate"
    33  	"github.com/snapcore/snapd/overlord/configstate/config"
    34  )
    35  
    36  var proxyConfigKeys = map[string]bool{
    37  	"http_proxy":  true,
    38  	"https_proxy": true,
    39  	"ftp_proxy":   true,
    40  	"no_proxy":    true,
    41  }
    42  
    43  func init() {
    44  	// add supported configuration of this module
    45  	supportedConfigurations["core.proxy.http"] = true
    46  	supportedConfigurations["core.proxy.https"] = true
    47  	supportedConfigurations["core.proxy.ftp"] = true
    48  	supportedConfigurations["core.proxy.no-proxy"] = true
    49  	supportedConfigurations["core.proxy.store"] = true
    50  }
    51  
    52  func etcEnvironment() string {
    53  	return filepath.Join(dirs.GlobalRootDir, "/etc/environment")
    54  }
    55  
    56  func updateEtcEnvironmentConfig(path string, config map[string]string) error {
    57  	f, err := os.OpenFile(path, os.O_RDONLY|os.O_CREATE, 0644)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	defer f.Close()
    62  
    63  	toWrite, err := updateKeyValueStream(f, proxyConfigKeys, config)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	if toWrite != nil {
    68  		// XXX: would be great to atomically write but /etc/environment
    69  		//      is a single bind mount :/
    70  		return ioutil.WriteFile(path, []byte(strings.Join(toWrite, "\n")), 0644)
    71  	}
    72  
    73  	return nil
    74  }
    75  
    76  func handleProxyConfiguration(tr config.Conf, opts *fsOnlyContext) error {
    77  	config := map[string]string{}
    78  	// normal proxy settings
    79  	for _, key := range []string{"http", "https", "ftp"} {
    80  		output, err := coreCfg(tr, "proxy."+key)
    81  		if err != nil {
    82  			return err
    83  		}
    84  		config[key+"_proxy"] = output
    85  	}
    86  	// handle no_proxy
    87  	output, err := coreCfg(tr, "proxy.no-proxy")
    88  	if err != nil {
    89  		return err
    90  	}
    91  	config["no_proxy"] = output
    92  
    93  	if err := updateEtcEnvironmentConfig(etcEnvironment(), config); err != nil {
    94  		return err
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func validateProxyStore(tr config.Conf) error {
   101  	proxyStore, err := coreCfg(tr, "proxy.store")
   102  	if err != nil {
   103  		return err
   104  	}
   105  
   106  	if proxyStore == "" {
   107  		return nil
   108  	}
   109  
   110  	st := tr.State()
   111  	st.Lock()
   112  	defer st.Unlock()
   113  
   114  	store, err := assertstate.Store(st, proxyStore)
   115  	if asserts.IsNotFound(err) {
   116  		return fmt.Errorf("cannot set proxy.store to %q without a matching store assertion", proxyStore)
   117  	}
   118  	if err == nil && store.URL() == nil {
   119  		return fmt.Errorf("cannot set proxy.store to %q with a matching store assertion with url unset", proxyStore)
   120  	}
   121  	return err
   122  }