add host metadat, radix minor fix

This commit is contained in:
wanyaoqi
2019-02-27 12:11:14 +08:00
parent 40dbc8d478
commit 39c0ac797b
6 changed files with 269 additions and 6 deletions
+4 -1
View File
@@ -388,7 +388,10 @@ func (app *Application) ListenAndServeWithCleanup(addr string, onStop func()) {
func (app *Application) ListenAndServeTLSWithCleanup(addr string, certFile, keyFile string, onStop func()) {
s := app.initServer(addr)
app.registerCleanShutdown(s, onStop)
if onStop != nil {
app.registerCleanShutdown(s, onStop)
}
var err error
if len(certFile) == 0 && len(keyFile) == 0 {
err = s.ListenAndServe()
+4 -1
View File
@@ -33,7 +33,10 @@ func isRegexSegment(seg string) bool {
func (r *RadixNode) Add(segments []string, data interface{}) error {
err := r.add(segments, data, 1, nil)
return fmt.Errorf("Add Node error: %s %s", err, strings.Join(segments, "/"))
if err != nil {
return fmt.Errorf("Add Node error: %s %s", err, strings.Join(segments, "/"))
}
return nil
}
func (r *RadixNode) add(segments []string, data interface{}, depth int, segNames map[int]string) error {
+1 -1
View File
@@ -11,7 +11,7 @@ import (
func doStatsHandler(stats *jsonutils.JSONArray, method, path string, hi, total *SHandlerInfo) {
s := jsonutils.NewDict()
s.Add(jsonutils.NewString(method), "method")
s.Add(jsonutils.NewString("/"+path), "path")
s.Add(jsonutils.NewString(path), "path")
s.Add(jsonutils.NewString(hi.GetName(nil)), "name")
s.Add(jsonutils.NewInt(hi.counter2XX.hit), "hit.2XX")
s.Add(jsonutils.NewFloat(hi.counter2XX.duration), "duration.2XX")
-3
View File
@@ -6,7 +6,6 @@ import (
"net/http"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/onecloud/pkg/appsrv"
@@ -175,13 +174,11 @@ func diskDelete(ctx context.Context, storage storageman.IStorage, diskId string,
}
func diskResize(ctx context.Context, storage storageman.IStorage, diskId string, disk storageman.IDisk, body jsonutils.JSONObject) (interface{}, error) {
log.Errorln(body.String())
diskInfo, err := body.Get("disk")
if err != nil {
return nil, httperrors.NewMissingParameterError("disk")
}
serverId, _ := diskInfo.GetString("server_id")
log.Errorln(serverId, guestman.GetGuestManager().Status(serverId))
if len(serverId) > 0 && guestman.GetGuestManager().Status(serverId) == "running" {
sizeMb, _ := diskInfo.Int("size")
return guestman.GetGuestManager().OnlineResizeDisk(ctx, serverId, diskId, sizeMb)
+6
View File
@@ -16,6 +16,7 @@ import (
"yunion.io/x/onecloud/pkg/hostman/hostinfo"
"yunion.io/x/onecloud/pkg/hostman/hostmetrics"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/hostman/metadata"
"yunion.io/x/onecloud/pkg/hostman/options"
"yunion.io/x/onecloud/pkg/hostman/storageman"
)
@@ -53,6 +54,11 @@ func (host *SHostService) StartService() {
host.initHandlers(app)
<-hostinfo.Instance().IsRegistered // wait host and guest init
// Init Metadata handler
go metadata.StartService(
cloudcommon.InitApp(&options.HostOptions.CommonOptions, false),
options.HostOptions.Address, options.HostOptions.Port+1000)
cronManager := cronman.GetCronJobManager(false)
cronManager.AddJob2(
"CleanRecycleDiskFiles", 1, 3, 0, 0, storageman.CleanRecycleDiskfiles, false)
+254
View File
@@ -0,0 +1,254 @@
package metadata
import (
"context"
"encoding/base64"
"fmt"
"net"
"net/http"
"strconv"
"strings"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/hostman/guestman"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/pkg/util/netutils"
)
func addMetadataHandler(prefix string, app *appsrv.Application) {
for _, method := range []string{"GET", "HEAD"} {
app.AddHandler(method, fmt.Sprintf("%s/<version:%s>",
prefix, `(latest|\d{4}-\d{2}-\d{2})`), versionOnly)
}
for _, method := range []string{"GET", "HEAD"} {
app.AddHandler(method, fmt.Sprintf("%s/<version:%s>/user-data",
prefix, `(latest|\d{4}-\d{2}-\d{2})`), userData)
app.AddHandler(method, fmt.Sprintf("%s/<version:%s>/meta-data",
prefix, `(latest|\d{4}-\d{2}-\d{2})`), metaData)
}
}
func versionOnly(ctx context.Context, w http.ResponseWriter, r *http.Request) {
hostutils.Response(ctx, w, strings.Join([]string{"meta-data", "user-data"}, "\n"))
}
func userData(ctx context.Context, w http.ResponseWriter, r *http.Request) {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
hostutils.Response(ctx, w, httperrors.NewBadRequestError("Parse Remoteaddr %s error %s", r.RemoteAddr, err.Error()))
return
}
guestDesc, gusetNic := guestman.GetGuestManager().GetGuestNicDesc("", ip, "", "", false)
if guestDesc == nil || gusetNic == nil {
hostutils.Response(ctx, w, "")
return
}
if !guestDesc.Contains("user_data") {
hostutils.Response(ctx, w, "")
return
}
guestUserData, _ := guestDesc.GetString("user_data")
userDataDecoded, err := base64.StdEncoding.DecodeString(guestUserData)
if err != nil {
guestId, _ := guestDesc.GetString("id")
log.Errorf("Error format user_data %s, %s", guestId, guestUserData)
hostutils.Response(ctx, w, "")
return
}
hostutils.Response(ctx, w, string(userDataDecoded))
}
func metaData(ctx context.Context, w http.ResponseWriter, r *http.Request) {
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
hostutils.Response(ctx, w, httperrors.NewBadRequestError("Parse Remoteaddr %s error %s", r.RemoteAddr, err.Error()))
return
}
guestDesc, gusetNic := guestman.GetGuestManager().GetGuestNicDesc("", ip, "", "", false)
if guestDesc == nil || gusetNic == nil {
hostutils.Response(ctx, w, "")
return
}
req := appsrv.SplitPath(r.URL.Path)[2:]
if len(req) == 0 {
resNames := []string{
"ami-launch-index",
"block-device-mapping/", "hostname",
"instance-id", "instance-type",
"local-hostname", "local-ipv4", "mac",
"public-hostname", "public-ipv4",
"network_config/",
//"amiid", "ami-manifest-path",
//"instance-action", "kernel-id",
//"ipv4-associations", "network/",
//"placement/", "public-keys/",
//"reservation-id", "security-groups", "password",
}
if guestDesc.Contains("pubkey") {
resNames = append(resNames, "public-keys/")
}
if guestDesc.Contains("zone") {
resNames = append(resNames, "placement/")
}
if guestDesc.Contains("secgroup") {
resNames = append(resNames, "security-groups/")
}
hostutils.Response(ctx, w, strings.Join(resNames, "\n"))
} else {
resName := req[0]
switch resName {
case "public-keys":
if guestDesc.Contains("pubkey") {
if len(req) == 1 {
hostutils.Response(ctx, w, "0=my-public-key")
return
} else if len(req) == 2 {
hostutils.Response(ctx, w, "openssh-key")
return
} else if len(req) == 3 {
pubkey, _ := guestDesc.GetString("pubkeu")
hostutils.Response(ctx, w, pubkey)
return
}
}
case "hostname", "public-hostname", "local-hostname":
guestName, _ := guestDesc.GetString("name")
hostutils.Response(ctx, w, guestName)
return
case "instance-id":
guestUUID, _ := guestDesc.GetString("uuid")
hostutils.Response(ctx, w, guestUUID)
return
case "instance-type":
flavor, err := guestDesc.GetString("flavor")
if err != nil {
flavor = "customized"
}
hostutils.Response(ctx, w, flavor)
return
case "mac":
macs := make([]string, 0)
guestNics, _ := guestDesc.GetArray("nics")
for _, nic := range guestNics {
nicMac, _ := nic.GetString("mac")
macs = append(macs, nicMac)
}
hostutils.Response(ctx, w, strings.Join(macs, "\n"))
return
case "local-ipv4":
ips := make([]string, 0)
guestNics, _ := guestDesc.GetArray("nics")
for _, nic := range guestNics {
nicip, _ := nic.GetString("ip")
ips = append(ips, nicip)
}
hostutils.Response(ctx, w, strings.Join(ips, "\n"))
return
case "public-ipv4":
ips := make([]string, 0)
guestNics, _ := guestDesc.GetArray("nics")
for _, nic := range guestNics {
nicip, _ := nic.GetString("ip")
ipv4, _ := netutils.NewIPV4Addr(nicip)
if !netutils.IsPrivate(ipv4) {
ips = append(ips, nicip)
}
}
hostutils.Response(ctx, w, strings.Join(ips, "\n"))
return
case "placement":
if guestDesc.Contains("zone") {
if len(req) == 1 {
hostutils.Response(ctx, w, "availability-zone")
return
} else if len(req) == 2 && req[1] == "availability-zone" {
guestZone, _ := guestDesc.GetString("zone")
hostutils.Response(ctx, w, guestZone)
return
}
}
case "security-groups":
if guestDesc.Contains("secgroup") {
guestSecgroup, _ := guestDesc.GetString("secgroup")
hostutils.Response(ctx, w, guestSecgroup)
return
}
case "ami-launch-index":
hostutils.Response(ctx, w, "0")
return
case "network_config":
if len(req) == 1 {
hostutils.Response(ctx, w,
strings.Join([]string{"name", "content_path"}, "\n"))
return
} else if len(req) == 2 {
if req[1] == "name" {
hostutils.Response(ctx, w, "network_config")
return
} else if req[1] == "content_path" {
hostutils.Response(ctx, w, "content/0001")
return
}
}
case "block-device-mapping":
guestDisks, _ := guestDesc.GetArray("disks")
swapDisks := make([]string, 0)
dataDisk := make([]string, 0)
for _, d := range guestDisks {
fs, err := d.GetString("fs")
idx, _ := d.Int("index")
if err != nil && fs == "swap" {
swapDisks = append(swapDisks, strconv.Itoa(int(idx)))
} else {
dataDisk = append(dataDisk, strconv.Itoa(int(idx)))
}
}
if len(req) == 1 {
devs := []string{"root"}
if len(swapDisks) > 0 {
devs = append(devs, "swap")
}
if len(dataDisk) > 0 {
for i := 0; i < len(dataDisk); i++ {
devs = append(devs, fmt.Sprintf("ephemeral%d", i+1))
}
}
hostutils.Response(ctx, w, strings.Join(devs, "\n"))
return
} else if len(req) == 2 {
devs := []string{}
if req[1] == "root" {
devs = append(devs, "/dev/root")
} else if req[1] == "swap" {
for i := 0; i < len(swapDisks); i++ {
idx, _ := strconv.Atoi(swapDisks[i])
devs = append(devs, fmt.Sprintf("/dev/vd%c1", 'a'+idx))
}
} else if strings.HasPrefix(req[1], "ephemeral") || strings.HasPrefix(req[1], "ebs") {
for i := 0; i < len(dataDisk); i++ {
idx, _ := strconv.Atoi(dataDisk[i])
devs = append(devs, fmt.Sprintf("/dev/vd%c1", 'a'+idx))
}
}
hostutils.Response(ctx, w, strings.Join(devs, "\n"))
return
}
}
}
hostutils.Response(ctx, w, httperrors.NewNotFoundError("Resource not handled"))
}
func StartService(app *appsrv.Application, address string, port int) {
addMetadataHandler("", app)
addr := net.JoinHostPort(address, strconv.Itoa(port))
log.Infof("Host Metadata Start listen on %s://%s", "http", addr)
app.ListenAndServeWithCleanup(addr, nil)
}