github.com/coreos/mantle@v0.13.0/platform/local/flight.go (about) 1 // Copyright 2015 CoreOS, Inc. 2 // Copyright 2018 Red Hat 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package local 17 18 import ( 19 "fmt" 20 "sync/atomic" 21 22 "github.com/coreos/go-omaha/omaha" 23 "github.com/vishvananda/netns" 24 25 "github.com/coreos/mantle/lang/destructor" 26 "github.com/coreos/mantle/network" 27 "github.com/coreos/mantle/network/ntp" 28 "github.com/coreos/mantle/platform" 29 "github.com/coreos/mantle/system/ns" 30 ) 31 32 const ( 33 listenPortBase = 30000 34 ) 35 36 type LocalFlight struct { 37 destructor.MultiDestructor 38 *platform.BaseFlight 39 Dnsmasq *Dnsmasq 40 SimpleEtcd *SimpleEtcd 41 NTPServer *ntp.Server 42 nshandle netns.NsHandle 43 listenPort int32 44 } 45 46 func NewLocalFlight(opts *platform.Options, platformName platform.Name) (*LocalFlight, error) { 47 nshandle, err := ns.Create() 48 if err != nil { 49 return nil, err 50 } 51 52 nsdialer := network.NewNsDialer(nshandle) 53 bf, err := platform.NewBaseFlightWithDialer(opts, platformName, "", nsdialer) 54 if err != nil { 55 nshandle.Close() 56 return nil, err 57 } 58 59 lf := &LocalFlight{ 60 BaseFlight: bf, 61 nshandle: nshandle, 62 listenPort: listenPortBase, 63 } 64 lf.AddDestructor(lf.BaseFlight) 65 lf.AddCloser(&lf.nshandle) 66 67 // dnsmasq and etcd must be launched in the new namespace 68 nsExit, err := ns.Enter(lf.nshandle) 69 if err != nil { 70 lf.Destroy() 71 return nil, err 72 } 73 defer nsExit() 74 75 lf.Dnsmasq, err = NewDnsmasq() 76 if err != nil { 77 lf.Destroy() 78 return nil, err 79 } 80 lf.AddDestructor(lf.Dnsmasq) 81 82 lf.SimpleEtcd, err = NewSimpleEtcd() 83 if err != nil { 84 lf.Destroy() 85 return nil, err 86 } 87 lf.AddDestructor(lf.SimpleEtcd) 88 89 lf.NTPServer, err = ntp.NewServer(":123") 90 if err != nil { 91 lf.Destroy() 92 return nil, err 93 } 94 lf.AddCloser(lf.NTPServer) 95 go lf.NTPServer.Serve() 96 97 return lf, nil 98 } 99 100 func (lf *LocalFlight) NewCluster(rconf *platform.RuntimeConfig) (*LocalCluster, error) { 101 lc := &LocalCluster{ 102 flight: lf, 103 } 104 105 var err error 106 lc.BaseCluster, err = platform.NewBaseCluster(lf.BaseFlight, rconf) 107 if err != nil { 108 lc.Destroy() 109 return nil, err 110 } 111 lc.AddDestructor(lc.BaseCluster) 112 113 // Omaha server must be launched in the new namespace 114 nsExit, err := ns.Enter(lf.nshandle) 115 if err != nil { 116 lc.Destroy() 117 return nil, err 118 } 119 defer nsExit() 120 121 omahaServer, err := omaha.NewTrivialServer(fmt.Sprintf(":%d", lf.newListenPort())) 122 if err != nil { 123 lc.Destroy() 124 return nil, err 125 } 126 lc.OmahaServer = OmahaWrapper{TrivialServer: omahaServer} 127 lc.AddDestructor(lc.OmahaServer) 128 go lc.OmahaServer.Serve() 129 130 // does not lf.AddCluster() since we are not the top-level object 131 132 return lc, nil 133 } 134 135 func (lf *LocalFlight) newListenPort() int { 136 return int(atomic.AddInt32(&lf.listenPort, 1)) 137 } 138 139 func (lf *LocalFlight) Destroy() { 140 lf.MultiDestructor.Destroy() 141 }