Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace.Next/Phase 1 - CheService/CheFeature model #9292

Closed
skabashnyuk opened this issue Mar 29, 2018 · 34 comments
Closed

Workspace.Next/Phase 1 - CheService/CheFeature model #9292

skabashnyuk opened this issue Mar 29, 2018 · 34 comments
Labels
kind/task Internal things, technical debt, and to-do tasks to be performed.

Comments

@skabashnyuk
Copy link
Contributor

Description

In this issue, I would like to discuss CheService/CheFeature model before we start to implement it.
tl4zjygm3dtzapa3iz9lfvdeoc51oc1smwj4vaeodjaw---4j4thyhigl_ozfzklpr5aps73u574l2v-b1a7cbrt-q2dqybywp6f1bnpzlb9u0e0cxn8dwarcssoy84gm8z5flynnvvyhjdo4mzxjb4vjdw85pvsdrcswrkmwrvojnn9itgehmzeh5ahaat14n_jnjfujtthfqptkbhqatwkgq5tm8bwfqtwxoyluc9-wv9y

Service Model

CheServices combines kubernetes Pods and Services to define servers running inside of containers. It can be referenced, for instance in features by name and version. A pod can define environment variables. Value of variables can be templated with ${VARIABLE_NAME} syntax. Value of variable can be combined in feature level. See more in feature description.
Service may specify Volumes in PodSpec and volumeMounts in ContainerSpec then infrastructure will provide PVC.
PodSpec#Volumes#persistentVolumeClaim#ClaimName will be used of Che volume identifier, and if two different services specify the same claim names, it means that they will use shared Che volume (PVC).
So, services should specify projects as claimName to mount Projects Sources. Another example is naming claim as m2 to mount ~/.m2 folder.

apiVersion: stable.che.eclipse.org/v1
kind: CheService
metadata:
 name: io.typefox.theia-ide.che-service
spec:
 services:
   - apiVersion: v1
     kind: Service
     metadata:
       name: io.typefox.theia-ide.che-service.mainservice
     spec:
       selector:
         app: theia
       ports:
       - protocol: TCP
         port: 80
         targetPort: 9376
 pods:
   - apiVersion: v1
     kind: Pod
     metadata:
       name: io.typefox.theia-ide.che-service.mainpod
     spec:
       selector:
         app: theia
       containers:
         - image: eclipse/che-theia:nightly
           labels:
             che.eclipse.org/container-name: theia-core
           name: theia
           env:
             - name: THEIA_PLUGINS
               value: ${THEIA_PLUGINS}
           volumeMounts:
             - mountPath: "/projects"
               name: projects   
         - image: maven:latest
           labels:
             che.eclipse.org/container-name: theia-maven-sidecar
           name: theia-sidecar
     volumes:
       - name: projects
         persistentVolumeClaim:
         claimName: projects
 commands:
   - apiVersion: stable.che.eclipse.org/v1
     kind: CheCommand
     metadata:
       name: mvn-clean
     spec:
       target-label-selector: "che.eclipse.org/container-name= theia-maven-sidecar"
       working-dir: "$(project)"
       command: ["mvn", "clean", "install"]   

Feature Model

A feature is a place where several CheSerivces are combining together. One of the goals of this combination is to combine sidecar services with UI part. In given example terminal side car org.eclipse.che.terminal:1.0.0 are combined with UI part provided by org.eclipse.che.terminal@latest plugin for io.typefox.theia-ide:2.1.5 service. There is a way to provide some parameter for CheServices on CheFeature level. In case if on Workspace level will be defined several CheFeature that are referencing the same service with the same parameter name, THEIA_PLUGINS in our case. That means that the value of this parameter will be concatenated in one string with comma separation and put as a value of placeholder in CheFeature. In our case values of THEIA_PLUGINS will be concatenated and put as environment variable of theia container.

apiVersion: v1
kind: CheFeature
metadata:
  name: theia-che-terminal
spec:
  version: 1.0.0
  description: Some meaningful description of Theia's terminal
  services:
    - name : org.eclipse.che.terminal
      version : 1.0.0
    - name : io.typefox.theia-ide
      version : 2.1.5
      parameters:
          - name: THEIA_PLUGINS
            value: org.eclipse.che.terminal@latest

Features as a part of Che6 workspace.

The first stage will combine che6 workspace and features. Also will teach Kubernetes/Openshift infrastructures to adjust workspace runtime with containers that come from features stored in workspace attributes.

{
  "environments": {
    "default": {
      "recipe": {
        "type": "dockerimage",
        "content": "eclipse/ubuntu_jdk8"
      }
    }
  },
  "defaultEnv": "default",
  "projects": [
    {
      "links": [],
      "name": "che",
      "attributes": {},
      "type": "maven",
      "source": {
        "location": "https://github.com/eclipse/che.git",
        "type": "git",
        "parameters": {}
      },
      "path": "/che",
      "problems": [],
      "mixins": []
    }
  ],
  "name": "wksp-large",
  "attributes":{
    "features":"features list"
  }
}
@skabashnyuk skabashnyuk added kind/task Internal things, technical debt, and to-do tasks to be performed. team/platform labels Mar 29, 2018
@skabashnyuk skabashnyuk mentioned this issue Mar 29, 2018
14 tasks
@garagatyi
Copy link

