github.com/coreos/mantle@v0.13.0/platform/machine/azure/machine.go (about) 1 // Copyright 2018 CoreOS, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in campliance 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 azure 16 17 import ( 18 "fmt" 19 "os" 20 "path/filepath" 21 22 "golang.org/x/crypto/ssh" 23 24 "github.com/coreos/mantle/platform" 25 "github.com/coreos/mantle/platform/api/azure" 26 ) 27 28 type machine struct { 29 cluster *cluster 30 mach *azure.Machine 31 dir string 32 journal *platform.Journal 33 console []byte 34 } 35 36 func (am *machine) ID() string { 37 return am.mach.ID 38 } 39 40 func (am *machine) IP() string { 41 return am.mach.PublicIPAddress 42 } 43 44 func (am *machine) PrivateIP() string { 45 return am.mach.PrivateIPAddress 46 } 47 48 func (am *machine) RuntimeConf() platform.RuntimeConfig { 49 return am.cluster.RuntimeConf() 50 } 51 52 func (am *machine) ResourceGroup() string { 53 return am.cluster.ResourceGroup 54 } 55 56 func (am *machine) InterfaceName() string { 57 return am.mach.InterfaceName 58 } 59 60 func (am *machine) PublicIPName() string { 61 return am.mach.PublicIPName 62 } 63 64 func (am *machine) SSHClient() (*ssh.Client, error) { 65 return am.cluster.SSHClient(am.IP()) 66 } 67 68 func (am *machine) PasswordSSHClient(user string, password string) (*ssh.Client, error) { 69 return am.cluster.PasswordSSHClient(am.IP(), user, password) 70 } 71 72 func (am *machine) SSH(cmd string) ([]byte, []byte, error) { 73 return am.cluster.SSH(am, cmd) 74 } 75 76 func (am *machine) Reboot() error { 77 err := platform.RebootMachine(am, am.journal) 78 if err != nil { 79 return err 80 } 81 82 // Re-fetch the Public & Private IP address for the event that it's changed during the reboot 83 am.mach.PublicIPAddress, am.mach.PrivateIPAddress, err = am.cluster.flight.api.GetIPAddresses(am.InterfaceName(), am.PublicIPName(), am.ResourceGroup()) 84 if err != nil { 85 return fmt.Errorf("Fetching IP addresses: %v", err) 86 } 87 return nil 88 } 89 90 func (am *machine) Destroy() { 91 if err := am.saveConsole(); err != nil { 92 // log error, but do not fail to terminate instance 93 plog.Warningf("Saving console for instance %v: %v", am.ID(), err) 94 } 95 96 if err := am.cluster.flight.api.TerminateInstance(am.ID(), am.ResourceGroup()); err != nil { 97 plog.Errorf("terminating instance: %v", err) 98 } 99 100 if am.journal != nil { 101 am.journal.Destroy() 102 } 103 104 am.cluster.DelMach(am) 105 } 106 107 func (am *machine) ConsoleOutput() string { 108 return string(am.console) 109 } 110 111 func (am *machine) saveConsole() error { 112 var err error 113 am.console, err = am.cluster.flight.api.GetConsoleOutput(am.ID(), am.ResourceGroup(), am.cluster.StorageAccount) 114 if err != nil { 115 return err 116 } 117 118 path := filepath.Join(am.dir, "console.txt") 119 f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0666) 120 if err != nil { 121 return err 122 } 123 defer f.Close() 124 _, err = f.Write(am.console) 125 if err != nil { 126 return fmt.Errorf("failed writing console to file: %v", err) 127 } 128 129 return nil 130 } 131 132 func (am *machine) JournalOutput() string { 133 if am.journal == nil { 134 return "" 135 } 136 137 data, err := am.journal.Read() 138 if err != nil { 139 plog.Errorf("Reading journal for machine %v: %v", am.ID(), err) 140 } 141 return string(data) 142 }