Switch from ThirdPartyResources to CustomResourceDefinitions (#381)
Switch Fission's storage over to the new CustomResourceDefinitions, from the deprecated ThirdPartyResources. This allows us to be compatible with Kubernets 1.8 and onwards. This also adds a CLI tool for dumping state from an old fission version and restoring state into new CRDs. The storage service is unaffected by this change.
This commit is contained in:
committed by
Soam Vasani
parent
746c51901d
commit
5f14b9b0ae
+12
-12
@@ -33,7 +33,7 @@ import (
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/cache"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -49,16 +49,16 @@ type (
|
||||
|
||||
Poolmgr struct {
|
||||
gpm *GenericPoolManager
|
||||
functionEnv *cache.Cache // map[string]tpr.Environment
|
||||
functionEnv *cache.Cache // map[string]crd.Environment
|
||||
fsCache *functionServiceCache
|
||||
fissionClient *tpr.FissionClient
|
||||
fissionClient *crd.FissionClient
|
||||
|
||||
fsCreateChannels map[string]*sync.WaitGroup // xxx no channels here, rename this
|
||||
requestChan chan *createFuncServiceRequest
|
||||
}
|
||||
)
|
||||
|
||||
func MakePoolmgr(gpm *GenericPoolManager, fissionClient *tpr.FissionClient, fissionNs string, fsCache *functionServiceCache) *Poolmgr {
|
||||
func MakePoolmgr(gpm *GenericPoolManager, fissionClient *crd.FissionClient, fissionNs string, fsCache *functionServiceCache) *Poolmgr {
|
||||
poolMgr := &Poolmgr{
|
||||
gpm: gpm,
|
||||
functionEnv: cache.MakeCache(10*time.Second, 0),
|
||||
@@ -83,13 +83,13 @@ func (poolMgr *Poolmgr) serveCreateFuncServices() {
|
||||
m := req.funcMeta
|
||||
|
||||
// Cache miss -- is this first one to request the func?
|
||||
wg, found := poolMgr.fsCreateChannels[tpr.CacheKey(m)]
|
||||
wg, found := poolMgr.fsCreateChannels[crd.CacheKey(m)]
|
||||
if !found {
|
||||
// create a waitgroup for other requests for
|
||||
// the same function to wait on
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
poolMgr.fsCreateChannels[tpr.CacheKey(m)] = wg
|
||||
poolMgr.fsCreateChannels[crd.CacheKey(m)] = wg
|
||||
|
||||
// launch a goroutine for each request, to parallelize
|
||||
// the specialization of different functions
|
||||
@@ -99,7 +99,7 @@ func (poolMgr *Poolmgr) serveCreateFuncServices() {
|
||||
address: address,
|
||||
err: err,
|
||||
}
|
||||
delete(poolMgr.fsCreateChannels, tpr.CacheKey(m))
|
||||
delete(poolMgr.fsCreateChannels, crd.CacheKey(m))
|
||||
wg.Done()
|
||||
}()
|
||||
} else {
|
||||
@@ -149,13 +149,13 @@ func (poolMgr *Poolmgr) getServiceForFunctionApi(w http.ResponseWriter, r *http.
|
||||
w.Write([]byte(serviceName))
|
||||
}
|
||||
|
||||
func (poolMgr *Poolmgr) getFunctionEnv(m *metav1.ObjectMeta) (*tpr.Environment, error) {
|
||||
var env *tpr.Environment
|
||||
func (poolMgr *Poolmgr) getFunctionEnv(m *metav1.ObjectMeta) (*crd.Environment, error) {
|
||||
var env *crd.Environment
|
||||
|
||||
// Cached ?
|
||||
result, err := poolMgr.functionEnv.Get(tpr.CacheKey(m))
|
||||
result, err := poolMgr.functionEnv.Get(crd.CacheKey(m))
|
||||
if err == nil {
|
||||
env = result.(*tpr.Environment)
|
||||
env = result.(*crd.Environment)
|
||||
return env, nil
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ func (poolMgr *Poolmgr) getFunctionEnv(m *metav1.ObjectMeta) (*tpr.Environment,
|
||||
}
|
||||
|
||||
// cache for future lookups
|
||||
poolMgr.functionEnv.Set(tpr.CacheKey(m), env)
|
||||
poolMgr.functionEnv.Set(crd.CacheKey(m), env)
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/cache"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type fscRequestType int
|
||||
@@ -39,7 +39,7 @@ const (
|
||||
type (
|
||||
funcSvc struct {
|
||||
function *metav1.ObjectMeta // function this pod/service is for
|
||||
environment *tpr.Environment // function's environment
|
||||
environment *crd.Environment // function's environment
|
||||
address string // Host:Port or IP:Port that the function's service can be reached at.
|
||||
podName string // pod name (within the function namespace)
|
||||
|
||||
@@ -94,7 +94,7 @@ func (fsc *functionServiceCache) service() {
|
||||
pods := make([]string, 0)
|
||||
for podNameI, mI := range byPodCopy {
|
||||
m := mI.(metav1.ObjectMeta)
|
||||
fsvcI, err := fsc.byFunction.Get(tpr.CacheKey(&m))
|
||||
fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m))
|
||||
if err != nil {
|
||||
resp.error = err
|
||||
} else {
|
||||
@@ -123,7 +123,7 @@ func (fsc *functionServiceCache) service() {
|
||||
}
|
||||
|
||||
func (fsc *functionServiceCache) GetByFunction(m *metav1.ObjectMeta) (*funcSvc, error) {
|
||||
key := tpr.CacheKey(m)
|
||||
key := crd.CacheKey(m)
|
||||
|
||||
fsvcI, err := fsc.byFunction.Get(key)
|
||||
if err != nil {
|
||||
@@ -140,7 +140,7 @@ func (fsc *functionServiceCache) GetByFunction(m *metav1.ObjectMeta) (*funcSvc,
|
||||
|
||||
// TODO: error should be second return
|
||||
func (fsc *functionServiceCache) Add(fsvc funcSvc) (error, *funcSvc) {
|
||||
err, existing := fsc.byFunction.Set(tpr.CacheKey(fsvc.function), &fsvc)
|
||||
err, existing := fsc.byFunction.Set(crd.CacheKey(fsvc.function), &fsvc)
|
||||
if err != nil {
|
||||
if existing != nil {
|
||||
f := existing.(*funcSvc)
|
||||
@@ -199,7 +199,7 @@ func (fsc *functionServiceCache) _touchByAddress(address string) error {
|
||||
return err
|
||||
}
|
||||
m := mI.(metav1.ObjectMeta)
|
||||
fsvcI, err := fsc.byFunction.Get(tpr.CacheKey(&m))
|
||||
fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -228,7 +228,7 @@ func (fsc *functionServiceCache) _deleteByPod(podName string, minAge time.Durati
|
||||
return false, err
|
||||
}
|
||||
m := mI.(metav1.ObjectMeta)
|
||||
fsvcI, err := fsc.byFunction.Get(tpr.CacheKey(&m))
|
||||
fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -238,7 +238,7 @@ func (fsc *functionServiceCache) _deleteByPod(podName string, minAge time.Durati
|
||||
return false, nil
|
||||
}
|
||||
|
||||
fsc.byFunction.Delete(tpr.CacheKey(&m))
|
||||
fsc.byFunction.Delete(crd.CacheKey(&m))
|
||||
fsc.byAddress.Delete(fsvc.address)
|
||||
fsc.byPod.Delete(podName)
|
||||
return true, nil
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
func TestFunctionServiceCache(t *testing.T) {
|
||||
@@ -25,7 +25,7 @@ func TestFunctionServiceCache(t *testing.T) {
|
||||
Name: "foo",
|
||||
UID: "1212",
|
||||
},
|
||||
environment: &tpr.Environment{
|
||||
environment: &crd.Environment{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "foo-env",
|
||||
UID: "2323",
|
||||
|
||||
+5
-5
@@ -40,10 +40,10 @@ import (
|
||||
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
"github.com/fission/fission/environments/fetcher"
|
||||
fetcherClient "github.com/fission/fission/environments/fetcher/client"
|
||||
"github.com/fission/fission/logger"
|
||||
"github.com/fission/fission/tpr"
|
||||
)
|
||||
|
||||
const POOLMGR_INSTANCEID_LABEL string = "poolmgrInstanceId"
|
||||
@@ -51,7 +51,7 @@ const POD_PHASE_RUNNING string = "Running"
|
||||
|
||||
type (
|
||||
GenericPool struct {
|
||||
env *tpr.Environment
|
||||
env *crd.Environment
|
||||
replicas int32 // num idle pods
|
||||
deployment *v1beta1.Deployment // kubernetes deployment
|
||||
namespace string // namespace to keep our resources
|
||||
@@ -64,7 +64,7 @@ type (
|
||||
fetcherImagePullPolicy apiv1.PullPolicy
|
||||
runtimeImagePullPolicy apiv1.PullPolicy // pull policy for generic pool to created env deployment
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
fissionClient *tpr.FissionClient
|
||||
fissionClient *crd.FissionClient
|
||||
instanceId string // poolmgr instance id
|
||||
labelsForPool map[string]string
|
||||
requestChannel chan *choosePodRequest
|
||||
@@ -94,9 +94,9 @@ func getImagePullPolicy(policy string) apiv1.PullPolicy {
|
||||
}
|
||||
|
||||
func MakeGenericPool(
|
||||
fissionClient *tpr.FissionClient,
|
||||
fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset,
|
||||
env *tpr.Environment,
|
||||
env *crd.Environment,
|
||||
initialReplicas int32,
|
||||
namespace string,
|
||||
fsCache *functionServiceCache,
|
||||
|
||||
+10
-10
@@ -24,7 +24,7 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
type requestType int
|
||||
@@ -39,15 +39,15 @@ type (
|
||||
pools map[string]*GenericPool
|
||||
kubernetesClient *kubernetes.Clientset
|
||||
namespace string
|
||||
fissionClient *tpr.FissionClient
|
||||
fissionClient *crd.FissionClient
|
||||
fsCache *functionServiceCache
|
||||
instanceId string
|
||||
requestChannel chan *request
|
||||
}
|
||||
request struct {
|
||||
requestType
|
||||
env *tpr.Environment
|
||||
envList []tpr.Environment
|
||||
env *crd.Environment
|
||||
envList []crd.Environment
|
||||
responseChannel chan *response
|
||||
}
|
||||
response struct {
|
||||
@@ -57,7 +57,7 @@ type (
|
||||
)
|
||||
|
||||
func MakeGenericPoolManager(
|
||||
fissionClient *tpr.FissionClient,
|
||||
fissionClient *crd.FissionClient,
|
||||
kubernetesClient *kubernetes.Clientset,
|
||||
fissionNamespace string,
|
||||
functionNamespace string,
|
||||
@@ -85,7 +85,7 @@ func (gpm *GenericPoolManager) service() {
|
||||
switch req.requestType {
|
||||
case GET_POOL:
|
||||
var err error
|
||||
pool, ok := gpm.pools[tpr.CacheKey(&req.env.Metadata)]
|
||||
pool, ok := gpm.pools[crd.CacheKey(&req.env.Metadata)]
|
||||
if !ok {
|
||||
var poolSize int32 = 3 // TODO configurable/autoscalable
|
||||
switch req.env.Spec.AllowedFunctionsPerContainer {
|
||||
@@ -100,13 +100,13 @@ func (gpm *GenericPoolManager) service() {
|
||||
req.responseChannel <- &response{error: err}
|
||||
continue
|
||||
}
|
||||
gpm.pools[tpr.CacheKey(&req.env.Metadata)] = pool
|
||||
gpm.pools[crd.CacheKey(&req.env.Metadata)] = pool
|
||||
}
|
||||
req.responseChannel <- &response{pool: pool}
|
||||
case CLEANUP_POOLS:
|
||||
latestEnvSet := make(map[string]bool)
|
||||
for _, env := range req.envList {
|
||||
latestEnvSet[tpr.CacheKey(&env.Metadata)] = true
|
||||
latestEnvSet[crd.CacheKey(&env.Metadata)] = true
|
||||
}
|
||||
for key, pool := range gpm.pools {
|
||||
_, ok := latestEnvSet[key]
|
||||
@@ -124,7 +124,7 @@ func (gpm *GenericPoolManager) service() {
|
||||
}
|
||||
}
|
||||
|
||||
func (gpm *GenericPoolManager) GetPool(env *tpr.Environment) (*GenericPool, error) {
|
||||
func (gpm *GenericPoolManager) GetPool(env *crd.Environment) (*GenericPool, error) {
|
||||
c := make(chan *response)
|
||||
gpm.requestChannel <- &request{
|
||||
requestType: GET_POOL,
|
||||
@@ -135,7 +135,7 @@ func (gpm *GenericPoolManager) GetPool(env *tpr.Environment) (*GenericPool, erro
|
||||
return resp.pool, resp.error
|
||||
}
|
||||
|
||||
func (gpm *GenericPoolManager) CleanupPools(envs []tpr.Environment) {
|
||||
func (gpm *GenericPoolManager) CleanupPools(envs []crd.Environment) {
|
||||
gpm.requestChannel <- &request{
|
||||
requestType: CLEANUP_POOLS,
|
||||
envList: envs,
|
||||
|
||||
+2
-2
@@ -21,12 +21,12 @@ import (
|
||||
|
||||
"github.com/dchest/uniuri"
|
||||
|
||||
"github.com/fission/fission/tpr"
|
||||
"github.com/fission/fission/crd"
|
||||
)
|
||||
|
||||
// Start the poolmgr service.
|
||||
func StartPoolmgr(fissionNamespace string, functionNamespace string, port int) error {
|
||||
fissionClient, kubernetesClient, err := tpr.MakeFissionClient()
|
||||
fissionClient, kubernetesClient, _, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
log.Printf("Failed to get kubernetes client: %v", err)
|
||||
return err
|
||||
|
||||
+32
-22
@@ -39,14 +39,14 @@ import (
|
||||
apiv1 "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"github.com/fission/fission"
|
||||
"github.com/fission/fission/crd"
|
||||
"github.com/fission/fission/poolmgr/client"
|
||||
"github.com/fission/fission/tpr"
|
||||
)
|
||||
|
||||
// return the number of pods in the given namespace matching the given labels
|
||||
func countPods(kubeClient *kubernetes.Clientset, ns string, labelz map[string]string) int {
|
||||
pods, err := kubeClient.Pods(ns).List(metav1.ListOptions{
|
||||
LabelSelector: labels.Set(labelz).AsSelector(),
|
||||
LabelSelector: labels.Set(labelz).AsSelector().String(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Panicf("Failed to list pods: %v", err)
|
||||
@@ -120,8 +120,8 @@ func TestPoolmgr(t *testing.T) {
|
||||
}
|
||||
|
||||
// connect to k8s
|
||||
// and get TPR client
|
||||
fissionClient, kubeClient, err := tpr.MakeFissionClient()
|
||||
// and get CRD client
|
||||
fissionClient, kubeClient, apiExtClient, err := crd.MakeFissionClient()
|
||||
if err != nil {
|
||||
log.Panicf("failed to connect: %v", err)
|
||||
}
|
||||
@@ -133,16 +133,16 @@ func TestPoolmgr(t *testing.T) {
|
||||
createTestNamespace(kubeClient, functionNs)
|
||||
defer kubeClient.Namespaces().Delete(functionNs, nil)
|
||||
|
||||
// make sure TPR types exist on cluster
|
||||
err = tpr.EnsureFissionTPRs(kubeClient)
|
||||
// make sure CRD types exist on cluster
|
||||
err = crd.EnsureFissionCRDs(apiExtClient)
|
||||
if err != nil {
|
||||
log.Panicf("failed to ensure tprs: %v", err)
|
||||
log.Panicf("failed to ensure crds: %v", err)
|
||||
}
|
||||
fissionClient.WaitForTPRs()
|
||||
fissionClient.WaitForCRDs()
|
||||
|
||||
// create an env on the cluster
|
||||
env, err := fissionClient.Environments(fissionNs).Create(&tpr.Environment{
|
||||
Metadata: metametav1.ObjectMeta{
|
||||
env, err := fissionClient.Environments(fissionNs).Create(&crd.Environment{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "nodejs",
|
||||
Namespace: fissionNs,
|
||||
},
|
||||
@@ -173,37 +173,47 @@ func TestPoolmgr(t *testing.T) {
|
||||
// waitForPool(functionNs, "nodejs")
|
||||
time.Sleep(6 * time.Second)
|
||||
|
||||
envRef := fission.EnvironmentReference{
|
||||
Namespace: env.Metadata.Namespace,
|
||||
Name: env.Metadata.Name,
|
||||
}
|
||||
|
||||
deployment := fission.Archive{
|
||||
Type: fission.ArchiveTypeLiteral,
|
||||
Literal: []byte(`module.exports = async function(context) { return { status: 200, body: "Hello, world!\n" }; }`),
|
||||
}
|
||||
|
||||
// create a package
|
||||
p := &tpr.Package{
|
||||
Metadata: metametav1.ObjectMeta{
|
||||
p := &crd.Package{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "hello",
|
||||
Namespace: fissionNs,
|
||||
},
|
||||
Spec: fission.PackageSpec{
|
||||
Type: fission.PackageTypeLiteral,
|
||||
Literal: []byte(`module.exports = async function(context) { return { status: 200, body: "Hello, world!\n" }; }`),
|
||||
Environment: envRef,
|
||||
Deployment: deployment,
|
||||
},
|
||||
}
|
||||
_, err = fissionClient.Packages(fissionNs).Create(p)
|
||||
p, err = fissionClient.Packages(fissionNs).Create(p)
|
||||
if err != nil {
|
||||
log.Panicf("failed to create package: %v", err)
|
||||
}
|
||||
|
||||
// create a function
|
||||
f := &tpr.Function{
|
||||
Metadata: metametav1.ObjectMeta{
|
||||
f := &crd.Function{
|
||||
Metadata: metav1.ObjectMeta{
|
||||
Name: "hello",
|
||||
Namespace: fissionNs,
|
||||
},
|
||||
Spec: fission.FunctionSpec{
|
||||
Source: fission.FunctionPackageRef{},
|
||||
Deployment: fission.FunctionPackageRef{
|
||||
Environment: envRef,
|
||||
Package: fission.FunctionPackageRef{
|
||||
PackageRef: fission.PackageRef{
|
||||
Name: p.Metadata.Name,
|
||||
Namespace: p.Metadata.Namespace,
|
||||
Namespace: p.Metadata.Namespace,
|
||||
Name: p.Metadata.Name,
|
||||
ResourceVersion: p.Metadata.ResourceVersion,
|
||||
},
|
||||
},
|
||||
EnvironmentName: env.Metadata.Name,
|
||||
},
|
||||
}
|
||||
_, err = fissionClient.Functions(fissionNs).Create(f)
|
||||
|
||||
Reference in New Issue
Block a user