There are situations in which behavior of an infrastructure is not that clear to me. For example:

  • if CheService declares 2 pods and both declare project volume in it.
  • if Feature 1 declares service with a pod with the project volume and Feature 2 declares a service with a pod with the project volume.
  • If Feature 1 declares a k8s service with a name CoolService and Feature 2 declares a k8s service with the same name CoolService.
  • If a set of CheServices in a workspace declares 10 volumes and volume claims but an underlying k8s/OS system allows only 1 volume.

@skabashnyuk @sleshchenko @l0rd WDYT?

@skabashnyuk
Copy link
Contributor Author

skabashnyuk commented Apr 3, 2018

if CheService declares 2 pods and both declare project volume in it.

Fail. Do not allow to create CheService with 2 pods

if Feature 1 declares service with a pod with the project volume and Feature 2 declares a service with a pod with the project volume.

Shared project volume. We are going to merge pods from all features into one single pod.

If Feature 1 declares a k8s service with a name CoolService and Feature 2 declares a k8s service with the same name CoolService.

CoolService name has to be unique for a feature. like feature name. That means that Feature 1 and Feature 2 provides identical
functionality and they can't be run at the same time.

If a set of CheServices in a workspace declares 10 volumes and volume claims but an underlying k8s/OS system allows only 1 volume.

Thinking.

@garagatyi
Copy link

Shared project volume. We are going to merge pods from all features into one single pod.

I see, thank you for the explanation. I believe that it might be tricky with a lot of corner cases.

@skabashnyuk
Copy link
Contributor Author

Proposed api
2018-04-06 15 29 46

Swagger spec

swagger: '2.0'
info:
  description: Che Feature API
  version: 1.0.0
  title: Che Feature API
  contact:
    email: skabashniuk@redhat.com
  license:
    name: Eclipse Public License v1.0
    url: http://www.eclipse.org/legal/epl-v10.html
paths:
  /service:
    post:
      summary: Create a new CheService
      operationId: addCheService
      description: Create a new CheService
      consumes:
      - application/json
      - application/x-yaml
      produces:
      - application/json
      -  application/x-yaml
      parameters:
      - in: body
        name: CheServiceItem
        description: CheFeature item to add
        schema:
          $ref: '#/definitions/CheService'
      responses:
        201:
          description: The CheService successfully created
        400:
          description: Missed required parameters, parameters are not valid
        403:
          description: The user does not have access to create a new CheService  
        409:
          description: Conflict error occurred during the CheService creation(e.g. The CheService with such name and version already exists)
  /service/{name}:
    get:
      summary: Searches latest CheService by name
      operationId: getServiceByName
      description: Searches latest CheService by name
      parameters:
      - in: path
        name: name
        type: string
        required: true
        description: Numeric ID of the user to get.
      produces:
      -  application/x-yaml
      -  application/json
      responses:
        200:
          description: The CheService successfully fetched
          schema:
            $ref: '#/definitions/CheService'
        500:
          description: Internal server error occurred during CheService fetching
  /service/{name}/{version}:
    get:
      summary: Get CheService by name and version
      operationId: getServiceByNameAndVersion
      description: Get CheService by name and version
      parameters:
      - in: path
        name: name
        type: string
        required: true
        description: CheService name.
      - in: path
        name: version
        type: string
        required: true
        description: CheService version.  
      produces:
      -  application/x-yaml
      -  application/json
      responses:
        200:
          description: The CheService successfully fetched
          schema:
             $ref: '#/definitions/CheService'
        500:
          description: Internal server error occurred during CheService fetching
    delete:
      summary: Removes CheService by name and version
      operationId: deleteServiceByNameAndVersion
      description: Removes CheService by name and version
      parameters:
      - in: path
        name: name
        type: string
        required: true
        description: Service name.
      - in: path
        name: version
        type: string
        required: true
        description: Service version.  
      produces:
      -  application/x-yaml
      -  application/json
      responses:
        204:
          description: The CheService successfully removed
        403:
          description: The user does not have access to remove the CheService
        404:
          description: The CheService doesn't exist  
        500:
          description: Internal server error occurred        

  /feature:
    post:
      summary: Create a new CheFeature
      operationId: addFeature
      description: Create a new CheFeature
      consumes:
      - application/json
      - application/x-yaml
      produces:
      - application/json
      -  application/x-yaml
      parameters:
      - in: body
        name: CheFeatureItem
        description: CheFeature item to add
        schema:
          $ref: '#/definitions/CheFeature'
      responses:
        201:
          description: The CheFeature successfully created
        400:
          description: Missed required parameters, parameters are not valid
        403:
          description: The user does not have access to create a new CheFeature  
        409:
          description: Conflict error occurred during the CheFeature creation(e.g. The CheFeature with such name and version already exists)
  /feature/{name}:
    get:
      summary: Searches latest CheFeature by name
      operationId: searchFeatureByName
      description: Searches latest CheFeature by name
      parameters:
      - in: path
        name: name
        type: string
        required: true
        description: Numeric ID of the user to get.
      produces:
      -  application/x-yaml
      -  application/json
      responses:
        200:
          description: The CheFeature successfully fetched
          schema:
            $ref: '#/definitions/CheFeature'
        500:
          description: Internal server error occurred during CheFeature fetching   
  /feature/{name}/{version}:
    get:
      summary: Get CheFeature by name and version
      operationId: searchFeatureByNameAndVersion
      description: Get CheFeature by name and version
      parameters:
      - in: path
        name: name
        type: string
        required: true
        description: CheFeature name.
      - in: path
        name: version
        type: string
        required: true
        description: CheFeature version.  
      produces:
      -  application/x-yaml
      -  application/json
      responses:
        200:
          description: The CheFeature successfully fetched
          schema:
            $ref: '#/definitions/CheFeature'
        500:
          description: Internal server error occurred during CheFeature fetching
    delete:
      summary: Removes CheFeature by name and version
      operationId: deleteFeatureByNameAndVersion
      description: Removes CheFeature by name and version
      parameters:
      - in: path
        name: name
        type: string
        required: true
        description: CheFeature name.
      - in: path
        name: version
        type: string
        required: true
        description: CheFeature version.  
      produces:
      -  application/x-yaml
      -  application/json
      responses:
        204:
          description: The CheFeature successfully removed
        403:
          description: The user does not have access to remove the CheFeature
        404:
          description: The CheFeature doesn't exist  
        500:
          description: Internal server error occurred    
definitions:
  CheService:
    type: object
    required:
    - apiVersion
    - kind
    - metadata
    - spec
    properties:
      apiVersion:
        type: string
        example: che.eclipse.org/v1
      kind:
        type: string
        example: CheService
      metadata:
        $ref: '#/definitions/KubernetesObjectMeta'  
      spec:
        $ref: '#/definitions/CheServiceSpec'

  CheServiceSpec: 
    type: object
    required:
    - services
    - pods
    - commands
    - version
    properties:
      version:
        type: string
        example: 1.0.0
      services:
        type: array
        items:
          $ref: '#/definitions/Service'
      pods:
        type: array
        items:
          $ref: '#/definitions/Pod'
      commands:
        type: array
        items:
          $ref: '#/definitions/CheCommand'    
  Pod:
    type: object
    description: "Kubernetes Pod"
  Service:
    type: object 
    description: "Kubernetes Service"
  CheCommand:
    type: object
    required:
      - apiVersion
      - kind
      - metadata
      - spec
    properties:
      apiVersion:
        type: string
        example: che.eclipse.org/v1
      kind:
        type: string
        example: CheCommand
      metadata:
        $ref: '#/definitions/KubernetesObjectMeta'  
      spec:
        $ref: '#/definitions/CheCommandSpec'
        
  CheCommandSpec:
    type: object
    required: 
      - target-label-selector
      - working-dir
      - command
    properties:
      target-label-selector:
        type: string
        example: che.eclipse.org/container-name= theia-maven-sidecar
      working-dir:
        type: string
        example: $(project)
      command:
          type: array
          items:
            type: string
            example: "mvn"
  CheFeature:
    type: object
    required:
    - apiVersion
    - kind
    - metadata
    - spec
    properties:
      apiVersion:
        type: string
        example: che.eclipse.org/v1
      kind:
        type: string
        example: CheFeature
      metadata:
        $ref: '#/definitions/KubernetesObjectMeta'  
      spec:
        $ref: '#/definitions/CheFeatureSpec'
  CheFeatureSpec:
    type: object
    required: 
      - version
      - services
    properties:
      version:
        type: string
        example: 1.0.0
      services:
        type: array
        items:
          $ref: '#/definitions/CheServiceReference' 
  CheServiceReference:
    type: object 
    required:
      - name
      - version
      - parameters
    properties:
      name:
        type: string
        example: o.typefox.theia-ide.che-service.mainpod
      version:
        type: string
        example: 51.233
      services:
        type: array
        items:
          $ref: '#/definitions/CheServiceParameter'   
  CheServiceParameter:
    type: object 
    required:
      - name
      - value
    properties:
      name:
        type: string
        example: THEIA_PLUGINS
      value:
        type: string
        example: org.eclipse.che.terminal@latest     
  KubernetesObjectMeta:
    type: object 
    required:
      - name
    properties:
      name:
        type: string
        example: o.typefox.theia-ide.che-service.mainpod
      
# Added by API Auto Mocking Plugin
host: virtserver.swaggerhub.com
schemes:
 - https
basePath: /skabashniuk/Che/1.0.0

Live spec https://app.swaggerhub.com/apis/skabashniuk/Che/1.0.0

@garagatyi
Copy link

@skabashnyuk since the model contains a Pod concept which is not part of the Docker model do you want to get rid of support of Docker infrastructure in Che 7?

@skabashnyuk
Copy link
Contributor Author

As far as I understand @gorkem @l0rd @slemeur we are going to use Kuberenetes's Pod and Services
to define containers, volumes, ports and other necessary objects since the community is more familiar with it. however, that doesn't mean that we are going to use all features from Kuberenetes's Pod and Services. We may use a small subset of features like we are doing now with Compose support on Docker. I think during Phase one implementation we should keep in mind that in future we are going to add Docker support and not implement any features that are not possible to port to Docker.

@garagatyi
Copy link

I'm not concerned about all the features from k8s right now, but there is no concept of a POD in Docker. And in the suggested model it is a core object.
I have concerns regarding support of Docker infra if we use the suggested model.

@skabashnyuk
Copy link
Contributor Author

skabashnyuk commented Apr 11, 2018

In che6 model, we have no concept of Pod. We starting all containers in the same instance. We are going to continue in this way.

