Merge pull request #833 from Zexi/feature/baremetal-http-ipxe

baremetal: support http download kernel and initramfs for pxe boot
This commit is contained in:
yunion-ci-robot
2019-05-16 14:02:35 +08:00
committed by GitHub
4 changed files with 51 additions and 12 deletions
+27 -10
View File
@@ -191,7 +191,7 @@ func (m *SBaremetalManager) GetBaremetalById(bmId string) *SBaremetalInstance {
}
func (m *SBaremetalManager) GetBaremetalByMac(mac net.HardwareAddr) pxe.IBaremetalInstance {
var obj *SBaremetalInstance
var obj pxe.IBaremetalInstance
getter := func(key, val interface{}) bool {
instance := val.(*SBaremetalInstance)
if instance.GetNicByMac(mac) != nil {
@@ -690,24 +690,41 @@ func (b *SBaremetalInstance) GetNotifyUrl() string {
return fmt.Sprintf("%s/baremetals/%s/notify", b.manager.Agent.GetManagerUri(), b.GetId())
}
func (b *SBaremetalInstance) getTftpFileUrl(filename string) string {
serverIP, err := b.manager.Agent.GetDHCPServerIP()
if err != nil {
log.Errorf("Get http file server: %v", err)
return filename
}
if o.Options.EnableTftpHttpDownload {
return fmt.Sprintf("http://%s:%d/tftp/%s", serverIP, o.Options.Port+1000, filename)
}
return filename
}
func (b *SBaremetalInstance) GetTFTPResponse() string {
resp := `default start
resp := `DEFAULT start
serial 1 115200
label start
menu label ^Start
menu default
LABEL start
MENU LABEL ^Start
MENU default
`
if b.NeedPXEBoot() {
resp += " kernel kernel\n"
resp += fmt.Sprintf(" append initrd=initramfs token=%s url=%s",
auth.GetTokenString(), b.GetNotifyUrl())
resp += fmt.Sprintf(" kernel %s\n", b.getTftpFileUrl("kernel"))
args := []string{
fmt.Sprintf("initrd=%s", b.getTftpFileUrl("initramfs")),
fmt.Sprintf("token=%s", auth.GetTokenString()),
fmt.Sprintf("url=%s", b.GetNotifyUrl()),
}
resp += fmt.Sprintf(" append %s\n", strings.Join(args, " "))
} else {
resp += " COM32 chain.c32\n"
resp += fmt.Sprintf(" COM32 %s\n", b.getTftpFileUrl("chain.c32"))
resp += " APPEND hd0 0\n"
b.ClearSSHConfig()
}
log.Infof("%s", resp)
log.Infof("[TFTP response]: \n%s", resp)
return resp
}
+5 -1
View File
@@ -76,7 +76,11 @@ func GetNicDHCPConfig(
case 6:
conf.BootFile = "bootia32.efi"
default:
conf.BootFile = "pxelinux.0"
bootFile := "pxelinux.0"
if o.Options.EnableTftpHttpDownload {
bootFile = "lpxelinux.0"
}
conf.BootFile = bootFile
}
pxePath := filepath.Join(o.Options.TftpRoot, conf.BootFile)
if f, err := os.Open(pxePath); err != nil {
+2 -1
View File
@@ -22,7 +22,7 @@ type BaremetalOptions struct {
ListenInterface string `help:"Master net interface of baremetal server" default:"br0"`
AccessAddress string `help:"Management IP address of baremetal server, only need to use when multiple address bind to ListenInterface"`
ListenAddress string `help:"PXE serve IP address to select when multiple address bind to ListenInterface" default:"0.0.0.0"`
TftpRoot string `help:"tftp root directory"`
TftpRoot string `default:"/opt/cloud/yunion/baremetal" help:"tftp root directory"`
AutoRegisterBaremetal bool `default:"true" help:"Automatically create a baremetal instance"`
BaremetalsPath string `default:"/opt/cloud/workspace/baremetals" help:"Path for baremetals configuration files"`
LinuxDefaultRootUser bool `default:"false" help:"Default account for linux system is root"`
@@ -41,6 +41,7 @@ type BaremetalOptions struct {
DefaultStrongIpmiPassword string `help:"Default strong IPMI passowrd"`
WindowsDefaultAdminUser bool `default:"true" help:"Default account for Windows system is Administrator"`
EnableTftpHttpDownload bool `default:"true" help:"Pxelinux download file through http"`
}
var (
+17
View File
@@ -15,6 +15,8 @@
package service
import (
"fmt"
"net/http"
"os"
"yunion.io/x/log"
@@ -43,12 +45,27 @@ func (s *BaremetalService) StartService() {
app := app_common.InitApp(&o.Options.CommonOptions, false)
handler.InitHandlers(app)
s.startFileServer()
app_common.ServeForeverWithCleanup(app, &o.Options.CommonOptions, func() {
tasks.OnStop()
baremetal.Stop()
})
}
func (s *BaremetalService) startFileServer() {
if !o.Options.EnableTftpHttpDownload {
return
}
fs := http.FileServer(http.Dir(o.Options.TftpRoot))
http.Handle("/tftp/", http.StripPrefix("/tftp/", fs))
go func() {
if err := http.ListenAndServe(fmt.Sprintf("%s:%d", o.Options.Address, o.Options.Port+1000), nil); err != nil {
panic(fmt.Sprintf("start http file server: %v", err))
}
}()
}
func (s *BaremetalService) startAgent() {
err := baremetal.Start()
if err != nil {