github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cloudconfig/containerinit/container_userdata.go (about)

     1  // Copyright 2013, 2015 Canonical Ltd.
     2  // Copyright 2015 Cloudbase Solutions SRL
     3  // Licensed under the AGPLv3, see LICENCE file for details.
     4  
     5  package containerinit
     6  
     7  import (
     8  	"io/ioutil"
     9  	"path/filepath"
    10  
    11  	"github.com/juju/errors"
    12  	"github.com/juju/loggo"
    13  
    14  	"github.com/juju/juju/cloudconfig"
    15  	"github.com/juju/juju/cloudconfig/cloudinit"
    16  	"github.com/juju/juju/cloudconfig/instancecfg"
    17  	"github.com/juju/juju/container"
    18  	"github.com/juju/juju/network"
    19  )
    20  
    21  var (
    22  	logger = loggo.GetLogger("juju.cloudconfig.containerinit")
    23  )
    24  
    25  // WriteUserData generates the cloud-init user-data using the
    26  // specified machine and network config for a container, and writes
    27  // the serialized form out to a cloud-init file in the directory
    28  // specified.
    29  func WriteUserData(
    30  	instanceConfig *instancecfg.InstanceConfig,
    31  	networkConfig *container.NetworkConfig,
    32  	directory string,
    33  ) (string, error) {
    34  	userData, err := CloudInitUserData(instanceConfig, networkConfig)
    35  	if err != nil {
    36  		logger.Errorf("failed to create user data: %v", err)
    37  		return "", err
    38  	}
    39  	return WriteCloudInitFile(directory, userData)
    40  }
    41  
    42  // WriteCloudInitFile writes the data out to a cloud-init file in the
    43  // directory specified, and returns the filename.
    44  func WriteCloudInitFile(directory string, userData []byte) (string, error) {
    45  	userDataFilename := filepath.Join(directory, "cloud-init")
    46  	if err := ioutil.WriteFile(userDataFilename, userData, 0644); err != nil {
    47  		logger.Errorf("failed to write user data: %v", err)
    48  		return "", err
    49  	}
    50  	return userDataFilename, nil
    51  }
    52  
    53  func CloudInitUserData(
    54  	instanceConfig *instancecfg.InstanceConfig,
    55  	networkConfig *container.NetworkConfig,
    56  ) ([]byte, error) {
    57  	cloudConfig, err := cloudinit.New(instanceConfig.Series)
    58  	if err != nil {
    59  		return nil, errors.Trace(err)
    60  	}
    61  	var interfaces []network.InterfaceInfo
    62  	if networkConfig != nil {
    63  		interfaces = networkConfig.Interfaces
    64  	}
    65  	err = cloudConfig.AddNetworkConfig(interfaces)
    66  	if err != nil {
    67  		return nil, errors.Trace(err)
    68  	}
    69  	udata, err := cloudconfig.NewUserdataConfig(instanceConfig, cloudConfig)
    70  	if err != nil {
    71  		return nil, errors.Trace(err)
    72  	}
    73  	if err = udata.Configure(); err != nil {
    74  		return nil, errors.Trace(err)
    75  	}
    76  	// Run ifconfig to get the addresses of the internal container at least
    77  	// logged in the host.
    78  	cloudConfig.AddRunCmd("ifconfig")
    79  
    80  	if instanceConfig.MachineContainerHostname != "" {
    81  		logger.Debugf("Cloud-init configured to set hostname")
    82  		cloudConfig.SetAttr("hostname", instanceConfig.MachineContainerHostname)
    83  	}
    84  
    85  	data, err := cloudConfig.RenderYAML()
    86  	if err != nil {
    87  		return nil, errors.Trace(err)
    88  	}
    89  	return data, nil
    90  }