@garagatyi
Copy link

CheService specification based on the POD concept

  CheServiceSpec: 
...
      pods:
      type: array
          $ref: '#/definitions/Pod'
...
  Pod:
    type: object
    description: "Kubernetes Pod"
...

@skabashnyuk
Copy link
Contributor Author

skabashnyuk commented Apr 11, 2018

The rule of thumb for Phase 1 is - It must have a potential to run on Docker.
We should not use any features that only limited by kubernetes/OpenShift. Consider Pod and Service
only as a placeholder of information to define containers, networks, volumes, other things that we are using in che6 now.

@garagatyi
Copy link

OK. Thank you for the explanation. Let's figure this out after we have a POC.

@slemeur slemeur added kind/epic A long-lived, PM-driven feature request. Must include a checklist of items that must be completed. and removed kind/task Internal things, technical debt, and to-do tasks to be performed. labels Apr 11, 2018
@skabashnyuk
Copy link
Contributor Author

@slemeur I was planning to close this issue before the end of this sprint because it is dedicated only for initial discussing of phase 1 model. Next issues I was planning to create as part of #8265 issue

@benoitf
Copy link
Contributor

benoitf commented Apr 13, 2018

I've a question on 'feature' and API
How do we ensure we can't delete and then post a feature with the same version than the one deleted before ?

@skabashnyuk
Copy link
Contributor Author

Good question. Maybe we should deny items removal at all.
@benoitf @slemeur @gorkem wdyt?

@skabashnyuk
Copy link
Contributor Author

skabashnyuk commented Apr 13, 2018

After discussing with @sleshchenko @garagatyi we want to present such API https://app.swaggerhub.com/apis/skabashniuk/Che/1.0.0/swagger.yaml
ChangeLog:

  1. Removed GET /service/{name}
  2. Added GET /service
  3. Update Pod and Service object

2018-04-13 11 16 37

---
swagger: 2.0
info:
  description: Che Feature API
  version: 1.0.0
  title: Che Feature API
  contact:
    email: skabashniuk@redhat.com
  license:
    name: Eclipse Public License v1.0
    url: http://www.eclipse.org/legal/epl-v10.html
host: virtserver.swaggerhub.com
basePath: /skabashniuk/Che/1.0.0
schemes:
- https
paths:
  /service:
    get:
      summary: Searches CheService by list of ids
      description: Searches  CheService by list of ids, example ?id=io.typefox.theia-ide.che-service:1.2.3&org.eclipse.che.svn:4.2.3
      operationId: getServiceByIdList
      produces:
      - application/x-yaml
      - application/json
      parameters:
      - name: id
        in: query
        description: list if CheService ids.
        required: true
        type: array
        items:
          type: string
        collectionFormat: multi
      responses:
        200:
          description: The CheService successfully fetched
          schema:
            type: array
            items:
              $ref: '#/definitions/CheService'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
    post:
      summary: Create a new CheService
      description: Create a new CheService
      operationId: addCheService
      consumes:
      - application/json
      - application/x-yaml
      produces:
      - application/json
      - application/x-yaml
      parameters:
      - in: body
        name: CheServiceItem
        description: CheFeature item to add
        required: false
        schema:
          $ref: '#/definitions/CheService'
      responses:
        201:
          description: The CheService successfully created
          schema:
            $ref: '#/definitions/CheService'
        400:
          description: 400 Server receives invalid input parameter
          schema:
            $ref: '#/definitions/Error'
        403:
          description: 403 The user does not have access to update resource
          schema:
            $ref: '#/definitions/Error'
        409:
          description: 409 Operation could not be performed because of conflict with prior state.
          schema:
            $ref: '#/definitions/Error'
  /service/{name}/{version}:
    get:
      summary: Get CheService by name and version
      description: Get CheService by name and version
      operationId: getServiceByNameAndVersion
      produces:
      - application/x-yaml
      - application/json
      parameters:
      - name: name
        in: path
        description: CheService name.
        required: true
        type: string
      - name: version
        in: path
        description: CheService version.
        required: true
        type: string
      responses:
        200:
          description: The CheService successfully fetched
          schema:
            $ref: '#/definitions/CheService'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
    delete:
      summary: Removes CheService by name and version
      description: Removes CheService by name and version
      operationId: deleteServiceByNameAndVersion
      produces:
      - application/x-yaml
      - application/json
      parameters:
      - name: name
        in: path
        description: Service name.
        required: true
        type: string
      - name: version
        in: path
        description: Service version.
        required: true
        type: string
      responses:
        204:
          description: The CheService successfully removed
        403:
          description: 403 The user does not have access to update resource
          schema:
            $ref: '#/definitions/Error'
        404:
          description: 404 The specified resource was not found
          schema:
            $ref: '#/definitions/Error'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
  /feature:
    get:
      summary: Searches CheFeature by list of ids
      description: Searches CheFeature by list of ids. For example, ?id=io.typefox.theia-ide.che-service:1.2.3&org.eclipse.che.svn:4.2
      operationId: searchFeatureByListOfId
      produces:
      - application/x-yaml
      - application/json
      parameters:
      - name: id
        in: query
        description: list if CheService ids.
        required: true
        type: array
        items:
          type: string
        collectionFormat: multi
      responses:
        200:
          description: The CheFeature successfully fetched
          schema:
            type: array
            items:
              $ref: '#/definitions/CheFeature'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
    post:
      summary: Create a new CheFeature
      description: Create a new CheFeature
      operationId: addFeature
      consumes:
      - application/json
      - application/x-yaml
      produces:
      - application/json
      - application/x-yaml
      parameters:
      - in: body
        name: CheFeatureItem
        description: CheFeature item to add
        required: false
        schema:
          $ref: '#/definitions/CheFeature'
      responses:
        201:
          description: The CheFeature successfully created
          schema:
            $ref: '#/definitions/CheFeature'
        403:
          description: 403 The user does not have access to update resource
          schema:
            $ref: '#/definitions/Error'
        404:
          description: 404 The specified resource was not found
          schema:
            $ref: '#/definitions/Error'
        409:
          description: 409 Operation could not be performed because of conflict with prior state.
          schema:
            $ref: '#/definitions/Error'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
  /feature/{name}/{version}:
    get:
      summary: Get CheFeature by name and version
      description: Get CheFeature by name and version
      operationId: searchFeatureByNameAndVersion
      produces:
      - application/x-yaml
      - application/json
      parameters:
      - name: name
        in: path
        description: CheFeature name.
        required: true
        type: string
      - name: version
        in: path
        description: CheFeature version.
        required: true
        type: string
      responses:
        200:
          description: The CheFeature successfully fetched
          schema:
            $ref: '#/definitions/CheFeature'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
    delete:
      summary: Removes CheFeature by name and version
      description: Removes CheFeature by name and version
      operationId: deleteFeatureByNameAndVersion
      produces:
      - application/x-yaml
      - application/json
      parameters:
      - name: name
        in: path
        description: CheFeature name.
        required: true
        type: string
      - name: version
        in: path
        description: CheFeature version.
        required: true
        type: string
      responses:
        204:
          description: The CheFeature successfully removed
        403:
          description: 403 The user does not have access to update resource
          schema:
            $ref: '#/definitions/Error'
        404:
          description: 404 The specified resource was not found
          schema:
            $ref: '#/definitions/Error'
        409:
          description: 409 Operation could not be performed because of conflict with prior state.
          schema:
            $ref: '#/definitions/Error'
        500:
          description: 500 Internal server error occurred
          schema:
            $ref: '#/definitions/Error'
