Skip to content

Commit

Permalink
kube: manifest crd
Browse files Browse the repository at this point in the history
* replaces deployment annotation encoding/decoding
  • Loading branch information
aastein authored Jun 19, 2018
1 parent ea64abe commit 7e05fd9
Show file tree
Hide file tree
Showing 44 changed files with 2,219 additions and 200 deletions.
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ test-cover:
goveralls -service=travis-ci -ignore="types/types.pb.go"

test-vet:
go vet $$(glide novendor)
go vet $$(glide novendor | grep -v ./pkg/)

deps-install:
glide install
glide install -v

devdeps-install:
go get github.com/gogo/protobuf/protoc-gen-gogo
Expand All @@ -68,6 +68,11 @@ integrationdeps-install:

gentypes: $(PROTOC_FILES)

kubetypes:
vendor/k8s.io/code-generator/generate-groups.sh all \
github.com/ovrclk/akash/pkg/client github.com/ovrclk/akash/pkg/apis \
akash.network:v1

%.pb.go: %.proto
protoc -I. \
-Ivendor -Ivendor/github.com/gogo/protobuf/protobuf \
Expand Down Expand Up @@ -102,4 +107,5 @@ clean:
test-vet \
mocks \
docs \
clean
clean \
kubetypes
2 changes: 1 addition & 1 deletion _run/multi/akash-provider/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ fi

echo "running provider $(cat "$providerKey")..."

./akash provider run "$(cat "$providerKey")" -k master --kube
./akash provider run "$(cat "$providerKey")" -k master --kube --manifest-ns "$1"
2 changes: 1 addition & 1 deletion _run/multi/akash-provider/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ spec:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: [ "/bin/sh" , "/config/run.sh" ]
command: [ "/bin/sh" , "/config/run.sh", "{{ template "akash-provider.name" . }}" ]
env:
- name: AKASH_DATA
value: /data
Expand Down
7 changes: 6 additions & 1 deletion cmd/akash/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ func runCommand() *cobra.Command {
}

cmd.Flags().Bool("kube", false, "use kubernetes cluster")
cmd.Flags().String("manifest-ns", "lease", "set manifest namespace")
return cmd
}

Expand Down Expand Up @@ -152,7 +153,11 @@ func doProviderRunCommand(session session.Session, cmd *cobra.Command, args []st

if ok, _ := cmd.Flags().GetBool("kube"); ok {
session.Log().Debug("using kube client")
cclient, err = kube.NewClient(session.Log().With("cmp", "cluster-client"))
ns, err := cmd.Flags().GetString("manifest-ns")
if err != nil {
return err
}
cclient, err = kube.NewClient(session.Log().With("cmp", "cluster-client"), ns)
if err != nil {
return err
}
Expand Down
8 changes: 8 additions & 0 deletions glide.lock

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

4 changes: 4 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import:
version: ^7.0.0
subpackages:
- '...'
- package: k8s.io/apiextensions-apiserver
- package: k8s.io/apimachinery
subpackages:
- '...'
Expand All @@ -56,3 +57,6 @@ import:
- package: github.com/golang/protobuf
version: ~1.1.0
- package: github.com/juju/errors
- package: k8s.io/code-generator
- package: k8s.io/gengo
- package: github.com/hashicorp/golang-lru
5 changes: 5 additions & 0 deletions pkg/apis/akash.network/v1/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// +k8s:deepcopy-gen=package

// Package v1 is the v1 version of the API.
// +groupName=akash.network
package v1
68 changes: 68 additions & 0 deletions pkg/apis/akash.network/v1/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package v1

import (
"reflect"

apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apiextcs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)

const (
CRDPlural string = "manifests"
CRDGroup string = "akash.network"
CRDVersion string = "v1"
FullCRDName string = CRDPlural + "." + CRDGroup
)

var (
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme = SchemeBuilder.AddToScheme
)

// Create a Rest client with the new CRD Schema
var SchemeGroupVersion = schema.GroupVersion{Group: CRDGroup, Version: CRDVersion}

func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Manifest{},
&ManifestList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

// Create the CRD resource, ignore error if it already exists
func CreateCRD(clientset apiextcs.Interface) error {
crd := &apiextv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: FullCRDName},
Spec: apiextv1beta1.CustomResourceDefinitionSpec{
Group: CRDGroup,
Version: CRDVersion,
Scope: apiextv1beta1.NamespaceScoped,
Names: apiextv1beta1.CustomResourceDefinitionNames{
Plural: CRDPlural,
Kind: reflect.TypeOf(Manifest{}).Name(),
},
},
}

_, err := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Create(crd)
if err != nil && apierrors.IsAlreadyExists(err) {
return nil
}
return err
}
179 changes: 179 additions & 0 deletions pkg/apis/akash.network/v1/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package v1

