Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
# MetaMorph

Lifecycle your BareMetal
MetaMorph is a tool introduced to provision baremetal nodes in the kubernetes native way. It is fully compliant with Kubernetes Cluster API, its a Baremetal Provisioner. MetaMorph uses native redfish APIs to provision the baremetal nodes thus eliminating complex traditional pre-requisties like DHCP, TFTP, PXE booting etc. ISO used to provision the OS will be mounted from an HTTP share using `VirtualMedia` feature of Redfish

## Features

1. **Minimum Pre-requisties/Dependencies** The only Pre-requisties Metamorph has is the Redfish Protocal support on the node to be provisioned.
2. **Edge Node Deployment** Since Metamorph eliminates the complex pre-requisties like DHCP, TFTP, PXE booting etc, Its very easy and reliable to deploy edge nodes.
3. **Vendor Independent** Servers manufactored by any vendor can be deployed (provided it supports Redfish protocol)
4. **Boot Actions** Boot Actions are jobs that will be executed on the first boot of the deployed node. It can be used to deploy any kind of software on the target node. Boot Actions can be written in any languages.
5. **Plugin Support** Plugins can do variety of things. It can extend default features/functionlity, Add support for old hardware that doesn't support Redfish protocol (eg: HP iLO4 RAID Config), Integrate othe tools/services to MetaMorph \**coming soon*.



## Setup Dev env

1. `git clone https://github.com/bm-metamorph/MetaMorph.git`

## Setting up Development Environment

Setup ENV variables

```
export METAMORPH_CONFIGPATH=<path of config.yaml location>
export REDFISH_SLEEPTIME_SECS=10 //time duration in between subsequent redfish API calls. Default = 120 secs
export METAMORPH_POWERCHANGE_TIMEOUT=300 //To handle Nodes that are powered off at the start of RAID Creation.
export METAMORPH_LOG_LEVEL= 1 // default is DEBUG, 1 = INFO 2 = WARN 3 = ERROR
export REDFISH_JOBCHECKTIMEOUT_MTS= 10 // default is 10 minutes. Job related to firmware updates takes more time.
cd MetaMorph
```

1. To Run the Controller
2. To Run the Controller
`go run main.go controller`

2. To Run the API
3. To Run the API
`go run main.go api`

## Resources

* [Usage Documentation](https://metamorph.readthedocs.io/en/latest/usageGuide)
* [API References](https://metamorph.readthedocs.io/en/latest/references)




6 changes: 3 additions & 3 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package main
import(
"fmt"
//"time"
"bitbucket.com/metamorph/proto"
"bitbucket.com/metamorph/pkg/config"
"bitbucket.com/metamorph/pkg/db/models/node"
"github.com/bm-metamorph/MetaMorph/proto"
"github.com/manojkva/metamorph-plugin/pkg/config"
"github.com/bm-metamorph/MetaMorph/pkg/db/models/node"
"google.golang.org/grpc"
"context"
"encoding/json"
Expand Down
27 changes: 17 additions & 10 deletions pkg/apis/main.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
package api

import (
"bitbucket.com/metamorph/pkg/logger"
"bitbucket.com/metamorph/proto"
"github.com/manojkva/metamorph-plugin/pkg/logger"
"github.com/bm-metamorph/MetaMorph/proto"
"fmt"
"github.com/gin-contrib/zap"
"github.com/gin-gonic/gin"
ctrlgRPCServer "github.com/bm-metamorph/MetaMorph/pkg/controller/grpc"
"go.uber.org/zap"
"google.golang.org/grpc"
"net/http"
"time"
"os"
)
func run_controller() {
ctrlgRPCServer.Serve()

}
func grpcClient() (proto.NodeServiceClient, *grpc.ClientConn) {

grpcServer := "localhost"
if gs := os.Getenv("METMORPH_CONTROLLER_HOST"); gs != "" {
grpcServer = gs
}

logger.Log.Info("grpcClient()")
conn, err := grpc.Dial(fmt.Sprintf("%s:4040", grpcServer), grpc.WithInsecure())
if err != nil {
logger.Log.Error("Failed to connect to GRPC server", zap.Error(err))
panic(err)
}
client := proto.NewNodeServiceClient(conn)

return client, conn
}

Expand All @@ -37,6 +40,7 @@ func createNode(ctx *gin.Context) {
data, _ := ctx.GetRawData()
req := &proto.Request{NodeSpec: data}
if response, err := client.Create(ctx, req); err == nil {
fmt.Println(response)
ctx.JSON(http.StatusOK, gin.H{
"result": fmt.Sprint(response.Result),
})
Expand All @@ -54,7 +58,7 @@ func describeNode(ctx *gin.Context) {
logger.Log.Info("describeNode()")
client, conn := grpcClient()
node_id := ctx.Param("node_id")
fmt.Println(node_id)
logger.Log.Debug("Node info from Request", zap.String("NodeID", string(node_id)))
req := &proto.Request{NodeID: string(node_id)}
if response, err := client.Describe(ctx, req); err == nil {
ctx.Data(http.StatusOK, gin.MIMEJSON, response.Res)
Expand Down Expand Up @@ -195,7 +199,7 @@ func updateNodeHWStatus(ctx *gin.Context) {

}

func Serve() {
func Serve() *gin.Engine {
logger.Log.Info("Serve()")

r := gin.Default()
Expand All @@ -214,10 +218,13 @@ func Serve() {
node.DELETE("/:node_id", deleteNode)
node.POST("/deploy/:node_id", deployNode)
}
return r
}

if err := r.Run(":8080"); err != nil {
logger.Log.Fatal("Failed to Run Server", zap.Error(err))
//log.Fatalf("Failed to Run server: %v ", err)
}
func api() {
if err := Serve().Run(":8080"); err != nil {
logger.Log.Fatal("Failed to Run Server", zap.Error(err))
//log.Fatalf("Failed to Run server: %v ", err)
}

}
Loading