definitions:
  CheService:
    allOf:
    - $ref: '#/definitions/TypeMeta'
    - type: object
      required:
      - metadata
      - spec
      properties:
        metadata:
          $ref: '#/definitions/ObjectMeta'
        spec:
          $ref: '#/definitions/CheServiceSpec'
  CheServiceSpec:
    type: object
    required:
    - commands
    - pods
    - services
    - version
    properties:
      version:
        type: string
        example: 1.0.0
      services:
        type: array
        items:
          $ref: '#/definitions/Service'
      pods:
        type: array
        items:
          $ref: '#/definitions/Pod'
      commands:
        type: array
        items:
          $ref: '#/definitions/CheCommand'
  Pod:
    allOf:
    - $ref: '#/definitions/TypeMeta'
    - type: object
      required:
      - metadata
      - spec
      properties:
        metadata:
          $ref: '#/definitions/ObjectMeta'
        spec:
          $ref: '#/definitions/PodSpec'
    description: Pod is a collection of containers that can run on a host. This resource is created by clients and scheduled onto hosts.
  PodSpec:
    type: object
    required:
    - containers
    properties:
      containers:
        type: array
        description: List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.
        items:
          $ref: '#/definitions/Container'
      volumes:
        type: array
        description: 'List of volumes that can be mounted by containers belonging
          to the pod. '
        items:
          $ref: '#/definitions/Volume'
    description: PodSpec is a description of a pod.
  Volume:
    type: object
    required:
    - name
    properties:
      name:
        type: string
        description: 'Volume''s name. Must be a DNS_LABEL and unique within the pod.
          More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
      persistentVolumeClaim:
        description: PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace.
        $ref: '#/definitions/PersistentVolumeClaimVolumeSource'
    description: Volume represents a named volume in a pod that may be accessed by any container in the pod.
  PersistentVolumeClaimVolumeSource:
    required:
    - claimName
    properties:
      claimName:
        type: string
        description: 'ClaimName is the name of a PersistentVolumeClaim in the same
          namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims'
      readOnly:
        type: boolean
        description: Will force the ReadOnly setting in VolumeMounts. Default false.
    description: PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace. This volume finds the bound PV and mounts that volume for the pod. A PersistentVolumeClaimVolumeSource is, essentially, a wrapper around another type of volume that is owned by someone else (the system).
  Container:
    type: object
    required:
    - name
    properties:
      image:
        type: string
        description: 'Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images
          This field is optional to allow higher level config management to default
          or override container images in workload controllers like Deployments and
          StatefulSets.'
      name:
        type: string
        description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.
      env:
        type: array
        description: List of environment variables to set in the container. Cannot be updated.
        items:
          $ref: '#/definitions/EnvVar'
      volumeMounts:
        type: array
        description: Pod volumes to mount into the container's filesystem. Cannot be updated.
        items:
          $ref: '#/definitions/VolumeMount'
    description: A single application container that you want to run within a pod.
  VolumeMount:
    required:
    - mountPath
    - name
    properties:
      mountPath:
        type: string
        description: Path within the container at which the volume should be mounted.  Must not contain ':'.
      mountPropagation:
        type: string
        description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationHostToContainer is used. This field is alpha in 1.8 and can be reworked or removed in a future release.
      name:
        type: string
        description: This must match the Name of a Volume.
      readOnly:
        type: boolean
        description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.
      subPath:
        type: string
        description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root).
    description: VolumeMount describes a mounting of a Volume within a container.
  EnvVar:
    required:
    - name
    properties:
      name:
        type: string
        description: Name of the environment variable. Must be a C_IDENTIFIER.
      value:
        type: string
        description: 'Variable references $(VAR_NAME) are expanded using the previous
          defined environment variables in the container and any service environment
          variables. If a variable cannot be resolved, the reference in the input
          string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double
          $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless
          of whether the variable exists or not. Defaults to "".'
    description: EnvVar represents an environment variable present in a Container.
  Service:
    allOf:
    - $ref: '#/definitions/TypeMeta'
    - type: object
      required:
      - metadata
      - spec
      properties:
        metadata:
          $ref: '#/definitions/ObjectMeta'
        spec:
          $ref: '#/definitions/ServiceSpec'
  ServiceSpec:
    type: object
    properties:
      ports:
        type: array
        description: 'The list of ports that are exposed by this service. More info:
          https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies'
        items:
          $ref: '#/definitions/ServicePort'
      selector:
        type: object
        description: 'Route service traffic to pods with label keys and values matching
          this selector. If empty or not present, the service is assumed to have an
          external process managing its endpoints, which Kubernetes will not modify.
          Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
          type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/'
        additionalProperties:
          type: string
    description: ServiceSpec describes the attributes that a user creates on a service.
  ServicePort:
    required:
    - port
    properties:
      name:
        type: string
        description: The name of this port within the service. This must be a DNS_LABEL. All ports within a ServiceSpec must have unique names. This maps to the 'Name' field in EndpointPort objects. Optional if only one ServicePort is defined on this service.
      port:
        type: integer
        format: int32
        description: The port that will be exposed by this service.
      protocol:
        type: string
        description: The IP protocol for this port. Supports "TCP" and "UDP". Default is TCP.
      targetPort:
        type: string
        description: Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field.
    description: ServicePort contains information on service's port.
  CheCommand:
    allOf:
    - $ref: '#/definitions/TypeMeta'
    - type: object
      required:
      - metadata
      - spec
      properties:
        metadata:
          $ref: '#/definitions/ObjectMeta'
        spec:
          $ref: '#/definitions/CheCommandSpec'
  CheCommandSpec:
    type: object
    required:
    - command
    - target-label-selector
    - working-dir
    properties:
      target-label-selector:
        type: string
        example: che.eclipse.org/container-name= theia-maven-sidecar
      working-dir:
        type: string
        example: $(project)
      command:
        type: array
        items:
          type: string
          example: mvn
  CheFeature:
    allOf:
    - $ref: '#/definitions/TypeMeta'
    - type: object
      required:
      - metadata
      - spec
      properties:
        metadata:
          $ref: '#/definitions/ObjectMeta'
        spec:
          $ref: '#/definitions/CheFeatureSpec'
  CheFeatureSpec:
    type: object
    required:
    - services
    - version
    properties:
      version:
        type: string
        example: 1.0.0
      services:
        type: array
        items:
          $ref: '#/definitions/CheServiceReference'
  CheServiceReference:
    type: object
    required:
    - name
    - version
    properties:
      name:
        type: string
        example: o.typefox.theia-ide.che-service.mainpod
      version:
        type: string
        example: 51.233
      services:
        type: array
        items:
          $ref: '#/definitions/CheServiceParameter'
  CheServiceParameter:
    type: object
    required:
    - name
    - value
    properties:
      name:
        type: string
        example: THEIA_PLUGINS
      value:
        type: string
        example: org.eclipse.che.terminal@latest
  TypeMeta:
    type: object
    required:
    - apiVersion
    - kind
    properties:
      kind:
        type: string
        example: CheService
        description: Kind is a string value representing the REST resource this object represents.
      apiVersion:
        type: string
        example: che.eclipse.org/v1
        description: APIVersion defines the versioned schema of this representation of an object
  ObjectMeta:
    type: object
    required:
    - name
    properties:
      name:
        type: string
        example: org.eclipse.che.theia.git
        description: Object name. Name must be unique.
      labels:
        type: object
        description: 'Map of string keys and values that can be used to organize and
          categorize (scope and select) objects. May match selectors of replication
          controllers and services. More info: http://kubernetes.io/docs/user-guide/labels'
        additionalProperties:
          type: string
  Error:
    type: object
    required:
    - message
    properties:
      message:
        type: string
