Skip to content
Snippets Groups Projects
Commit ccd74079 authored by Alex Clemmer's avatar Alex Clemmer
Browse files

Generate ksonnet-lib as part of `metadata.Manager` initialization

`metadata.Init` is meant to initialize a ksonnet application, including
its directory structure and the initial versions of various metadata
files in the tree. But, this implementation is incomplete: currently
only the directory tree is initialized.

This commit will change init to generate ksonnet-lib as part of the
initialization process.
parent ee31939b
No related branches found
No related tags found
No related merge requests found
package metadata package metadata
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"github.com/ksonnet/ksonnet-lib/ksonnet-gen/ksonnet"
"github.com/ksonnet/ksonnet-lib/ksonnet-gen/kubespec"
"github.com/spf13/afero" "github.com/spf13/afero"
) )
...@@ -24,7 +27,8 @@ const ( ...@@ -24,7 +27,8 @@ const (
schemaDir = "vendor/schema" schemaDir = "vendor/schema"
vendorLibDir = "vendor/lib" vendorLibDir = "vendor/lib"
schemaFilename = "swagger.json" schemaFilename = "swagger.json"
ksonnetLibCoreFilename = "k8s.libsonnet"
) )
type manager struct { type manager struct {
...@@ -62,18 +66,41 @@ func findManager(abs AbsPath, appFS afero.Fs) (*manager, error) { ...@@ -62,18 +66,41 @@ func findManager(abs AbsPath, appFS afero.Fs) (*manager, error) {
} }
func initManager(rootPath AbsPath, spec ClusterSpec, appFS afero.Fs) (*manager, error) { func initManager(rootPath AbsPath, spec ClusterSpec, appFS afero.Fs) (*manager, error) {
data, err := spec.data() //
// IMPLEMENTATION NOTE: We get the cluster specification and generate
// ksonnet-lib before initializing the directory structure so that failure of
// either (e.g., GET'ing the spec from a live cluster returns 404) does not
// result in a partially-initialized directory structure.
//
// Get cluster specification data, possibly from the network.
specData, err := spec.data()
if err != nil { if err != nil {
return nil, err return nil, err
} }
m := newManager(rootPath, appFS) m := newManager(rootPath, appFS)
// Generate the program text for ksonnet-lib.
ksonnetLibDir := appendToAbsPath(m.schemaDir, defaultEnvName)
ksonnetLibData, err := generateKsonnetLibData(ksonnetLibDir, specData)
if err != nil {
return nil, err
}
// Initialize directory structure.
if err = m.createAppDirTree(); err != nil { if err = m.createAppDirTree(); err != nil {
return nil, err return nil, err
} }
if err = m.cacheClusterSpecData(defaultEnvName, data); err != nil { // Cache specification data.
if err = m.cacheClusterSpecData(defaultEnvName, specData); err != nil {
return nil, err
}
ksonnetLibPath := appendToAbsPath(ksonnetLibDir, ksonnetLibCoreFilename)
err = afero.WriteFile(appFS, string(ksonnetLibPath), ksonnetLibData, 0644)
if err != nil {
return nil, err return nil, err
} }
...@@ -136,3 +163,18 @@ func (m *manager) createAppDirTree() error { ...@@ -136,3 +163,18 @@ func (m *manager) createAppDirTree() error {
return nil return nil
} }
func generateKsonnetLibData(ksonnetLibDir AbsPath, text []byte) ([]byte, error) {
// Deserialize the API object.
s := kubespec.APISpec{}
err := json.Unmarshal(text, &s)
if err != nil {
return nil, err
}
s.Text = text
s.FilePath = filepath.Dir(string(ksonnetLibDir))
// Emit Jsonnet code.
return ksonnet.Emit(&s, nil, nil)
}
...@@ -10,7 +10,25 @@ import ( ...@@ -10,7 +10,25 @@ import (
const ( const (
blankSwagger = "/blankSwagger.json" blankSwagger = "/blankSwagger.json"
blankSwaggerData = `{}` blankSwaggerData = `{
"swagger": "2.0",
"info": {
"title": "Kubernetes",
"version": "v1.7.0"
},
"paths": {
},
"definitions": {
}
}`
blankKsonnetLib = `// AUTOGENERATED from the Kubernetes OpenAPI specification. DO NOT MODIFY.
// Kubernetes version: v1.7.0
{
local hidden = {
},
}
`
) )
var appFS = afero.NewMemMapFs() var appFS = afero.NewMemMapFs()
...@@ -60,6 +78,14 @@ func TestInitSuccess(t *testing.T) { ...@@ -60,6 +78,14 @@ func TestInitSuccess(t *testing.T) {
} else if actualSwagger := string(bytes); actualSwagger != blankSwaggerData { } else if actualSwagger := string(bytes); actualSwagger != blankSwaggerData {
t.Fatalf("Expected swagger file at '%s' to have value: '%s', got: '%s'", schemaPath, blankSwaggerData, actualSwagger) t.Fatalf("Expected swagger file at '%s' to have value: '%s', got: '%s'", schemaPath, blankSwaggerData, actualSwagger)
} }
ksonnetLibPath := appendToAbsPath(envPath, ksonnetLibCoreFilename)
ksonnetLibBytes, err := afero.ReadFile(appFS, string(ksonnetLibPath))
if err != nil {
t.Fatalf("Failed to read ksonnet-lib file at '%s':\n%v", ksonnetLibPath, err)
} else if actualKsonnetLib := string(ksonnetLibBytes); actualKsonnetLib != blankKsonnetLib {
t.Fatalf("Expected swagger file at '%s' to have value: '%s', got: '%s'", ksonnetLibPath, blankKsonnetLib, actualKsonnetLib)
}
} }
func TestFindSuccess(t *testing.T) { func TestFindSuccess(t *testing.T) {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment