github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cloudconfig/cloudinit/interface.go (about)

     1  // Copyright 2011, 2013, 2015 Canonical Ltd.
     2  // Copyright 2015 Cloudbase Solutions SRL
     3  // Licensed under the AGPLv3, see LICENCE file for details.
     4  
     5  // The cloudinit package implements a way of creating
     6  // a cloud-init configuration file.
     7  // See https://help.ubuntu.com/community/CloudInit.
     8  package cloudinit
     9  
    10  import (
    11  	"github.com/juju/errors"
    12  	"github.com/juju/utils/os"
    13  	"github.com/juju/utils/packaging"
    14  	"github.com/juju/utils/packaging/commands"
    15  	"github.com/juju/utils/packaging/config"
    16  	"github.com/juju/utils/proxy"
    17  	"github.com/juju/utils/series"
    18  	"github.com/juju/utils/shell"
    19  )
    20  
    21  // CloudConfig is the interface of all cloud-init cloudconfig options.
    22  type CloudConfig interface {
    23  	// SetAttr sets an arbitrary attribute in the cloudinit config.
    24  	// The value will be marshalled according to the rules
    25  	// of the goyaml.Marshal.
    26  	SetAttr(string, interface{})
    27  
    28  	// UnsetAttr unsets the attribute given from the cloudinit config.
    29  	// If the attribute has not been previously set, no error occurs.
    30  	UnsetAttr(string)
    31  
    32  	// GetSeries returns the series this CloudConfig was made for.
    33  	GetSeries() string
    34  
    35  	// CloudConfig also contains all the smaller interfaces for config
    36  	// management:
    37  	UsersConfig
    38  	SystemUpdateConfig
    39  	SystemUpgradeConfig
    40  	PackageProxyConfig
    41  	PackageMirrorConfig
    42  	PackageSourcesConfig
    43  	PackagingConfig
    44  	RunCmdsConfig
    45  	BootCmdsConfig
    46  	EC2MetadataConfig
    47  	FinalMessageConfig
    48  	LocaleConfig
    49  	DeviceMountConfig
    50  	OutputConfig
    51  	SSHAuthorizedKeysConfig
    52  	RootUserConfig
    53  	WrittenFilesConfig
    54  	RenderConfig
    55  	AdvancedPackagingConfig
    56  }
    57  
    58  // SystemUpdateConfig is the interface for managing all system update options.
    59  type SystemUpdateConfig interface {
    60  	// SetSystemUpdate sets whether the system should refresh the local package
    61  	// database on first boot.
    62  	// NOTE: This option is active in cloudinit by default and must be
    63  	// explicitly set to false if it is not desired.
    64  	SetSystemUpdate(bool)
    65  
    66  	// UnsetSystemUpdate unsets the package list updating option set by
    67  	// SetSystemUpdate, returning it to the cloudinit *default of true*.
    68  	// If the option has not previously been set, no error occurs.
    69  	UnsetSystemUpdate()
    70  
    71  	// SystemUpdate returns the value set with SetSystemUpdate or false
    72  	// NOTE: even though not set, the cloudinit-defined default is true.
    73  	SystemUpdate() bool
    74  }
    75  
    76  // SystemUpgradeConfig is the interface for managing all system upgrade settings.
    77  type SystemUpgradeConfig interface {
    78  	// SetSystemUpgrade sets whether cloud-init should run the process of upgrading
    79  	// all the packages with available newer versions on the machine's *first* boot.
    80  	SetSystemUpgrade(bool)
    81  
    82  	// UnsetSystemUpgrade unsets the value set by SetSystemUpgrade.
    83  	// If the option has not previously been set, no error occurs.
    84  	UnsetSystemUpgrade()
    85  
    86  	// SystemUpgrade returns the value set by SetSystemUpgrade or
    87  	// false if no call to SetSystemUpgrade has been made.
    88  	SystemUpgrade() bool
    89  }
    90  
    91  // PackageProxyConfig is the interface for packaging proxy settings on a cloudconfig
    92  type PackageProxyConfig interface {
    93  	// SetPackageProxy sets the URL to be used as a proxy by the
    94  	// specific package manager
    95  	SetPackageProxy(string)
    96  
    97  	// UnsetPackageProxy unsets the option set by SetPackageProxy
    98  	// If it has not been previously set, no error occurs
    99  	UnsetPackageProxy()
   100  
   101  	// PackageProxy returns the URL of the proxy server set using
   102  	// SetPackageProxy or an empty string if it has not been set
   103  	PackageProxy() string
   104  }
   105  
   106  // PackageMirrorConfig is the interface for package mirror settings on a cloudconfig.
   107  type PackageMirrorConfig interface {
   108  	// SetPackageMirror sets the URL to be used as the mirror for
   109  	// pulling packages by the system's specific package manager.
   110  	SetPackageMirror(string)
   111  
   112  	// UnsetPackageMirror unsets the value set by SetPackageMirror
   113  	// If it has not been previously set, no error occurs.
   114  	UnsetPackageMirror()
   115  
   116  	// PackageMirror returns the URL of the package mirror set by
   117  	// SetPackageMirror or an empty string if not previously set.
   118  	PackageMirror() string
   119  }
   120  
   121  // PackageSourceConfig is the interface for package source settings on a cloudconfig.
   122  type PackageSourcesConfig interface {
   123  	// AddPackageSource adds a new repository and optional key to be
   124  	// used as a package source by the system's specific package manager.
   125  	AddPackageSource(packaging.PackageSource)
   126  
   127  	// PackageSources returns all sources set with AddPackageSource.
   128  	PackageSources() []packaging.PackageSource
   129  
   130  	// AddPackagePreferences adds the necessary options and/or bootcmds to
   131  	// enable the given packaging.PackagePreferences.
   132  	AddPackagePreferences(packaging.PackagePreferences)
   133  
   134  	// PackagePreferences returns the previously-added PackagePreferences.
   135  	PackagePreferences() []packaging.PackagePreferences
   136  }
   137  
   138  // PackagingConfig is the interface for all packaging-related operations.
   139  type PackagingConfig interface {
   140  	// AddPackage adds a package to be installed on *first* boot.
   141  	AddPackage(string)
   142  
   143  	// RemovePackage removes a package from the list of to be installed packages
   144  	// If the package has not been previously installed, no error occurs.
   145  	RemovePackage(string)
   146  
   147  	// Packages returns a list of all packages that will be installed.
   148  	Packages() []string
   149  }
   150  
   151  // RunCmdsConfig is the interface for all operations on first-boot commands.
   152  type RunCmdsConfig interface {
   153  	// AddRunCmd adds a command to be executed on *first* boot.
   154  	// It can recieve any number of string arguments, which will be joined into
   155  	// a single command and passed to cloudinit to be executed.
   156  	// NOTE: metacharacters will *not* be escaped!
   157  	AddRunCmd(...string)
   158  
   159  	// AddScripts simply calls AddRunCmd on every string passed to it.
   160  	// NOTE: this means that each given string must be a full command plus
   161  	// all of its arguments.
   162  	// NOTE: metacharacters will not be escaped.
   163  	AddScripts(...string)
   164  
   165  	// RemoveRunCmd removes the given command from the list of commands to be
   166  	// run on first boot. If it has not been previously added, no error occurs.
   167  	RemoveRunCmd(string)
   168  
   169  	// RunCmds returns all the commands added with AddRunCmd or AddScript.
   170  	RunCmds() []string
   171  }
   172  
   173  // BootCmdsConfig is the interface for all operations on early-boot commands.
   174  type BootCmdsConfig interface {
   175  	// AddBootCmd adds a command to be executed on *every* boot.
   176  	// It can recieve any number of string arguments, which will be joined into
   177  	// a single command.
   178  	// NOTE: metacharecters will not be escaped.
   179  	AddBootCmd(...string)
   180  
   181  	// RemoveBootCmd removes the given command from the list of commands to be
   182  	// run every boot. If it has not been previously added, no error occurs.
   183  	RemoveBootCmd(string)
   184  
   185  	// BootCmds returns all the commands added with AddBootCmd.
   186  	BootCmds() []string
   187  }
   188  
   189  // EC2MetadataConfig is the interface for all EC2-metadata related settings.
   190  type EC2MetadataConfig interface {
   191  	// SetDisableEC2Metadata sets whether access to the EC2 metadata service is
   192  	// disabled early in boot via a null route. The default value is false.
   193  	// (route del -host 169.254.169.254 reject).
   194  	SetDisableEC2Metadata(bool)
   195  
   196  	// UnsetDisableEC2Metadata unsets the value set by SetDisableEC2Metadata,
   197  	// returning it to the cloudinit-defined value of false.
   198  	// If the option has not been previously set, no error occurs.
   199  	UnsetDisableEC2Metadata()
   200  
   201  	// DisableEC2Metadata returns the value set by SetDisableEC2Metadata or
   202  	// false if it has not been previously set.
   203  	DisableEC2Metadata() bool
   204  }
   205  
   206  // FinalMessageConfig is the interface for all settings related to the
   207  // cloudinit final message.
   208  type FinalMessageConfig interface {
   209  	// SetFinalMessage sets to message that will be written when the system has
   210  	// finished booting for the first time. By default, the message is:
   211  	// "cloud-init boot finished at $TIMESTAMP. Up $UPTIME seconds".
   212  	SetFinalMessage(string)
   213  
   214  	// UnsetFinalMessage unsets the value set by SetFinalMessage.
   215  	// If it has not been previously set, no error occurs.
   216  	UnsetFinalMessage()
   217  
   218  	// FinalMessage returns the value set using SetFinalMessage or an empty
   219  	// string if it has not previously been set.
   220  	FinalMessage() string
   221  }
   222  
   223  // LocaleConfig is the interface for all locale-related setting operations.
   224  type LocaleConfig interface {
   225  	// SetLocale sets the locale; it defaults to en_US.UTF-8
   226  	SetLocale(string)
   227  
   228  	// UnsetLocale unsets the option set by SetLocale, returning it to the
   229  	// cloudinit-defined default of en_US.UTF-8
   230  	// If it has not been previously set, no error occurs
   231  	UnsetLocale()
   232  
   233  	// Locale returns the locale set with SetLocale
   234  	// If it has not been previously set, an empty string is returned
   235  	Locale() string
   236  }
   237  
   238  // DeviceMountConfig is the interface for all device mounting settings.
   239  type DeviceMountConfig interface {
   240  	// AddMount adds takes arguments for installing a mount point in /etc/fstab
   241  	// The options are of the order and format specific to fstab entries:
   242  	// <device> <mountpoint> <filesystem> <options> <backup setting> <fsck priority>
   243  	AddMount(...string)
   244  }
   245  
   246  // OutputConfig is the interface for all stdout and stderr setting options.
   247  type OutputConfig interface {
   248  	// SetOutput specifies the destinations of standard output and standard error of
   249  	// particular kinds of an output stream.
   250  	// Valid values include:
   251  	//	- init:		the output of cloudinit itself
   252  	//	- config:	cloud-config caused output
   253  	//	- final:	the final output of cloudinit (plus that set with SetFinalMessage)
   254  	//	- all:		all of the above
   255  	// Both stdout and stderr can take the following forms:
   256  	//	- > file:	write to given file. Will truncate of file exists
   257  	//	- >>file:	append to given file
   258  	//	- | command:	pipe output to given command
   259  	SetOutput(OutputKind, string, string)
   260  
   261  	// Output returns the destination set by SetOutput for the given OutputKind.
   262  	// If it has not been previously set, empty strings are returned.
   263  	Output(OutputKind) (string, string)
   264  }
   265  
   266  // SSHAuthorizedKeysConfig is the interface for adding ssh authorized keys.
   267  type SSHAuthorizedKeysConfig interface {
   268  	// SetSSHAuthorizedKeys puts a set of authorized keys for the default
   269  	// user in the ~/.ssh/authorized_keys file.
   270  	SetSSHAuthorizedKeys(string)
   271  }
   272  
   273  // RootUserConfig is the interface for all root user-related settings.
   274  type RootUserConfig interface {
   275  	// SetDisableRoot sets whether ssh login to the root account of the new server
   276  	// through the ssh authorized key provided with the config should be disabled.
   277  	// This option is set to true (ie. disabled) by default.
   278  	SetDisableRoot(bool)
   279  
   280  	// UnsetDisable unsets the value set with SetDisableRoot, returning it to the
   281  	// cloudinit-defined default of true.
   282  	UnsetDisableRoot()
   283  
   284  	// DisableRoot returns the value set by SetDisableRoot or false if the
   285  	// option had not been previously set.
   286  	DisableRoot() bool
   287  }
   288  
   289  // WrittenFilesConfig is the interface for all file writing operaions.
   290  type WrittenFilesConfig interface {
   291  	// AddRunTextFile simply issues some AddRunCmd's to set the contents of a
   292  	// given file with the specified file permissions on *first* boot.
   293  	// NOTE: if the file already exists, it will be truncated.
   294  	AddRunTextFile(string, string, uint)
   295  
   296  	// AddBootTextFile simply issues some AddBootCmd's to set the contents of a
   297  	// given file with the specified file permissions on *every* boot.
   298  	// NOTE: if the file already exists, it will be truncated.
   299  	AddBootTextFile(string, string, uint)
   300  
   301  	// AddRunBinaryFile simply issues some AddRunCmd's to set the binary contents
   302  	// of a given file with the specified file permissions on *first* boot.
   303  	// NOTE: if the file already exists, it will be truncated.
   304  	AddRunBinaryFile(string, []byte, uint)
   305  }
   306  
   307  // RenderConfig provides various ways to render a CloudConfig.
   308  type RenderConfig interface {
   309  	// Renders the current cloud config as valid YAML
   310  	RenderYAML() ([]byte, error)
   311  
   312  	// Renders a script that will execute the cloud config
   313  	// It is used over ssh for bootstrapping with the manual provider.
   314  	RenderScript() (string, error)
   315  
   316  	// ShellRenderer renturns the shell renderer of this particular instance.
   317  	ShellRenderer() shell.Renderer
   318  
   319  	// getCommandsForAddingPackages is a helper function which returns all the
   320  	// necessary shell commands for adding all the configured package settings.
   321  	getCommandsForAddingPackages() ([]string, error)
   322  }
   323  
   324  // Makes two more advanced package commands available
   325  type AdvancedPackagingConfig interface {
   326  	// Adds the necessary commands for installing the required packages for
   327  	// each OS is they are necessary.
   328  	AddPackageCommands(
   329  		aptProxySettings proxy.Settings,
   330  		aptMirror string,
   331  		addUpdateScripts bool,
   332  		addUpgradeScripts bool,
   333  	)
   334  
   335  	// getPackageCommander returns the PackageCommander of the CloudConfig.
   336  	getPackageCommander() commands.PackageCommander
   337  
   338  	// getPackagingConfigurer returns the PackagingConfigurer of the CloudConfig.
   339  	getPackagingConfigurer() config.PackagingConfigurer
   340  
   341  	// addRequiredPackages is a helper to add packages that juju requires in
   342  	// order to operate.
   343  	addRequiredPackages()
   344  
   345  	//TODO(bogdanteleaga): this might be the same as the exported proxy setting up above, need
   346  	//to investigate how they're used
   347  	updateProxySettings(proxy.Settings)
   348  
   349  	// RequiresCloudArchiveCloudTools determines whether the cloudconfig
   350  	// requires the configuration of the cloud archive depending on its series.
   351  	RequiresCloudArchiveCloudTools() bool
   352  
   353  	// AddCloudArchiveCloudTools configures the cloudconfig to set up the cloud
   354  	// archive if it is required (eg: LTS'es).
   355  	AddCloudArchiveCloudTools()
   356  }
   357  
   358  type User struct {
   359  	// Login name for the user.
   360  	Name string
   361  
   362  	// Additional groups to add the user to.
   363  	Groups []string
   364  
   365  	// Path to shell to use by default.
   366  	Shell string
   367  
   368  	// SSH keys to add to the authorized keys file.
   369  	SSHAuthorizedKeys string
   370  
   371  	// Sudo directives to add.
   372  	Sudo []string
   373  }
   374  
   375  // UsersConfig is the interface for managing user additions
   376  type UsersConfig interface {
   377  	// AddUser sets a new user to be created with the given configuration.
   378  	AddUser(*User)
   379  
   380  	// UnsetUsers unsets any users set in the config, meaning the default
   381  	// user specified in the image cloud config will be used.
   382  	UnsetUsers()
   383  }
   384  
   385  // New returns a new Config with no options set.
   386  func New(ser string) (CloudConfig, error) {
   387  	seriesos, err := series.GetOSFromSeries(ser)
   388  	if err != nil {
   389  		return nil, err
   390  	}
   391  	switch seriesos {
   392  	case os.Windows:
   393  		renderer, _ := shell.NewRenderer("powershell")
   394  		return &windowsCloudConfig{
   395  			&cloudConfig{
   396  				series:   ser,
   397  				renderer: renderer,
   398  				attrs:    make(map[string]interface{}),
   399  			},
   400  		}, nil
   401  	case os.Ubuntu:
   402  		renderer, _ := shell.NewRenderer("bash")
   403  		return &ubuntuCloudConfig{
   404  			&cloudConfig{
   405  				series:    ser,
   406  				paccmder:  commands.NewAptPackageCommander(),
   407  				pacconfer: config.NewAptPackagingConfigurer(ser),
   408  				renderer:  renderer,
   409  				attrs:     make(map[string]interface{}),
   410  			},
   411  		}, nil
   412  	case os.CentOS:
   413  		renderer, _ := shell.NewRenderer("bash")
   414  		return &centOSCloudConfig{
   415  			&cloudConfig{
   416  				series:    ser,
   417  				paccmder:  commands.NewYumPackageCommander(),
   418  				pacconfer: config.NewYumPackagingConfigurer(ser),
   419  				renderer:  renderer,
   420  				attrs:     make(map[string]interface{}),
   421  			},
   422  		}, nil
   423  	default:
   424  		return nil, errors.NotFoundf("cloudconfig for series %q", ser)
   425  	}
   426  }
   427  
   428  // SSHKeyType is the type of the four used key types passed to cloudinit
   429  // through the cloudconfig
   430  type SSHKeyType string
   431  
   432  // The constant SSH key types sent to cloudinit through the cloudconfig
   433  const (
   434  	RSAPrivate SSHKeyType = "rsa_private"
   435  	RSAPublic  SSHKeyType = "rsa_public"
   436  	DSAPrivate SSHKeyType = "dsa_private"
   437  	DSAPublic  SSHKeyType = "dsa_public"
   438  )
   439  
   440  // OutputKind represents the available destinations for command output as sent
   441  // through the cloudnit cloudconfig
   442  type OutputKind string
   443  
   444  // The constant output redirection options available to be passed to cloudinit
   445  const (
   446  	// the output of cloudinit iself
   447  	OutInit OutputKind = "init"
   448  	// cloud-config caused output
   449  	OutConfig OutputKind = "config"
   450  	// the final output of cloudinit
   451  	OutFinal OutputKind = "final"
   452  	// all of the above
   453  	OutAll OutputKind = "all"
   454  )