responses:
  BadRequestException:
    description: 400 Server receives invalid input parameter
    schema:
      $ref: '#/definitions/Error'
  ConflictException:
    description: 409 Operation could not be performed because of conflict with prior state.
    schema:
      $ref: '#/definitions/Error'
  ForbiddenException:
    description: 403 The user does not have access to update resource
    schema:
      $ref: '#/definitions/Error'
  NotFoundException:
    description: 404 The specified resource was not found
    schema:
      $ref: '#/definitions/Error'
  ServerException:
    description: 500 Internal server error occurred
    schema:
      $ref: '#/definitions/Error'

@slemeur
Copy link
Contributor

slemeur commented Apr 13, 2018

@skabashnyuk : Sounds good for creating the task on Implementation Phase1 under #8265.

On the feature removal question - should we think about a mechanism to deprecate a feature instead of removing it?

@skabashnyuk
Copy link
Contributor Author

@slemeur

@skabashnyuk : Sounds good for creating the task on Implementation Phase1 under #8265.

Done #9406

On the feature removal question - should we think about a mechanism to deprecate a feature instead of removing it?

Should we think - I gues yes. Should we concentrate I think no.
I suggest putting questions about adding, removing features, features storage in Phase 2 and more concentrate on methods how we are going to consume this features. For instance
how a user will select features? Will it be a list or a search form?
What if we have hundreds of different features?

