[WIP] [DO NOT MERGE] - Deployment Rollbacks

## Description

Rollback is meant to be a temporary fix to an incorrect environment.  A rollback is movement of application from current deployed state to an approximation of a previous deployed state that was recorded  in the OpenShift system.  This includes system configuration (hooks, deployment strategies, etc) and application (template, images, environment variables).  

## Definitions

* Pod rollback: rollback that includes only ControllerTemplate items
* Process rollback: rollback that includes only labels, triggers, and Template.Strategy does not include ControllerTemplate items
* Full rollback: rollback of application and process
* Deployment: point in time in OpenShift that was created from a deployment config and is tagged in the format of <id>-<release number>
* Example: my-deployment-1, my-deployment-2

## Proposal Summary

* Offer rollbacks to deployment.  
* Rollbacks should be initiated via the CLI or web interface.  
* Rollbacks should be configurable to include deployment process and/or template.  See rollback configuration.  This allows the user to control which part of the deployment is rolled back.  Pod, deployment processes, or both.
* OpenShift cannot always prevent application specific inconsistencies, but it should work to communicate to users where possible that an inconsistency may occur
     * inconsistencies include database schemas that are not compatible with the rollback code, passwords that may have changed in the code, configuration differences in portions of distributed apps after rollback
* OpenShift should be able to intelligently validate rollback requests to prevent issues like rollbacks to non-existing images and other issues as much as possible.  This information should be presented in an easily digestible format (see dry run use case).

## Constraints

* Config changes in a distributed app may leave that app in an invalid state (see dry run use case).  This could occur if changes in the back end of an app occur before front end code changes.  For instance, a database schema change that is incompatible with the application code accessing the database. 
* Incompatible application changes like a new deployment that changes schemas are outside the scope of rollback validation since OpenShift does not have insight into application implementation details and how they relate to deployments.  In this case a new deployment with schema changes is dependent on an earlier state.

## Use Cases

1. **Rollback to Previous Deployment**
     1. User requests rollback but does not provide a named release
     1. System validates that rollback is possible to N-1
     1. System creates new deployment config

1. **Rollback to Specific Deployment**
     1. User requests rollback to a specific deployment (other than n-1).  This use case may occur when a user discovers a critical bug that has occurred in deployment n-x and immediate rollback is necessary.  
     1. System validates that rollback is possible
     1. System creates new deployment config

1. **Rollback Only Pod**
     1. User requests a rollback and specifies a rollback configuration that indicates only the pod definition is to be rolled back.
     1. System validates that rollback is possible
     1. System modifies the existing deployment config that includes all process items from the current deployment configuration and replaces the ControllerTemplate with the previous version

1. **Rollback Only Process**
     1. User requests a rollback and specifies a rollback configuration that indicates only the process is to be rolledback
     1. System validates that rollback is possible (in this case checking the deployment strategy image, no application images are changing)
     1. System creates a new deployment config that includes the ControllerTemplate from the current deployment configuration and replaces all other items with process definition from previous version

1. **Rollback With Unknown Incompatibilities**
     1. System performs rollback.  Application is left in an incompatible state
It is up to the application administrator to resolve incompatibilities

1. **Rollback With Known Incompatibilities**
     1. System does not rollback
     1. Application administrator is displayed a message as to why the rollback could not be completed

1. **Rollback Dry Run**
     1. User requests a rollback dry run
     1. System compares the current and proposed deployment configuration
     1. If the specified configuration includes selectors for other pods a comparison of environment variables is done by matching on variable names to find potential issues
     1. System details the changes to the user

## Use Case Justification

1. **Rollback to Previous Deployment** - This allows a user who notices an immediate break in the current deployment to revert to n-1.  This seems to be the most obvious use case for rollbacks when something goes wrong with the deployment

1. **Rollback to Specific Deployment** - Rolling back to a specific deployment would likely be required if a critical bug has been found, more deployments have occurred that were not substantial, and the bug must be eliminated as fast as possible.  This is probably a rare occurrence in production since most users would probably patch as a new deployment (n+1) but may be more common in development or test environments.  

1. **Rollback Only Pod** - Rolling back only the pod is the likely use case for most rollbacks.  This allows you to roll back the pod without rolling back any changes in the deployment process.  

1. **Rollback Only Process** - This use case occurs if you’ve made changes to the deployment process and the pod definitions but something failed during the deployment process.  This allows you to revert the process to a previously known working state but retain the current pod definition.  This use case is only necessary if a user has made a change to the deployment config that does not affect the template and they would like to roll back the change.  This is likely a rare use case.

1. **Rollback Dry Run** - allowing the user to discover known incompatibilities prior to entering the deployment process would help them avoid potential application downtime and correct the issues prior to a real deployment.  Incompatibilities are validations performed by OpenShift prior to the rollback.  See deployments.md for details on actual validations.

Quick link to implementation details added to deployments.md: https://github.com/pweil-/origin/blob/deployment-rollback-proposal/docs/deployments.md#proposed-design---rollbacks
After a quick review I realize that I didn't make it part of details since details is currently just holding status information and is written by the server.  I can put the rollback config in details but maybe it belongs in `DeploymentTemplate` instead since that holds the desired state.  Rollback is essentially just shorthand for a template definition in the desired state.  In the POC it would mean the config changes like this:  

     from:
     {
          "metadata": {"name":"frontend"},
          "kind":"DeploymentConfig",
          "rollback": { "to": "frontend-1" }
      }

     to:
     {
          "metadata": {"name":"frontend"},
          "kind":"DeploymentConfig",
          "template": { "rollback": { "to": "frontend-1" }}         
      }

Acceptable?