github.com/coreos/mantle@v0.13.0/cmd/plume/containerlinux.go (about) 1 // Copyright 2016 CoreOS, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package main 16 17 import ( 18 "net/url" 19 "os" 20 "path" 21 "strings" 22 23 "github.com/spf13/pflag" 24 25 "github.com/coreos/mantle/lang/maps" 26 "github.com/coreos/mantle/sdk" 27 ) 28 29 var ( 30 specBoard string 31 specChannel string 32 specVersion string 33 gceBoards = []string{"amd64-usr"} 34 azureBoards = []string{"amd64-usr"} 35 awsBoards = []string{"amd64-usr"} 36 azureEnvironments = []azureEnvironmentSpec{ 37 azureEnvironmentSpec{ 38 SubscriptionName: "BizSpark", 39 AdditionalContainers: []string{"pre-publish"}, 40 }, 41 azureEnvironmentSpec{ 42 SubscriptionName: "BlackForest", 43 }, 44 azureEnvironmentSpec{ 45 SubscriptionName: "Mooncake", 46 }, 47 } 48 awsPartitions = []awsPartitionSpec{ 49 awsPartitionSpec{ 50 Name: "AWS", 51 Profile: "default", 52 Bucket: "coreos-prod-ami-import-us-west-2", 53 BucketRegion: "us-west-2", 54 LaunchPermissions: []string{ 55 "017021077683", // coreos-cl 56 }, 57 Regions: []string{ 58 "us-east-1", 59 "us-east-2", 60 "us-west-1", 61 "us-west-2", 62 "eu-west-1", 63 "eu-west-2", 64 "eu-west-3", 65 "eu-central-1", 66 "eu-north-1", 67 "ap-south-1", 68 "ap-southeast-1", 69 "ap-southeast-2", 70 "ap-northeast-1", 71 "ap-northeast-2", 72 "sa-east-1", 73 "ca-central-1", 74 }, 75 }, 76 awsPartitionSpec{ 77 Name: "AWS GovCloud", 78 Profile: "govcloud", 79 Bucket: "coreos-prod-ami-import-us-gov-west-1", 80 BucketRegion: "us-gov-west-1", 81 Regions: []string{ 82 "us-gov-west-1", 83 "us-gov-east-1", 84 }, 85 }, 86 awsPartitionSpec{ 87 Name: "AWS China", 88 Profile: "china", 89 Bucket: "coreos-prod-ami-import-cn-north-1", 90 BucketRegion: "cn-north-1", 91 Regions: []string{ 92 "cn-north-1", 93 "cn-northwest-1", 94 }, 95 }, 96 } 97 specs = map[string]channelSpec{ 98 "user": channelSpec{ 99 BaseURL: "gs://users.developer.core-os.net/" + os.Getenv("USER") + "/boards", 100 Boards: []string{"amd64-usr"}, 101 Destinations: []storageSpec{storageSpec{ 102 BaseURL: "gs://users.developer.core-os.net/" + os.Getenv("USER") + "/releases", 103 NamedPath: "current", 104 VersionPath: true, 105 DirectoryHTML: true, 106 IndexHTML: true, 107 }}, 108 GCE: gceSpec{ 109 Project: "coreos-gce-testing", 110 Family: "coreos-user", 111 Description: "CoreOS Container Linux development image", 112 Image: "coreos_production_gce.tar.gz", 113 Publish: "coreos_production_gce.txt", 114 Limit: 2, 115 }, 116 AWS: awsSpec{ 117 BaseName: "Container-Linux", 118 BaseDescription: "CoreOS Container Linux development image", 119 Prefix: "coreos_production_ami_", 120 Image: "coreos_production_ami_vmdk_image.vmdk.bz2", 121 Partitions: []awsPartitionSpec{ 122 awsPartitionSpec{ 123 Name: "AWS West", 124 Profile: "coreos-cl", 125 Bucket: "coreos-dev-ami-import-us-west-2", 126 BucketRegion: "us-west-2", 127 Regions: []string{ 128 "us-west-1", 129 "us-west-2", 130 "eu-west-3", // no PV 131 }, 132 }, 133 awsPartitionSpec{ 134 // partition with a single region 135 Name: "AWS East", 136 Profile: "coreos-cl", 137 Bucket: "coreos-dev-ami-import-us-east-1", 138 BucketRegion: "us-east-1", 139 LaunchPermissions: []string{ 140 "595879546273", // prod account, to test LaunchPermissions 141 }, 142 Regions: []string{ 143 "us-east-1", 144 }, 145 }, 146 }, 147 }, 148 }, 149 "developer": channelSpec{ 150 BaseURL: "gs://builds.developer.core-os.net/boards", 151 Boards: []string{"amd64-usr"}, 152 GCE: gceSpec{ 153 Project: "coreos-gce-testing", 154 Family: "coreos-developer", 155 Description: "CoreOS Container Linux development image", 156 Image: "coreos_production_gce.tar.gz", 157 Publish: "coreos_production_gce.txt", 158 Limit: 25, 159 }, 160 AWS: awsSpec{ 161 BaseName: "Container-Linux", 162 BaseDescription: "CoreOS Container Linux development image", 163 Prefix: "coreos_production_ami_", 164 Image: "coreos_production_ami_vmdk_image.vmdk.bz2", 165 Partitions: []awsPartitionSpec{ 166 awsPartitionSpec{ 167 Name: "AWS West", 168 Profile: "coreos-cl", 169 Bucket: "coreos-dev-ami-import-us-west-2", 170 BucketRegion: "us-west-2", 171 Regions: []string{ 172 "us-west-2", 173 }, 174 }, 175 }, 176 }, 177 }, 178 "alpha": channelSpec{ 179 BaseURL: "gs://builds.release.core-os.net/alpha/boards", 180 Boards: []string{"amd64-usr"}, 181 Destinations: []storageSpec{storageSpec{ 182 BaseURL: "gs://alpha.release.core-os.net", 183 NamedPath: "current", 184 VersionPath: true, 185 IndexHTML: true, 186 }, storageSpec{ 187 BaseURL: "gs://coreos-alpha", 188 Title: "alpha.release.core-os.net", 189 NamedPath: "current", 190 VersionPath: true, 191 DirectoryHTML: true, 192 IndexHTML: true, 193 }, storageSpec{ 194 BaseURL: "gs://storage.core-os.net/coreos", 195 NamedPath: "alpha", 196 VersionPath: true, 197 IndexHTML: true, 198 }, storageSpec{ 199 BaseURL: "gs://coreos-net-storage/coreos", 200 Title: "storage.core-os.net", 201 NamedPath: "alpha", 202 VersionPath: true, 203 DirectoryHTML: true, 204 IndexHTML: true, 205 }}, 206 GCE: gceSpec{ 207 Project: "coreos-cloud", 208 Family: "coreos-alpha", 209 Description: "CoreOS, CoreOS alpha", 210 Licenses: []string{"coreos-alpha"}, 211 Image: "coreos_production_gce.tar.gz", 212 Publish: "coreos_production_gce.txt", 213 Limit: 25, 214 }, 215 Azure: azureSpec{ 216 Offer: "CoreOS", 217 Image: "coreos_production_azure_image.vhd.bz2", 218 StorageAccount: "coreos", 219 Container: "publish", 220 Environments: azureEnvironments, 221 Label: "CoreOS Alpha", 222 Description: "The Alpha channel closely tracks current development work and is released frequently. The newest versions of the Linux kernel, systemd, and other components will be available for testing.", 223 RecommendedVMSize: "Medium", 224 IconURI: "coreos-globe-color-lg-100px.png", 225 SmallIconURI: "coreos-globe-color-lg-45px.png", 226 }, 227 AWS: awsSpec{ 228 BaseName: "CoreOS", 229 BaseDescription: "CoreOS Container Linux", 230 Prefix: "coreos_production_ami_", 231 Image: "coreos_production_ami_vmdk_image.vmdk.bz2", 232 Partitions: awsPartitions, 233 }, 234 }, 235 "beta": channelSpec{ 236 BaseURL: "gs://builds.release.core-os.net/beta/boards", 237 Boards: []string{"amd64-usr"}, 238 Destinations: []storageSpec{storageSpec{ 239 BaseURL: "gs://beta.release.core-os.net", 240 NamedPath: "current", 241 VersionPath: true, 242 IndexHTML: true, 243 }, storageSpec{ 244 BaseURL: "gs://coreos-beta", 245 Title: "beta.release.core-os.net", 246 NamedPath: "current", 247 VersionPath: true, 248 DirectoryHTML: true, 249 IndexHTML: true, 250 }, storageSpec{ 251 BaseURL: "gs://storage.core-os.net/coreos", 252 NamedPath: "beta", 253 IndexHTML: true, 254 }, storageSpec{ 255 BaseURL: "gs://coreos-net-storage/coreos", 256 Title: "storage.core-os.net", 257 NamedPath: "beta", 258 DirectoryHTML: true, 259 IndexHTML: true, 260 }}, 261 GCE: gceSpec{ 262 Project: "coreos-cloud", 263 Family: "coreos-beta", 264 Description: "CoreOS, CoreOS beta", 265 Licenses: []string{"coreos-beta"}, 266 Image: "coreos_production_gce.tar.gz", 267 Publish: "coreos_production_gce.txt", 268 Limit: 25, 269 }, 270 Azure: azureSpec{ 271 Offer: "CoreOS", 272 Image: "coreos_production_azure_image.vhd.bz2", 273 StorageAccount: "coreos", 274 Container: "publish", 275 Environments: azureEnvironments, 276 Label: "CoreOS Beta", 277 Description: "The Beta channel consists of promoted Alpha releases. Mix a few Beta machines into your production clusters to catch any bugs specific to your hardware or configuration.", 278 RecommendedVMSize: "Medium", 279 IconURI: "coreos-globe-color-lg-100px.png", 280 SmallIconURI: "coreos-globe-color-lg-45px.png", 281 }, 282 AWS: awsSpec{ 283 BaseName: "CoreOS", 284 BaseDescription: "CoreOS Container Linux", 285 Prefix: "coreos_production_ami_", 286 Image: "coreos_production_ami_vmdk_image.vmdk.bz2", 287 Partitions: awsPartitions, 288 }, 289 }, 290 "stable": channelSpec{ 291 BaseURL: "gs://builds.release.core-os.net/stable/boards", 292 Boards: []string{"amd64-usr"}, 293 Destinations: []storageSpec{storageSpec{ 294 BaseURL: "gs://stable.release.core-os.net", 295 NamedPath: "current", 296 VersionPath: true, 297 IndexHTML: true, 298 }, storageSpec{ 299 BaseURL: "gs://coreos-stable", 300 Title: "stable.release.core-os.net", 301 NamedPath: "current", 302 VersionPath: true, 303 DirectoryHTML: true, 304 IndexHTML: true, 305 }}, 306 GCE: gceSpec{ 307 Project: "coreos-cloud", 308 Family: "coreos-stable", 309 Description: "CoreOS, CoreOS stable", 310 Licenses: []string{"coreos-stable"}, 311 Image: "coreos_production_gce.tar.gz", 312 Publish: "coreos_production_gce.txt", 313 Limit: 25, 314 }, 315 Azure: azureSpec{ 316 Offer: "CoreOS", 317 Image: "coreos_production_azure_image.vhd.bz2", 318 StorageAccount: "coreos", 319 Container: "publish", 320 Environments: azureEnvironments, 321 Label: "CoreOS Stable", 322 Description: "The Stable channel should be used by production clusters. Versions of CoreOS are battle-tested within the Beta and Alpha channels before being promoted.", 323 RecommendedVMSize: "Medium", 324 IconURI: "coreos-globe-color-lg-100px.png", 325 SmallIconURI: "coreos-globe-color-lg-45px.png", 326 }, 327 AWS: awsSpec{ 328 BaseName: "CoreOS", 329 BaseDescription: "CoreOS Container Linux", 330 Prefix: "coreos_production_ami_", 331 Image: "coreos_production_ami_vmdk_image.vmdk.bz2", 332 Partitions: awsPartitions, 333 }, 334 }, 335 } 336 ) 337 338 func AddSpecFlags(flags *pflag.FlagSet) { 339 board := sdk.DefaultBoard() 340 channels := strings.Join(maps.SortedKeys(specs), " ") 341 versions, _ := sdk.VersionsFromManifest() 342 flags.StringVarP(&specBoard, "board", "B", 343 board, "target board") 344 flags.StringVarP(&specChannel, "channel", "C", 345 "user", "channels: "+channels) 346 flags.StringVarP(&specVersion, "version", "V", 347 versions.VersionID, "release version") 348 } 349 350 func ChannelSpec() channelSpec { 351 if specBoard == "" { 352 plog.Fatal("--board is required") 353 } 354 if specChannel == "" { 355 plog.Fatal("--channel is required") 356 } 357 if specVersion == "" { 358 plog.Fatal("--version is required") 359 } 360 361 spec, ok := specs[specChannel] 362 if !ok { 363 plog.Fatalf("Unknown channel: %s", specChannel) 364 } 365 366 boardOk := false 367 for _, board := range spec.Boards { 368 if specBoard == board { 369 boardOk = true 370 break 371 } 372 } 373 if !boardOk { 374 plog.Fatalf("Unknown board %q for channel %q", specBoard, specChannel) 375 } 376 377 gceOk := false 378 for _, board := range gceBoards { 379 if specBoard == board { 380 gceOk = true 381 break 382 } 383 } 384 if !gceOk { 385 spec.GCE = gceSpec{} 386 } 387 388 azureOk := false 389 for _, board := range azureBoards { 390 if specBoard == board { 391 azureOk = true 392 break 393 } 394 } 395 if !azureOk { 396 spec.Azure = azureSpec{} 397 } 398 399 awsOk := false 400 for _, board := range awsBoards { 401 if specBoard == board { 402 awsOk = true 403 break 404 } 405 } 406 if !awsOk { 407 spec.AWS = awsSpec{} 408 } 409 410 return spec 411 } 412 413 func (cs channelSpec) SourceURL() string { 414 u, err := url.Parse(cs.BaseURL) 415 if err != nil { 416 panic(err) 417 } 418 u.Path = path.Join(u.Path, specBoard, specVersion) 419 return u.String() 420 } 421 422 func (ss storageSpec) ParentPrefixes() []string { 423 u, err := url.Parse(ss.BaseURL) 424 if err != nil { 425 panic(err) 426 } 427 return []string{u.Path, path.Join(u.Path, specBoard)} 428 } 429 430 func (ss storageSpec) FinalPrefixes() []string { 431 u, err := url.Parse(ss.BaseURL) 432 if err != nil { 433 plog.Panic(err) 434 } 435 436 prefixes := []string{} 437 if ss.VersionPath { 438 prefixes = append(prefixes, 439 path.Join(u.Path, specBoard, specVersion)) 440 } 441 if ss.NamedPath != "" { 442 prefixes = append(prefixes, 443 path.Join(u.Path, specBoard, ss.NamedPath)) 444 } 445 if len(prefixes) == 0 { 446 plog.Panicf("Invalid destination: %#v", ss) 447 } 448 449 return prefixes 450 }