Skip to content

Commit

Permalink
Update reconcile logic with cold-warm-hot pod scale
Browse files Browse the repository at this point in the history
  • Loading branch information
vutuong committed Jan 14, 2021
1 parent 9d993bc commit d19c657
Show file tree
Hide file tree
Showing 12 changed files with 816 additions and 326 deletions.
236 changes: 118 additions & 118 deletions api-server/endpoints/podmigration.go
Original file line number Diff line number Diff line change
@@ -1,118 +1,118 @@
package endpoints

import (
"fmt"

v1 "github.com/SSU-DCN/podmigration-operator/api/v1"
"github.com/emicklei/go-restful"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
kubelog "sigs.k8s.io/controller-runtime/pkg/log"
)

type PodmigrationEndpoint struct {
client client.Client
}

func NewPodmigrationEndpoint(client client.Client) *PodmigrationEndpoint {
return &PodmigrationEndpoint{client: client}
}

func (pe *PodmigrationEndpoint) SetupWithWS(ws *restful.WebService) {
ws.Route(ws.GET("Podmigrations").To(pe.list).
Doc("List of Podmigrations").
Returns(200, "OK", &List{}))

ws.Route(ws.POST("Podmigrations").To(pe.create).
Doc("Create a new Podmigration").
Reads(&Podmigration{}).
Returns(200, "OK", &Podmigration{}).
Returns(400, "Bad Request", nil))
}

func (pe *PodmigrationEndpoint) list(request *restful.Request, response *restful.Response) {
dl := new(v1.PodmigrationList)
err := pe.client.List(request.Request.Context(), dl, &client.ListOptions{})
if err != nil {
writeError(response, 404, Error{
Title: "Error",
Details: fmt.Sprintf("Could not retrieve list: %s", err),
})
} else {
l := From.List(dl)
if err := response.WriteAsJson(l); err != nil {
writeError(response, 404, Error{
Title: "Error",
Details: "Could not list resources",
})
}
}
}

func (pe *PodmigrationEndpoint) create(request *restful.Request, response *restful.Response) {
pm := new(Podmigration)
err := request.ReadEntity(pm)

if err != nil {
writeError(response, 400, Error{
Title: "Bad Request",
Details: "Could not read entity",
})
return
}

if err := pm.Validate(); err != nil {
writeError(response, 400, Error{
Title: "Validation error",
Details: err.Error(),
})
return
}

//TODO(tuong): convert request data-raw to this Template.
template := corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"app": "redis"},
Annotations: map[string]string{"snapshotPolicy": "restore", "snapshotPath": "/var/lib/kubelet/migration/" + pm.Name},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "redis",
Image: "redis",
Ports: []corev1.ContainerPort{
{ContainerPort: 6379, Protocol: "TCP"},
},
},
},
},
}

obj := &v1.Podmigration{
ObjectMeta: metav1.ObjectMeta{Name: pm.Name, Namespace: "default"},
Spec: v1.PodmigrationSpec{Replicas: pm.Replicas, Selector: pm.Selector, Template: template},
}

err = pe.client.Create(request.Request.Context(), obj, &client.CreateOptions{})
if err != nil {
writeError(response, 400, Error{
Title: "Error",
Details: fmt.Sprintf("Could not create object: %s", err),
})
} else {
d := From.Object(obj)
if err := response.WriteAsJson(d); err != nil {
writeError(response, 422, Error{
Title: "Error",
Details: "Could not write response",
})
}
}
}

func writeError(response *restful.Response, httpStatus int, err Error) {
if err := response.WriteHeaderAndJson(httpStatus, err, "application/json"); err != nil {
kubelog.Log.Error(err, "Could not write the error response")
}
}
package endpoints

import (
"fmt"

v1 "github.com/SSU-DCN/podmigration-operator/api/v1"
"github.com/emicklei/go-restful"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
kubelog "sigs.k8s.io/controller-runtime/pkg/log"
)