import (
"bytes"
"encoding/json"

"github.com/gogo/protobuf/jsonpb"
"github.com/ovrclk/akash/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type Manifest struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Spec ManifestSpec
Status ManifestStatus
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type ManifestGroup struct {
metav1.TypeMeta `json:",inline"`
// Placement profile name
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Service definitions
Services []*ManifestService `protobuf:"bytes,2,rep,name=services" json:"services,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type LeaseID struct {
metav1.TypeMeta `json:",inline"`
// deployment address
Deployment []byte `protobuf:"bytes,1,opt,name=deployment,proto3,customtype=github.com/ovrclk/akash/types/base.Bytes" json:"deployment"`
// deployment group sequence
Group uint64 `protobuf:"varint,2,opt,name=group,proto3" json:"group,omitempty"`
// order sequence
Order uint64 `protobuf:"varint,3,opt,name=order,proto3" json:"order,omitempty"`
// provider address
Provider []byte `protobuf:"bytes,4,opt,name=provider,proto3,customtype=github.com/ovrclk/akash/types/base.Bytes" json:"provider"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type ManifestSpec struct {
metav1.TypeMeta `json:",inline"`
LeaseID LeaseID `json:"lease_id"`
ManifestGroup ManifestGroup `json:"manifest_group"`
}

type ManifestService struct {
// Service name
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// Docker image
Image string `protobuf:"bytes,2,opt,name=image,proto3" json:"image,omitempty"`
Args []string `protobuf:"bytes,3,rep,name=args" json:"args,omitempty"`
Env []string `protobuf:"bytes,4,rep,name=env" json:"env,omitempty"`
// Resource requirements
Unit ResourceUnit `protobuf:"bytes,5,opt,name=unit" json:"unit"`
// Number of instances
Count uint32 `protobuf:"varint,6,opt,name=count,proto3" json:"count,omitempty"`
// Overlay Network Links
Expose []*ManifestServiceExpose `protobuf:"bytes,7,rep,name=expose" json:"expose,omitempty"`
}

type ManifestServiceExpose struct {
Port uint32 `protobuf:"varint,1,opt,name=port,proto3" json:"port,omitempty"`
ExternalPort uint32 `protobuf:"varint,2,opt,name=externalPort,proto3" json:"externalPort,omitempty"`
Proto string `protobuf:"bytes,3,opt,name=proto,proto3" json:"proto,omitempty"`
Service string `protobuf:"bytes,4,opt,name=service,proto3" json:"service,omitempty"`
Global bool `protobuf:"varint,5,opt,name=global,proto3" json:"global,omitempty"`
// accepted hostnames
Hosts []string `protobuf:"bytes,6,rep,name=hosts" json:"hosts,omitempty"`
}

type ResourceUnit struct {
CPU uint32 `protobuf:"varint,1,opt,name=CPU,proto3" json:"CPU,omitempty"`
Memory uint32 `protobuf:"varint,2,opt,name=memory,proto3" json:"memory,omitempty"`
Disk uint64 `protobuf:"varint,3,opt,name=disk,proto3" json:"disk,omitempty"`
}

type ManifestStatus struct {
State string `json:"state,omitempty"`
Message string `json:"message,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type ManifestList struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
Items []Manifest `json:"items"`
}

func (m Manifest) ManifestGroup() *types.ManifestGroup {
group, err := m.manifestGroup()
if err != nil {
panic("kube manifest manifestGroup error: " + err.Error())
}
return group
}

func (m *Manifest) manifestGroup() (*types.ManifestGroup, error) {
group := &types.ManifestGroup{}
unmarshaler := &jsonpb.Unmarshaler{}
buf, err := json.Marshal(m.Spec.ManifestGroup)
if err != nil {
return nil, err
}
err = unmarshaler.Unmarshal(bytes.NewReader(buf), group)
if err != nil {
return nil, err
}
return group, nil
}

func (m Manifest) LeaseID() types.LeaseID {
leaseID, err := m.leaseID()
if err != nil {
panic("kube manifest leaseID error: " + err.Error())
}
return leaseID
}

func (m *Manifest) leaseID() (types.LeaseID, error) {
leaseID := types.LeaseID{}
buf, err := json.Marshal(m.Spec.LeaseID)
if err != nil {
return leaseID, err
}
unmarshaler := &jsonpb.Unmarshaler{}
err = unmarshaler.Unmarshal(bytes.NewReader(buf), &leaseID)
if err != nil {
return leaseID, err
}
return leaseID, nil
}

func NewManifest(name string, lid *types.LeaseID, mgroup *types.ManifestGroup) (*Manifest, error) {
buf := bytes.NewBuffer(nil)
marshaler := &jsonpb.Marshaler{}
manifestGroup := &ManifestGroup{}
leaseID := &LeaseID{}

err := marshaler.Marshal(buf, mgroup)
if err != nil {
return nil, err
}
json.Unmarshal(buf.Bytes(), manifestGroup)
if err != nil {
return nil, err
}

buf.Reset()
err = marshaler.Marshal(buf, lid)
if err != nil {
return nil, err
}
json.Unmarshal(buf.Bytes(), leaseID)
if err != nil {
return nil, err
}

return &Manifest{
TypeMeta: metav1.TypeMeta{
Kind: "Manifest",
APIVersion: "akash.network/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: ManifestSpec{
ManifestGroup: *manifestGroup,
LeaseID: *leaseID,
},
}, nil
}
40 changes: 40 additions & 0 deletions pkg/apis/akash.network/v1/types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package v1

import (
"testing"

"github.com/ovrclk/akash/sdl"
"github.com/ovrclk/akash/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestToProto(t *testing.T) {
lease := testutil.Lease(testutil.Address(t), testutil.Address(t), 1, 2, 3)

sdl, err := sdl.ReadFile("../../../../_run/kube/deployment.yml")
require.NoError(t, err)

mani, err := sdl.Manifest()
require.NoError(t, err)

_, err = NewManifest("name", &lease.LeaseID, mani.Groups[0])
assert.NoError(t, err)
}

func TestFromProto(t *testing.T) {
lease := testutil.Lease(testutil.Address(t), testutil.Address(t), 1, 2, 3)
sdl, err := sdl.ReadFile("../../../../_run/kube/deployment.yml")
require.NoError(t, err)

mani, err := sdl.Manifest()
require.NoError(t, err)

kubeManifest, err := NewManifest("name", &lease.LeaseID, mani.Groups[0])
assert.NoError(t, err)

fromKube := kubeManifest.ManifestGroup()
assert.NoError(t, err)

assert.Equal(t, mani.Groups[0].Name, fromKube.Name)
}
Loading

0 comments on commit 7e05fd9

Please sign in to comment.