Commit dd17c997 authored by jackgr's avatar jackgr

Code changes to support terminology rationalization.

parent e9abaf53
...@@ -36,29 +36,28 @@ import ( ...@@ -36,29 +36,28 @@ import (
) )
var ( var (
// TODO(jackgr): Implement reading a template from stdin stdin = flag.Bool("stdin", false, "Reads a configuration from the standard input")
//stdin = flag.Bool("stdin", false, "Reads a template from the standard input") properties = flag.String("properties", "", "Properties to use when deploying a template (e.g., --properties k1=v1,k2=v2)")
properties = flag.String("properties", "", "Properties to use when deploying a type (e.g., --properties k1=v1,k2=v2)") template_registry = flag.String("registry", "kubernetes/deployment-manager/templates", "Github based template registry (owner/repo[/path])")
type_registry = flag.String("registry", "kubernetes/deployment-manager", "Github based type registry [owner/repo]")
service = flag.String("service", "http://localhost:8001/api/v1/proxy/namespaces/default/services/manager-service:manager", "URL for deployment manager") service = flag.String("service", "http://localhost:8001/api/v1/proxy/namespaces/default/services/manager-service:manager", "URL for deployment manager")
binary = flag.String("binary", "../expandybird/expansion/expansion.py", "Path to template expansion binary") binary = flag.String("binary", "../expandybird/expansion/expansion.py", "Path to template expansion binary")
) )
var commands = []string{ var commands = []string{
"expand \t\t\t Expands the supplied template(s)", "expand \t\t\t Expands the supplied configuration(s)",
"deploy \t\t\t Deploys the supplied type or template(s)", "deploy \t\t\t Deploys the named template or the supplied configuration(s)",
"list \t\t\t Lists the deployments in the cluster", "list \t\t\t Lists the deployments in the cluster",
"get \t\t\t Retrieves the supplied deployment", "get \t\t\t Retrieves the supplied deployment",
"delete \t\t\t Deletes the supplied deployment", "delete \t\t\t Deletes the supplied deployment",
"update \t\t\t Updates a deployment using the supplied template(s)", "update \t\t\t Updates a deployment using the supplied configuration(s)",
"deployed-types \t\t Lists the types deployed in the cluster", "deployed-types \t\t Lists the types deployed in the cluster",
"deployed-instances \t Lists the instances of the supplied type deployed in the cluster", "deployed-instances \t Lists the instances of the named type deployed in the cluster",
"types \t\t\t Lists the types in the current registry", "templates \t\t Lists the templates in a given template registry",
"describe \t\t Describes the supplied type in the current registry", "describe \t\t Describes the named template in a given template registry",
} }
var usage = func() { var usage = func() {
message := "Usage: %s [<flags>] <command> (<type-name> | <deployment-name> | (<template> [<import1>...<importN>]))\n" message := "Usage: %s [<flags>] <command> (<template-name> | <deployment-name> | (<configuration> [<import1>...<importN>]))\n"
fmt.Fprintf(os.Stderr, message, os.Args[0]) fmt.Fprintf(os.Stderr, message, os.Args[0])
fmt.Fprintln(os.Stderr, "Commands:") fmt.Fprintln(os.Stderr, "Commands:")
for _, command := range commands { for _, command := range commands {
...@@ -73,12 +72,17 @@ var usage = func() { ...@@ -73,12 +72,17 @@ var usage = func() {
} }
func getGitRegistry() *registry.GithubRegistry { func getGitRegistry() *registry.GithubRegistry {
s := strings.Split(*type_registry, "/") s := strings.Split(*template_registry, "/")
if len(s) != 2 { if len(s) < 2 {
log.Fatalf("invalid type registry: %s", type_registry) log.Fatalf("invalid template registry: %s", *template_registry)
} }
return registry.NewGithubRegistry(s[0], s[1]) var path = ""
if len(s) > 2 {
path = strings.Join(s[2:], "/")
}
return registry.NewGithubRegistry(s[0], s[1], path)
} }
func main() { func main() {
...@@ -89,27 +93,32 @@ func main() { ...@@ -89,27 +93,32 @@ func main() {
usage() usage()
} }
if *stdin {
fmt.Printf("reading from stdin is not yet implemented")
os.Exit(0)
}
command := args[0] command := args[0]
switch command { switch command {
case "types": case "templates":
git := getGitRegistry() git := getGitRegistry()
types, err := git.List() templates, err := git.List()
if err != nil { if err != nil {
log.Fatalf("Cannot list %v err") log.Fatalf("Cannot list %v", err)
} }
fmt.Printf("Types:\n") fmt.Printf("Templates:\n")
for _, t := range types { for _, t := range templates {
fmt.Printf("%s:%s\n", t.Name, t.Version) fmt.Printf("%s:%s\n", t.Name, t.Version)
downloadURL, err := git.GetURL(t) downloadURL, err := git.GetURL(t)
if err != nil { if err != nil {
log.Printf("Failed to get download URL for type %s:%s", t.Name, t.Version) log.Printf("Failed to get download URL for template %s:%s", t.Name, t.Version)
} }
fmt.Printf("\tdownload URL: %s\n", downloadURL) fmt.Printf("\tdownload URL: %s\n", downloadURL)
} }
case "describe": case "describe":
fmt.Printf("this feature is not yet implemented") fmt.Printf("the describe feature is not yet implemented")
case "expand": case "expand":
backend := expander.NewExpander(*binary) backend := expander.NewExpander(*binary)
template := loadTemplate(args) template := loadTemplate(args)
...@@ -121,7 +130,7 @@ func main() { ...@@ -121,7 +130,7 @@ func main() {
fmt.Println(output) fmt.Println(output)
case "deploy": case "deploy":
template := loadTemplate(args) template := loadTemplate(args)
action := fmt.Sprintf("deploy template named %s", template.Name) action := fmt.Sprintf("deploy configuration named %s", template.Name)
callService("deployments", "POST", action, marshalTemplate(template)) callService("deployments", "POST", action, marshalTemplate(template))
case "list": case "list":
callService("deployments", "GET", "list deployments", nil) callService("deployments", "GET", "list deployments", nil)
...@@ -149,8 +158,7 @@ func main() { ...@@ -149,8 +158,7 @@ func main() {
action := fmt.Sprintf("delete deployment named %s", template.Name) action := fmt.Sprintf("delete deployment named %s", template.Name)
callService(path, "PUT", action, marshalTemplate(template)) callService(path, "PUT", action, marshalTemplate(template))
case "deployed-types": case "deployed-types":
action := fmt.Sprintf("list types in registry %s", *type_registry) callService("types", "GET", "list deployed types", nil)
callService("types", "GET", action, nil)
case "deployed-instances": case "deployed-instances":
if len(args) < 2 { if len(args) < 2 {
fmt.Fprintln(os.Stderr, "No type name supplied") fmt.Fprintln(os.Stderr, "No type name supplied")
...@@ -158,7 +166,7 @@ func main() { ...@@ -158,7 +166,7 @@ func main() {
} }
path := fmt.Sprintf("types/%s/instances", url.QueryEscape(args[1])) path := fmt.Sprintf("types/%s/instances", url.QueryEscape(args[1]))
action := fmt.Sprintf("list instances of type %s in registry %s", args[1], *type_registry) action := fmt.Sprintf("list deployed instances of type %s", args[1])
callService(path, "GET", action, nil) callService(path, "GET", action, nil)
default: default:
usage() usage()
...@@ -193,7 +201,7 @@ func loadTemplate(args []string) *expander.Template { ...@@ -193,7 +201,7 @@ func loadTemplate(args []string) *expander.Template {
var template *expander.Template var template *expander.Template
var err error var err error
if len(args) < 2 { if len(args) < 2 {
fmt.Fprintln(os.Stderr, "No type name or template file(s) supplied") fmt.Fprintln(os.Stderr, "No template name or configuration(s) supplied")
usage() usage()
} }
...@@ -208,7 +216,7 @@ func loadTemplate(args []string) *expander.Template { ...@@ -208,7 +216,7 @@ func loadTemplate(args []string) *expander.Template {
} }
if err != nil { if err != nil {
log.Fatalf("cannot create template from supplied arguments: %s\n", err) log.Fatalf("cannot create configuration from supplied arguments: %s\n", err)
} }
return template return template
...@@ -275,7 +283,7 @@ func buildTemplateFromType(name string, t registry.Type) *expander.Template { ...@@ -275,7 +283,7 @@ func buildTemplateFromType(name string, t registry.Type) *expander.Template {
func marshalTemplate(template *expander.Template) io.ReadCloser { func marshalTemplate(template *expander.Template) io.ReadCloser {
j, err := json.Marshal(template) j, err := json.Marshal(template)
if err != nil { if err != nil {
log.Fatalf("cannot deploy template %s: %s\n", template.Name, err) log.Fatalf("cannot deploy configuration %s: %s\n", template.Name, err)
} }
return ioutil.NopCloser(bytes.NewReader(j)) return ioutil.NopCloser(bytes.NewReader(j))
......
resources: resources:
- name: expandybird - name: expandybird
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/replicatedservice/v1/replicatedservice.py type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/replicatedservice/v1/replicatedservice.py
properties: properties:
service_port: 8081 service_port: 8081
target_port: 8080 target_port: 8080
...@@ -11,7 +11,7 @@ resources: ...@@ -11,7 +11,7 @@ resources:
labels: labels:
app: dm app: dm
- name: resourcifier - name: resourcifier
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/replicatedservice/v1/replicatedservice.py type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/replicatedservice/v1/replicatedservice.py
properties: properties:
service_port: 8082 service_port: 8082
target_port: 8080 target_port: 8080
...@@ -22,7 +22,7 @@ resources: ...@@ -22,7 +22,7 @@ resources:
labels: labels:
app: dm app: dm
- name: manager - name: manager
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/replicatedservice/v1/replicatedservice.py type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/replicatedservice/v1/replicatedservice.py
properties: properties:
service_port: 8080 service_port: 8080
target_port: 8080 target_port: 8080
......
...@@ -97,7 +97,7 @@ resources: ...@@ -97,7 +97,7 @@ resources:
### Displaying types ### Displaying types
You can see both the both primitive types and the templates you deployed to the You can see both the both primitive types and the templates you've deployed to the
cluster using the `deployed-types` command: cluster using the `deployed-types` command:
``` ```
......
resources: resources:
- name: frontend - name: frontend
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/replicatedservice/v1/replicatedservice.py type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/replicatedservice/v1/replicatedservice.py
properties: properties:
service_port: 80 service_port: 80
container_port: 80 container_port: 80
...@@ -8,5 +8,5 @@ resources: ...@@ -8,5 +8,5 @@ resources:
replicas: 3 replicas: 3
image: gcr.io/google_containers/example-guestbook-php-redis:v3 image: gcr.io/google_containers/example-guestbook-php-redis:v3
- name: redis - name: redis
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/redis/v1/redis.jinja type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/redis/v1/redis.jinja
properties: null properties: null
...@@ -24,7 +24,7 @@ import ( ...@@ -24,7 +24,7 @@ import (
const invalidFileName = "afilethatdoesnotexist" const invalidFileName = "afilethatdoesnotexist"
var importFileNames = []string{ var importFileNames = []string{
"../test/replicatedservice.py", "../../templates/replicatedservice/v1/replicatedservice.py",
} }
var outputFileName = "../test/ExpectedOutput.yaml" var outputFileName = "../test/ExpectedOutput.yaml"
......
...@@ -65,7 +65,7 @@ const ( ...@@ -65,7 +65,7 @@ const (
) )
var importFileNames = []string{ var importFileNames = []string{
"../test/replicatedservice.py", "../../templates/replicatedservice/v1/replicatedservice.py",
} }
type ServiceWrapperTestCase struct { type ServiceWrapperTestCase struct {
......
...@@ -21,7 +21,6 @@ config: ...@@ -21,7 +21,6 @@ config:
labels: labels:
app: expandybird app: expandybird
name: expandybird-service name: expandybird-service
name: expandybird-service
namespace: default namespace: default
spec: spec:
ports: ports:
...@@ -30,7 +29,6 @@ config: ...@@ -30,7 +29,6 @@ config:
targetPort: 8080 targetPort: 8080
selector: selector:
app: expandybird app: expandybird
name: expandybird
type: LoadBalancer type: LoadBalancer
type: Service type: Service
- name: expandybird-rc - name: expandybird-rc
...@@ -41,21 +39,19 @@ config: ...@@ -41,21 +39,19 @@ config:
labels: labels:
app: expandybird app: expandybird
name: expandybird-rc name: expandybird-rc
name: expandybird-rc
namespace: default namespace: default
spec: spec:
replicas: 3 replicas: 3
selector: selector:
app: expandybird app: expandybird
name: expandybird
template: template:
metadata: metadata:
labels: labels:
app: expandybird app: expandybird
name: expandybird
spec: spec:
containers: containers:
- image: b.gcr.io/dm-k8s-testing/expandybird - env: []
image: b.gcr.io/dm-k8s-testing/expandybird
name: expandybird name: expandybird
ports: ports:
- containerPort: 8080 - containerPort: 8080
......
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
######################################################################
"""Defines a ReplicatedService type by creating both a Service and an RC.
This module creates a typical abstraction for running a service in a
Kubernetes cluster, namely a replication controller and a service packaged
together into a single unit.
"""
import yaml
SERVICE_TYPE_COLLECTION = 'Service'
RC_TYPE_COLLECTION = 'ReplicationController'
def GenerateConfig(context):
"""Generates a Replication Controller and a matching Service.
Args:
context: Template context, which can contain the following properties:
container_name - Name to use for container. If omitted, name is
used.
namespace - Namespace to create the resources in. If omitted,
'default' is used.
protocol - Protocol to use for the service
service_port - Port to use for the service
target_port - Target port for the service
container_port - Container port to use
replicas - Number of replicas to create in RC
image - Docker image to use for replicas. Required.
labels - labels to apply.
external_service - If set to true, enable external Load Balancer
Returns:
A Container Manifest as a YAML string.
"""
# YAML config that we're going to create for both RC & Service
config = {'resources': []}
name = context.env['name']
container_name = context.properties.get('container_name', name)
namespace = context.properties.get('namespace', 'default')
# Define things that the Service cares about
service_name = name + '-service'
service_type = SERVICE_TYPE_COLLECTION
# Define things that the Replication Controller (rc) cares about
rc_name = name + '-rc'
rc_type = RC_TYPE_COLLECTION
service = {
'name': service_name,
'type': service_type,
'properties': {
'apiVersion': 'v1',
'kind': 'Service',
'namespace': namespace,
'metadata': {
'name': service_name,
'labels': GenerateLabels(context, service_name),
},
'spec': {
'ports': [GenerateServicePorts(context, container_name)],
'selector': GenerateLabels(context, name)
}
}
}
set_up_external_lb = context.properties.get('external_service', None)
if set_up_external_lb:
service['properties']['spec']['type'] = 'LoadBalancer'
config['resources'].append(service)
rc = {
'name': rc_name,
'type': rc_type,
'properties': {
'apiVersion': 'v1',
'kind': 'ReplicationController',
'namespace': namespace,
'metadata': {
'name': rc_name,
'labels': GenerateLabels(context, rc_name),
},
'spec': {
'replicas': context.properties['replicas'],
'selector': GenerateLabels(context, name),
'template': {
'metadata': {
'labels': GenerateLabels(context, name),
},
'spec': {
'containers': [
{
'name': container_name,
'image': context.properties['image'],
'ports': [
{
'name': container_name,
'containerPort': context.properties['container_port'],
}
]
}
]
}
}
}
}
}
config['resources'].append(rc)
return yaml.dump(config)
# Generates labels either from the context.properties['labels'] or generates
# a default label 'name':name
def GenerateLabels(context, name):
"""Generates labels from context.properties['labels'] or creates default.
We make a deep copy of the context.properties['labels'] section to avoid
linking in the yaml document, which I believe reduces readability of the
expanded template. If no labels are given, generate a default 'name':name.
Args:
context: Template context, which can contain the following properties:
labels - Labels to generate
Returns:
A dict containing labels in a name:value format
"""
tmp_labels = context.properties.get('labels', None)
ret_labels = {'name': name}
if isinstance(tmp_labels, dict):
for key, value in tmp_labels.iteritems():
ret_labels[key] = value
return ret_labels
def GenerateServicePorts(context, name):
"""Generates a ports section for a service.
Args:
context: Template context, which can contain the following properties:
service_port - Port to use for the service
target_port - Target port for the service
protocol - Protocol to use.
Returns:
A dict containing a port definition
"""
service_port = context.properties.get('service_port', None)
target_port = context.properties.get('target_port', None)
protocol = context.properties.get('protocol')
ports = {}
if name:
ports['name'] = name
if service_port:
ports['port'] = service_port
if target_port:
ports['targetPort'] = target_port
if protocol:
ports['protocol'] = protocol
return ports
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
######################################################################
root: .
...@@ -24,14 +24,16 @@ import ( ...@@ -24,14 +24,16 @@ import (
type GithubRegistry struct { type GithubRegistry struct {
owner string owner string
repository string repository string
path string
client *github.Client client *github.Client
} }
// NewGithubRegistry creates a Registry that can be used to talk to github. // NewGithubRegistry creates a Registry that can be used to talk to github.
func NewGithubRegistry(owner string, repository string) *GithubRegistry { func NewGithubRegistry(owner, repository, path string) *GithubRegistry {
return &GithubRegistry{ return &GithubRegistry{
owner: owner, owner: owner,
repository: repository, repository: repository,
path: path,
client: github.NewClient(nil), client: github.NewClient(nil),
} }
} }
...@@ -39,19 +41,21 @@ func NewGithubRegistry(owner string, repository string) *GithubRegistry { ...@@ -39,19 +41,21 @@ func NewGithubRegistry(owner string, repository string) *GithubRegistry {
// List the types from the Registry. // List the types from the Registry.
func (g *GithubRegistry) List() ([]Type, error) { func (g *GithubRegistry) List() ([]Type, error) {
// First list all the types at the top level. // First list all the types at the top level.
types, err := g.getDirs(TypesDir) types, err := g.getDirs("")
if err != nil { if err != nil {
log.Printf("Failed to list types : %v", err) log.Printf("Failed to list templates: %v", err)
return nil, err return nil, err
} }
var retTypes []Type var retTypes []Type
for _, t := range types { for _, t := range types {
// Then we need to fetch the versions (directories for this type) // Then we need to fetch the versions (directories for this type)
versions, err := g.getDirs(TypesDir + "/" + t) versions, err := g.getDirs(t)
if err != nil { if err != nil {
log.Printf("Failed to fetch versions for type: %s", t) log.Printf("Failed to fetch versions for template: %s", t)
return nil, err return nil, err
} }
for _, v := range versions { for _, v := range versions {
retTypes = append(retTypes, Type{Name: t, Version: v}) retTypes = append(retTypes, Type{Name: t, Version: v})
} }
...@@ -62,9 +66,10 @@ func (g *GithubRegistry) List() ([]Type, error) { ...@@ -62,9 +66,10 @@ func (g *GithubRegistry) List() ([]Type, error) {
// GetURL fetches the download URL for a given Type and checks for existence of a schema file. // GetURL fetches the download URL for a given Type and checks for existence of a schema file.
func (g *GithubRegistry) GetURL(t Type) (string, error) { func (g *GithubRegistry) GetURL(t Type) (string, error) {
_, dc, _, err := g.client.Repositories.GetContents(g.owner, g.repository, TypesDir+"/"+t.Name+"/"+t.Version, nil) path := g.path + "/" + t.Name + "/" + t.Version
_, dc, _, err := g.client.Repositories.GetContents(g.owner, g.repository, path, nil)
if err != nil { if err != nil {
log.Printf("Failed to list types : %v", err) log.Printf("Failed to list versions at path: %s: %v", path, err)
return "", err return "", err
} }
var downloadURL, typeName, schemaName string var downloadURL, typeName, schemaName string
...@@ -80,25 +85,32 @@ func (g *GithubRegistry) GetURL(t Type) (string, error) { ...@@ -80,25 +85,32 @@ func (g *GithubRegistry) GetURL(t Type) (string, error) {
} }
} }
if downloadURL == "" { if downloadURL == "" {
return "", fmt.Errorf("Can not find type %s:%s", t.Name, t.Version) return "", fmt.Errorf("Can not find template %s:%s", t.Name, t.Version)
} }
if schemaName == typeName + ".schema" { if schemaName == typeName+".schema" {
return downloadURL, nil return downloadURL, nil
} }
return "", fmt.Errorf("Can not find schema for %s:%s, expected to find %s", t.Name, t.Version, typeName + ".schema") return "", fmt.Errorf("Can not find schema for %s:%s, expected to find %s", t.Name, t.Version, typeName+".schema")
} }
func (g *GithubRegistry) getDirs(dir string) ([]string, error) { func (g *GithubRegistry) getDirs(dir string) ([]string, error) {
_, dc, _, err := g.client.Repositories.GetContents(g.owner, g.repository, dir, nil) var path = g.path
if dir != "" {
path = g.path + "/" + dir
}
_, dc, _, err := g.client.Repositories.GetContents(g.owner, g.repository, path, nil)
if err != nil { if err != nil {
log.Printf("Failed to call ListRefs : %v", err) log.Printf("Failed to get contents at path: %s: %v", path, err)
return nil, err return nil, err
} }
var dirs []string var dirs []string
for _, entry := range dc { for _, entry := range dc {
if *entry.Type == "dir" { if *entry.Type == "dir" {
dirs = append(dirs, *entry.Name) dirs = append(dirs, *entry.Name)
} }
} }
return dirs, nil return dirs, nil
} }
...@@ -13,24 +13,27 @@ limitations under the License. ...@@ -13,24 +13,27 @@ limitations under the License.
package registry package registry
// Registry abstracts a types registry which holds types that can be // Registry abstracts a registry that holds templates, which can be
// used in a Deployment Manager configurations. A registry root must have // used in a Deployment Manager configurations. A registry root must be a
// a 'types' directory which contains all the available types. Each type // directory that contains all the available templates, one directory per
// then contains version directories which in turn contains all the files // template. Each template directory then contains version directories, each
// necessary for that version of the type. // of which in turn contains all the files necessary for that version of the
// For example a type registry holding two types: // template.
// redis v1 (implemented in jinja) // For example, a template registry containing two versions of redis
// replicatedservice v2 (implemented in python) // (implemented in jinja), and one version of replicatedservice (implemented
// would have a directory structure like so: // in python) would have a directory structure that looks something like this:
// /types/redis/v1 // /redis
// /v1
// redis.jinja // redis.jinja
// redis.jinja.schema // redis.jinja.schema
// /types/replicatedservice/v2 // /v2
// redis.jinja
// redis.jinja.schema
// /replicatedservice
// /v1
// replicatedservice.python // replicatedservice.python
// replicatedservice.python.schema // replicatedservice.python.schema
const TypesDir string = "types"
type Type struct { type Type struct {
Name string Name string
Version string Version string
...@@ -38,8 +41,8 @@ type Type struct { ...@@ -38,8 +41,8 @@ type Type struct {
// Registry abstracts type interactions. // Registry abstracts type interactions.
type Registry interface { type Registry interface {
// List all the types in the given registry // List all the templates at the given path
List() ([]Type, error) List() ([]Type, error)
// Get the download URL for a given type and version // Get the download URL for a given template and version
GetURL(t Type) (string, error) GetURL(t Type) (string, error)
} }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
resources: resources:
- name: redis-master - name: redis-master
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/replicatedservice/v1/replicatedservice.py type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/replicatedservice/v1/replicatedservice.py
properties: properties:
# This has to be overwritten since service names are hard coded in the code # This has to be overwritten since service names are hard coded in the code
service_name: redis-master service_name: redis-master
...@@ -15,7 +15,7 @@ resources: ...@@ -15,7 +15,7 @@ resources:
image: redis image: redis
- name: redis-slave - name: redis-slave
type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/types/replicatedservice/v1/replicatedservice.py type: https://raw.githubusercontent.com/kubernetes/deployment-manager/master/templates/replicatedservice/v1/replicatedservice.py
properties: properties:
# This has to be overwritten since service names are hard coded in the code # This has to be overwritten since service names are hard coded in the code
service_name: redis-slave service_name: redis-slave
......
######################################################################
# Copyright 2015 The Kubernetes Authors All rights reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
######################################################################
"""Defines a ReplicatedService type by creating both a Service and an RC. """Defines a ReplicatedService type by creating both a Service and an RC.
This module creates a typical abstraction for running a service in a This module creates a typical abstraction for running a service in a
......
Markdown is supported
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