Skip to content

Commit

Permalink
WIP implement deployments without Deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
ironcladlou committed Jan 5, 2015
1 parent ba96b08 commit 22e96cd
Show file tree
Hide file tree
Showing 18 changed files with 427 additions and 350 deletions.
9 changes: 5 additions & 4 deletions pkg/cmd/infra/deployer/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"

kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"

"github.com/openshift/origin/pkg/cmd/util"
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
deployapi "github.com/openshift/origin/pkg/deploy/api"
strategy "github.com/openshift/origin/pkg/deploy/strategy/recreate"
)

Expand Down Expand Up @@ -52,16 +53,16 @@ func NewCommandDeployer(name string) *cobra.Command {

// deploy starts the deployer
func deploy(cfg *config) error {
kClient, osClient, err := cfg.Config.Clients()
kClient, _, err := cfg.Config.Clients()
if err != nil {
return err
}
if len(cfg.DeploymentName) == 0 {
return errors.New("No deployment name was specified.")
}

var deployment *deployapi.Deployment
if deployment, err = osClient.Deployments(cfg.Namespace).Get(cfg.DeploymentName); err != nil {
var deployment *kapi.ReplicationController
if deployment, err = kClient.ReplicationControllers(cfg.Namespace).Get(cfg.DeploymentName); err != nil {
return err
}

Expand Down
20 changes: 17 additions & 3 deletions pkg/cmd/server/origin/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (c *MasterConfig) InstallAPI(container *restful.Container) []string {
oauthEtcd := oauthetcd.New(c.EtcdHelper)

deployConfigGenerator := &deployconfiggenerator.DeploymentConfigGenerator{
DeploymentInterface: deployEtcd,
DeploymentInterface: &clientDeploymentInterface{c.KubeClient},
DeploymentConfigInterface: deployEtcd,
ImageRepositoryInterface: imageEtcd,
}
Expand Down Expand Up @@ -367,13 +367,19 @@ func (c *MasterConfig) RunDeploymentController() {
}

func (c *MasterConfig) RunDeploymentConfigController() {
factory := deploycontrollerfactory.DeploymentConfigControllerFactory{Client: c.OSClient}
factory := deploycontrollerfactory.DeploymentConfigControllerFactory{
Client: c.OSClient,
KubeClient: c.KubeClient,
}
controller := factory.Create()
controller.Run()
}

func (c *MasterConfig) RunDeploymentConfigChangeController() {
factory := deploycontrollerfactory.DeploymentConfigChangeControllerFactory{Client: c.OSClient}
factory := deploycontrollerfactory.DeploymentConfigChangeControllerFactory{
Client: c.OSClient,
KubeClient: c.KubeClient,
}
controller := factory.Create()
controller.Run()
}
Expand Down Expand Up @@ -420,3 +426,11 @@ func (c ClientWebhookInterface) CreateBuild(namespace string, build *buildapi.Bu
func (c ClientWebhookInterface) GetBuildConfig(namespace, name string) (*buildapi.BuildConfig, error) {
return c.Client.BuildConfigs(namespace).Get(name)
}

type clientDeploymentInterface struct {
KubeClient kclient.Interface
}

func (c *clientDeploymentInterface) GetDeployment(ctx api.Context, id string) (*api.ReplicationController, error) {
return c.KubeClient.ReplicationControllers(api.Namespace(ctx)).Get(id)
}
8 changes: 5 additions & 3 deletions pkg/deploy/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ type DeploymentList struct {

// These constants represent annotation keys used for correlating objects related to deployments.
const (
DeploymentConfigAnnotation = "deploymentConfig"
DeploymentAnnotation = "deployment"
DeploymentPodAnnotation = "pod"
DeploymentConfigAnnotation = "deploymentConfig"
DeploymentAnnotation = "deployment"
DeploymentPodAnnotation = "pod"
DeploymentStatusAnnotation = "deploymentStatus"
DeploymentEncodedConfigAnnotation = "encodedDeploymentConfig"
// TODO: This is a workaround for upstream's lack of annotation support on PodTemplate. Once
// annotations are available on PodTemplate, audit this constant with the goal of removing it.
DeploymentLabel = "deployment"
Expand Down
8 changes: 5 additions & 3 deletions pkg/deploy/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,11 @@ type DeploymentList struct {

// These constants represent annotation keys used for correlating objects related to deployments.
const (
DeploymentConfigAnnotation = "deploymentConfig"
DeploymentAnnotation = "deployment"
DeploymentPodAnnotation = "pod"
DeploymentConfigAnnotation = "deploymentConfig"
DeploymentAnnotation = "deployment"
DeploymentPodAnnotation = "pod"
DeploymentStatusAnnotation = "deploymentStatus"
DeploymentEncodedConfigAnnotation = "encodedDeploymentConfig"
// TODO: This is a workaround for upstream's lack of annotation support on PodTemplate. Once
// annotations are available on PodTemplate, audit this constant with the goal of removing it.
DeploymentLabel = "deployment"
Expand Down
15 changes: 10 additions & 5 deletions pkg/deploy/controller/config_change_controller.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package controller

import (
kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
cache "github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
util "github.com/GoogleCloudPlatform/kubernetes/pkg/util"

Expand Down Expand Up @@ -62,17 +63,21 @@ func (dc *DeploymentConfigChangeController) HandleDeploymentConfig() {
return
}

deployment := obj.(*deployapi.Deployment)
deployment := obj.(*kapi.ReplicationController)

if deployutil.PodSpecsEqual(config.Template.ControllerTemplate.Template.Spec, deployment.ControllerTemplate.Template.Spec) {
glog.V(4).Infof("Ignoring updated config %s with LatestVersion=%d because it matches deployment %s", config.Name, config.LatestVersion, deployment.Name)
return
if deployedConfig, err := deployutil.DecodeDeploymentConfig(deployment); err == nil {
if deployutil.PodSpecsEqual(config.Template.ControllerTemplate.Template.Spec, deployedConfig.Template.ControllerTemplate.Template.Spec) {
glog.V(4).Infof("Ignoring updated config %s with LatestVersion=%d because it matches deployed config %s", config.Name, config.LatestVersion, deployment.Name)
return
}
} else {
glog.V(0).Infof("Error decoding deploymentConfig from deployment %s: %v", deployment.Name, err)
}

dc.generateDeployment(config, deployment)
}

func (dc *DeploymentConfigChangeController) generateDeployment(config *deployapi.DeploymentConfig, deployment *deployapi.Deployment) {
func (dc *DeploymentConfigChangeController) generateDeployment(config *deployapi.DeploymentConfig, deployment *kapi.ReplicationController) {
newConfig, err := dc.ChangeStrategy.GenerateDeploymentConfig(config.Namespace, config.Name)
if err != nil {
glog.V(2).Infof("Error generating new version of deploymentConfig %v: %#v", config.Name, err)
Expand Down
45 changes: 18 additions & 27 deletions pkg/deploy/controller/config_change_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"testing"

kapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"

deployapi "github.com/openshift/origin/pkg/deploy/api"
deploytest "github.com/openshift/origin/pkg/deploy/controller/test"
deployutil "github.com/openshift/origin/pkg/deploy/util"
)

// Test the controller's response to a new DeploymentConfig with a config change trigger.
Expand Down Expand Up @@ -102,7 +104,7 @@ func TestChangeWithTemplateDiff(t *testing.T) {
NextDeploymentConfig: func() *deployapi.DeploymentConfig {
return diffedConfig()
},
DeploymentStore: deploytest.NewFakeDeploymentStore(matchingInitialDeployment()),
DeploymentStore: deploytest.NewFakeDeploymentStore(matchingInitialDeployment(generatedConfig())),
}

controller.HandleDeploymentConfig()
Expand All @@ -123,24 +125,25 @@ func TestChangeWithTemplateDiff(t *testing.T) {
}

func TestChangeWithoutTemplateDiff(t *testing.T) {
config := existingConfigWithTrigger()
generated := false
updated := false

controller := &DeploymentConfigChangeController{
ChangeStrategy: &testChangeStrategy{
GenerateDeploymentConfigFunc: func(namespace, name string) (*deployapi.DeploymentConfig, error) {
generated = true
return nil, nil
return config, nil
},
UpdateDeploymentConfigFunc: func(namespace string, config *deployapi.DeploymentConfig) (*deployapi.DeploymentConfig, error) {
updated = true
return config, nil
},
},
NextDeploymentConfig: func() *deployapi.DeploymentConfig {
return existingConfigWithTrigger()
return config
},
DeploymentStore: deploytest.NewFakeDeploymentStore(matchingInitialDeployment()),
DeploymentStore: deploytest.NewFakeDeploymentStore(matchingInitialDeployment(config)),
}

controller.HandleDeploymentConfig()
Expand Down Expand Up @@ -291,30 +294,18 @@ func generatedConfig() *deployapi.DeploymentConfig {
return config
}

func matchingInitialDeployment() *deployapi.Deployment {
return &deployapi.Deployment{
ObjectMeta: kapi.ObjectMeta{Name: "test-deploy-config-1"},
Status: deployapi.DeploymentStatusNew,
ControllerTemplate: kapi.ReplicationControllerSpec{
Replicas: 1,
Selector: map[string]string{
"name": "test-pod",
},
Template: &kapi.PodTemplateSpec{
ObjectMeta: kapi.ObjectMeta{
Labels: map[string]string{
"name": "test-pod",
},
},
Spec: kapi.PodSpec{
Containers: []kapi.Container{
{
Name: "container-1",
Image: "registry:8080/openshift/test-image:ref-1",
},
},
},
func matchingInitialDeployment(config *deployapi.DeploymentConfig) *kapi.ReplicationController {
encodedConfig, _ := deployutil.EncodeDeploymentConfig(config)

return &kapi.ReplicationController{
ObjectMeta: kapi.ObjectMeta{
Name: deployutil.LatestDeploymentIDForConfig(config),
Annotations: map[string]string{
deployapi.DeploymentConfigAnnotation: config.Name,
deployapi.DeploymentStatusAnnotation: string(deployapi.DeploymentStatusNew),
"encodedDeploymentConfig": encodedConfig,
},
},
Spec: config.Template.ControllerTemplate,
}
}
27 changes: 19 additions & 8 deletions pkg/deploy/controller/deployment_config_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ type DeploymentConfigController struct {

// dccDeploymentInterface is a small private interface for dealing with Deployments.
type dccDeploymentInterface interface {
GetDeployment(namespace, name string) (*deployapi.Deployment, error)
CreateDeployment(namespace string, deployment *deployapi.Deployment) (*deployapi.Deployment, error)
GetDeployment(namespace, name string) (*kapi.ReplicationController, error)
CreateDeployment(namespace string, deployment *kapi.ReplicationController) (*kapi.ReplicationController, error)
}

// Process DeploymentConfig events one at a time.
Expand Down Expand Up @@ -80,7 +80,7 @@ func (c *DeploymentConfigController) shouldDeploy(config *deployapi.DeploymentCo
}

// TODO: reduce code duplication between trigger and config controllers
func (c *DeploymentConfigController) latestDeploymentForConfig(config *deployapi.DeploymentConfig) (*deployapi.Deployment, error) {
func (c *DeploymentConfigController) latestDeploymentForConfig(config *deployapi.DeploymentConfig) (*kapi.ReplicationController, error) {
latestDeploymentID := deployutil.LatestDeploymentIDForConfig(config)
deployment, err := c.DeploymentInterface.GetDeployment(config.Namespace, latestDeploymentID)
if err != nil {
Expand All @@ -93,21 +93,32 @@ func (c *DeploymentConfigController) latestDeploymentForConfig(config *deployapi

// deploy performs the work of actually creating a Deployment from the given DeploymentConfig.
func (c *DeploymentConfigController) deploy(config *deployapi.DeploymentConfig) error {
deployment := &deployapi.Deployment{
var err error
var encodedConfig string

if encodedConfig, err = deployutil.EncodeDeploymentConfig(config); err != nil {
return err
}

deployment := &kapi.ReplicationController{
ObjectMeta: kapi.ObjectMeta{
Name: deployutil.LatestDeploymentIDForConfig(config),
Annotations: map[string]string{
deployapi.DeploymentConfigAnnotation: config.Name,
deployapi.DeploymentStatusAnnotation: string(deployapi.DeploymentStatusNew),
"encodedDeploymentConfig": encodedConfig,
},
Labels: config.Labels,
},
Strategy: config.Template.Strategy,
ControllerTemplate: config.Template.ControllerTemplate,
Details: config.Details,
Spec: config.Template.ControllerTemplate,
}

deployment.Spec.Replicas = 0
deployment.Spec.Template.Labels[deployapi.DeploymentConfigLabel] = config.Name
// TODO: Switch this to an annotation once upstream supports annotations on a PodTemplate
deployment.Spec.Template.Labels[deployapi.DeploymentLabel] = deployment.Name

glog.V(4).Infof("Creating new deployment from config %s", config.Name)
_, err := c.DeploymentInterface.CreateDeployment(config.Namespace, deployment)
_, err = c.DeploymentInterface.CreateDeployment(config.Namespace, deployment)
return err
}
Loading

0 comments on commit 22e96cd

Please sign in to comment.