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 ¢OSCloudConfig{ 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 )