My proposal

  1. Remove POST and DELETE methods for Phase 1. Instead, we are will put all features and services
    on hierarchy file system under git version control on GitHub.
  2. Depending on the way how a user will select features will add methods to search or get all features. Search is my preferred method.

@skabashnyuk skabashnyuk added kind/task Internal things, technical debt, and to-do tasks to be performed. and removed kind/epic A long-lived, PM-driven feature request. Must include a checklist of items that must be completed. labels Apr 13, 2018
@gorkem
Copy link
Contributor

gorkem commented Apr 13, 2018

Can we even remove a feature or a version of a feature that is in use by any of the workspaces? I think removal basically means you can not add it to new workspaces.

@skabashnyuk
Copy link
Contributor Author

I guess we can, however, it can be dangerous in term of backward compatibility support.

I like an idea of maven repository concept. Where artifacts can be added but they can't be removed
or updated. In this way, you always have a guarantee that your list of Che features can be run anytime
anywhere.

I think we should provide a nice UI with ability to select the latest version of features, but in
same time it should be technically possible to use all available feature versions.

@l0rd
Copy link
Contributor

l0rd commented Apr 23, 2018

We had discussion this morning on the drawbacks of current Service model in workspace.next. Here is a short summary of the issues found by @garagatyi (@skabashnyuk @davidfestal @sleshchenko participated to the discussion):

  1. In workspace.next model every services defines a distinct pod. But Che will run all the services in the same pod
    => Action item: define a new model that doesn’t match k8s model and make it clear that che model is distinct by k8s model (e.g. we don’t call something service if it’s not a k8s service)
  2. Names of different resources could match and we could have name conflicting problems (e.g. names of 2 containers of 2 distinct services could match)
    => Action item: we haven't found a good solution to that problem yet but we should update model to avoid as much as possible that service authors can put names to resources.
  3. If we defining everything as k8s resources users will expect that everything behaves as real k8s resources
    => Action item: point 1 should address that point too
  4. It is not clear how Che server will creates Routes/Ingress needed to expose services ports in workspace.next?
    => Services already defines external ports that should be exposed by routes/ingress
    => If a service needs to expose a port internally (the port should be available to other services but not externally) that port should not be defined in the definition of the service. This should work out of the box on k8s/openshift but may be an issue in docker. In this case the services containers should share the same networking namespace.
  5. Definition of volumes lacks the PVC to be 100% compatible with k8s
    => Action item: Point 1 should solve that
  6. When a client starts a workspace, with current API definition, it’s complicated to retrieve the full list of commands, in particular the commands defined at service level
    => Action item: Implement a command API to simplify how a client should start a workspace
  7. Labels should be validated/sanitized to avoid security exposures
  8. How should we set memory limits for services containers in k8s/openshift?
    => Action item: Add some service property to allow author of the service could specify the service limit. For services that don’t have a limit defined we should have some strategy to set it automatically.

@skabashnyuk
Copy link
Contributor Author

skabashnyuk commented Apr 24, 2018

We had a discussion wtith @l0rd @garagatyi @sleshchenko this morning about issues that we identified yesterday.

Here is a proposed concept of CheService object.

apiVersion: v1
kind: CheService
metadata:
  name: io.typefox.theia-ide.che-service
spec:
 version: 1.2.0 
 containers:
   - image: eclipse/che-theia:nightly
     resources:
       requests:
         memory:200Mi
     env:
       - name: THEIA_PLUGINS
         value: ${THEIA_PLUGINS}
     volumes:
       - mountPath: "/projects"
         name: projects   
     servers:
       - name: theia
          attributes:
             type: ide
             internal : true
          port: '3000'
          protocol: http
     commands:
       - name: build
         working-dir: "$(project)"
         command: ["mvn", "clean", "install"] 

Also, we identified that object name CheService, and field containers may be confusing for users since they can interfere with Kubernetes/Openshift Service and containers. Here is a couple of alternatives orderer on my taste

CheService:

  1. CheIdeService
  2. IdeService
  3. CheTool
  4. CheMachine

containers:

  1. che-containers,
  2. che-tools,
  3. che-machines,
  4. dev-tools,
  5. tools,
  6. instruments,
  7. ide-containers

Please feel free to vote or propose your alternative.

@garagatyi
Copy link

We can also call containers sidecars.
Regarding CheService. Using something without service word would be clearer in my opinion. But CheMachine looks irrelevant here because CheService may represent several containers. From the provided list I opt for the tool word. It may be CheTool or just Tool. So features would bring tools. Sounds good to me.

@garagatyi
Copy link