type PodmigrationEndpoint struct {
client client.Client
}

func NewPodmigrationEndpoint(client client.Client) *PodmigrationEndpoint {
return &PodmigrationEndpoint{client: client}
}

func (pe *PodmigrationEndpoint) SetupWithWS(ws *restful.WebService) {
ws.Route(ws.GET("Podmigrations").To(pe.list).
Doc("List of Podmigrations").
Returns(200, "OK", &List{}))

ws.Route(ws.POST("Podmigrations").To(pe.create).
Doc("Create a new Podmigration").
Reads(&Podmigration{}).
Returns(200, "OK", &Podmigration{}).
Returns(400, "Bad Request", nil))
}

func (pe *PodmigrationEndpoint) list(request *restful.Request, response *restful.Response) {
dl := new(v1.PodmigrationList)
err := pe.client.List(request.Request.Context(), dl, &client.ListOptions{})
if err != nil {
writeError(response, 404, Error{
Title: "Error",
Details: fmt.Sprintf("Could not retrieve list: %s", err),
})
} else {
l := From.List(dl)
if err := response.WriteAsJson(l); err != nil {
writeError(response, 404, Error{
Title: "Error",
Details: "Could not list resources",
})
}
}
}

func (pe *PodmigrationEndpoint) create(request *restful.Request, response *restful.Response) {
pm := new(Podmigration)
err := request.ReadEntity(pm)

if err != nil {
writeError(response, 400, Error{
Title: "Bad Request",
Details: "Could not read entity",
})
return
}

if err := pm.Validate(); err != nil {
writeError(response, 400, Error{
Title: "Validation error",
Details: err.Error(),
})
return
}

//TODO(tuong): convert request data-raw to this Template.
template := corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"app": "redis"},
Annotations: map[string]string{"snapshotPolicy": "restore", "snapshotPath": "/var/lib/kubelet/migration/" + pm.Name},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "redis",
Image: "redis",
Ports: []corev1.ContainerPort{
{ContainerPort: 6379, Protocol: "TCP"},
},
},
},
},
}

obj := &v1.Podmigration{
ObjectMeta: metav1.ObjectMeta{Name: pm.Name, Namespace: "default"},
Spec: v1.PodmigrationSpec{Replicas: pm.Replicas, Selector: pm.Selector, Template: template},
}

err = pe.client.Create(request.Request.Context(), obj, &client.CreateOptions{})
if err != nil {
writeError(response, 400, Error{
Title: "Error",
Details: fmt.Sprintf("Could not create object: %s", err),
})
} else {
d := From.Object(obj)
if err := response.WriteAsJson(d); err != nil {
writeError(response, 422, Error{
Title: "Error",
Details: "Could not write response",
})
}
}
}

func writeError(response *restful.Response, httpStatus int, err Error) {
if err := response.WriteHeaderAndJson(httpStatus, err, "application/json"); err != nil {
kubelog.Log.Error(err, "Could not write the error response")
}
}
2 changes: 1 addition & 1 deletion api-server/endpoints/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Podmigration struct {
Name string `json:"name"`
// Replicas string `json:"replicas"`
// Selector string `json:"selector"`
Replicas *int32 `json:"replicas"`
Replicas int `json:"replicas"`
Selector *metav1.LabelSelector `json:"selector"`
// Template corev1.PodTemplateSpec `json:"template"`
Status *v1.PodmigrationStatus `json:"status,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion api/v1/podmigration_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type PodmigrationSpec struct {
// Number of desired pods. This is a pointer to distinguish between explicit
// zero and not specified. Defaults to 1.
// +optional
Replicas *int32 `json:"replicas,omitempty"`
Replicas int `json:"replicas,omitempty"`

// Label selector for pods. Existing ReplicaSets whose pods are
// selected by this will be the ones affected by this deployment.
Expand Down
5 changes: 0 additions & 5 deletions api/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d19c657

Please sign in to comment.