diff --git a/metadata/manager.go b/metadata/manager.go
index 9898bfed3b3ffbcfec433cbc953632b745270570..7f60687810cb3ba2a42362a68b6d75724e6c230e 100644
--- a/metadata/manager.go
+++ b/metadata/manager.go
@@ -1,11 +1,14 @@
 package metadata
 
 import (
+	"encoding/json"
 	"fmt"
 	"os"
 	"path"
 	"path/filepath"
 
+	"github.com/ksonnet/ksonnet-lib/ksonnet-gen/ksonnet"
+	"github.com/ksonnet/ksonnet-lib/ksonnet-gen/kubespec"
 	"github.com/spf13/afero"
 )
 
@@ -24,7 +27,8 @@ const (
 	schemaDir     = "vendor/schema"
 	vendorLibDir  = "vendor/lib"
 
-	schemaFilename = "swagger.json"
+	schemaFilename         = "swagger.json"
+	ksonnetLibCoreFilename = "k8s.libsonnet"
 )
 
 type manager struct {
@@ -62,18 +66,41 @@ func findManager(abs AbsPath, 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 {
 		return nil, err
 	}
 
 	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 {
 		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
 	}
 
@@ -136,3 +163,18 @@ func (m *manager) createAppDirTree() error {
 
 	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)
+}
diff --git a/metadata/manager_test.go b/metadata/manager_test.go
index 1329bc8b9d5385d6f5f9d8227bba8a96c540304f..d73fd97cc8c4f1e8bb332a3d35c9d40e680b70ee 100644
--- a/metadata/manager_test.go
+++ b/metadata/manager_test.go
@@ -10,7 +10,25 @@ import (
 
 const (
 	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()
@@ -60,6 +78,14 @@ func TestInitSuccess(t *testing.T) {
 	} else if actualSwagger := string(bytes); actualSwagger != blankSwaggerData {
 		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) {