@skabashnyuk @l0rd WDYT?

@garagatyi
Copy link

Regarding points stated in Mario's last comment:
Point #2. We need to create some flow for accessing APIs deployed in the sidecars which should be clear (at least after reading docs) to the features developers and which we would be able to implement on different infrastructures.

Point #4. Not precisely about the topic from Mario's comment but still related. Right now we do NOT allow a user to use Routes/Ingresses in his k8s/OS recipes. I think it should be changed not to conflict with the Workspace.Next idea of full-blown user recipe in different formats and Che tooling. We can allow a user to use Routes/Ingresses and Servers would be just an additional way to publish a port to the world. In case of Docker infrastructure, we do not publish ports that implicitly came from Docker images but publish ports that are explicitly set in the WS recipe.

Point #5. Also just related to volumes, not the issue mentioned by Mario. Currently, we don't allow a user to use volumes in the recipe. We should reconsider this due to compliance with the Workspace.Next concept of a completely working user's recipes without customizing it for Che.

Point #6. Do we need a separate issue for this where we could discuss what we need to change?

@skabashnyuk @l0rd WDYT?

@l0rd
Copy link
Contributor

l0rd commented Apr 26, 2018

@garagatyi +1 about the renaming of services tools. I would say CheTool or even better IDETool. And then I would rename containers as ide-tool-containers or che-tool-containers.

@skabashnyuk
Copy link
Contributor Author

@garagatyi @l0rd I do like CheTool and che-tool-containers names because in theory, we can run without web-based IDE at all ( work over the shell tools).

@skabashnyuk
Copy link
Contributor Author

@slemeur @gorkem wdyt about renaming of CheService-> CheTool and containers -> che-tool-containers

@l0rd
Copy link
Contributor

l0rd commented Apr 26, 2018

Commenting the other points:

Point #2. We need to create some flow for accessing APIs deployed in the sidecars which should be clear (at least after reading docs) to the features developers and which we would be able to implement on different infrastructures.

I don't understand I am sorry. I read a couple of times your sentence but I can't get what you mean.

Point #4. Not precisely about the topic from Mario's comment but still related. Right now we do NOT allow a user to use Routes/Ingresses in his k8s/OS recipes. I think it should be changed not to conflict with the Workspace.Next idea of full-blown user recipe in different formats and Che tooling. We can allow a user to use Routes/Ingresses and Servers would be just an additional way to publish a port to the world. In case of Docker infrastructure, we do not publish ports that implicitly came from Docker images but publish ports that are explicitly set in the WS recipe.

Makes sense but we need to be careful with this. For instance we should not allow to specify the host and tls in OpenShift routes definitions.

Point #5. Also just related to volumes, not the issue mentioned by Mario. Currently, we don't allow a user to use volumes in the recipe. We should reconsider this due to compliance with the Workspace.Next concept of a completely working user's recipes without customizing it for Che.

Not sure about that. Docker volumes let you specify a host paths and this doesn't make sense in the cloud. In OpenShift and Kubernetes PV have a cost and are limited. So in this cases we can't guarantee the support for user defined volumes. We may improve the volume support in the future but I am not sure that we should do it with workspace.next.

Point #6. Do we need a separate issue for this where we could discuss what we need to change?

Yes don't hesitate to create one.

@l0rd
Copy link
Contributor

l0rd commented Apr 26, 2018

@garagatyi @l0rd I do like CheTool and che-tool-containers names because in theory, we can run without web-based IDE at all ( work over the shell tools).

@skabashnyuk CheTool makes me think at a tool for Che. And Che is a web IDE (at least that's the understanding of 99% of our users). Maybe DevTool? It's not web based and it's not graphical. And since it's not related to a particular IDE (Che) it's more appropriate to define a kubernetes custom resource that may be reused in different contexts (dev tools not only for Che but suitable for different IDEs or applications).

@garagatyi
Copy link

I don't understand I am sorry. I read a couple of times your sentence but I can't get what you mean.

I mean that we should describe how:

  • a tooling container can access a port of another tooling container
  • a tooling container can access a port of user's container
  • a port of a tooling container can be accessed from browser
    But it is not something we need to do right now. Just my thoughts regarding the issue.

Yes don't hesitate to create one.

#9546

@gorkem
Copy link
Contributor

gorkem commented Apr 26, 2018

Is the name CheTool visible to users or just the extension developers.?

@skabashnyuk
Copy link
Contributor Author

Is the name CheTool visible to users or just the extension developers.?

It is for extension developers. Users will work with CheFeature.

@skabashnyuk
Copy link
Contributor Author

@l0rd @gorkem
DevTool name is fine, however, I see it a bit inconsistent with other names. Like CheFeature
or ChePlugin (we discusses this object in Che marketplace flow). So I think, we should call them all like Che* or they all should not have this prefix. My proposal

  1. CheService -> CheTool, CheDevTool
  2. CheFeature
  3. ChePlugin

or

  1. CheService -> DevTool
  2. CheFeature -> Feature
  3. ChePlugin -> Plugin

@skabashnyuk
Copy link
Contributor Author

Discussed model implemented in this prototype https://github.com/skabashnyuk/kubsrv/
about names, I guess we need to create a separate issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/task Internal things, technical debt, and to-do tasks to be performed.
Projects
None yet
Development

No branches or pull requests

6 participants