github.com/coreos/mantle@v0.13.0/platform/machine/do/cluster.go (about) 1 // Copyright 2017 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 do 16 17 import ( 18 "context" 19 "crypto/rand" 20 "fmt" 21 "os" 22 "path/filepath" 23 24 "github.com/coreos/mantle/platform" 25 "github.com/coreos/mantle/platform/conf" 26 ) 27 28 type cluster struct { 29 *platform.BaseCluster 30 flight *flight 31 sshKeyID int 32 } 33 34 func (dc *cluster) NewMachine(userdata *conf.UserData) (platform.Machine, error) { 35 conf, err := dc.RenderUserData(userdata, map[string]string{ 36 "$public_ipv4": "${COREOS_DIGITALOCEAN_IPV4_PUBLIC_0}", 37 "$private_ipv4": "${COREOS_DIGITALOCEAN_IPV4_PRIVATE_0}", 38 }) 39 if err != nil { 40 return nil, err 41 } 42 43 droplet, err := dc.flight.api.CreateDroplet(context.TODO(), dc.vmname(), dc.sshKeyID, conf.String()) 44 if err != nil { 45 return nil, err 46 } 47 48 mach := &machine{ 49 cluster: dc, 50 droplet: droplet, 51 } 52 mach.publicIP, err = droplet.PublicIPv4() 53 if mach.publicIP == "" || err != nil { 54 mach.Destroy() 55 return nil, fmt.Errorf("couldn't get public IP address for droplet: %v", err) 56 } 57 mach.privateIP, err = droplet.PrivateIPv4() 58 if mach.privateIP == "" || err != nil { 59 mach.Destroy() 60 return nil, fmt.Errorf("couldn't get private IP address for droplet: %v", err) 61 } 62 63 dir := filepath.Join(dc.RuntimeConf().OutputDir, mach.ID()) 64 if err := os.Mkdir(dir, 0777); err != nil { 65 mach.Destroy() 66 return nil, err 67 } 68 69 confPath := filepath.Join(dir, "user-data") 70 if err := conf.WriteFile(confPath); err != nil { 71 mach.Destroy() 72 return nil, err 73 } 74 75 if mach.journal, err = platform.NewJournal(dir); err != nil { 76 mach.Destroy() 77 return nil, err 78 } 79 80 if err := platform.StartMachine(mach, mach.journal); err != nil { 81 mach.Destroy() 82 return nil, err 83 } 84 85 dc.AddMach(mach) 86 87 return mach, nil 88 } 89 90 func (dc *cluster) vmname() string { 91 b := make([]byte, 5) 92 rand.Read(b) 93 return fmt.Sprintf("%s-%x", dc.Name()[0:13], b) 94 } 95 96 func (dc *cluster) Destroy() { 97 dc.BaseCluster.Destroy() 98 dc.flight.DelCluster(dc) 99 }