Custom Container Delivery

    The default component type has more than 10 properties. Maybe your developer only needs to configure the image path and resource limits. For the other properties, the team could set the default values. If so, you could change the webservice definition.

    1. Change the UI schema to hide some fields

    On the definition detail page, users could customize the UI schema to setting the UI forms. For example, if you want to hide the ExposeType field, only need to set the disable is true.

    1. Change the definition and remove or add some fields

    If you want to completely remove or add some fields, you should edit the component definition.

    This guide should learn the CUE language.

    1. vela def get webservice > custom-webservice.cue

    Refer to the CUE Basic and documents to learn how to custom the custom-webservice.cue.

    After edit:

    Create a new component type to deploy the war package

    1. "java-war": {
    2. alias: ""
    3. annotations: {}
    4. attributes: {
    5. workload: {
    6. definition: {
    7. apiVersion: "apps/v1"
    8. kind: "Deployment"
    9. }
    10. type: "deployments.apps"
    11. }
    12. status: {
    13. customStatus: #"""
    14. ready: {
    15. readyReplicas: *0 | int
    16. } & {
    17. if context.output.status.readyReplicas != _|_ {
    18. readyReplicas: context.output.status.readyReplicas
    19. }
    20. }
    21. message: "Ready:\(ready.readyReplicas)/\(context.output.spec.replicas)"
    22. """#
    23. healthPolicy: #"""
    24. ready: {
    25. updatedReplicas: *0 | int
    26. readyReplicas: *0 | int
    27. replicas: *0 | int
    28. observedGeneration: *0 | int
    29. } & {
    30. if context.output.status.updatedReplicas != _|_ {
    31. updatedReplicas: context.output.status.updatedReplicas
    32. }
    33. if context.output.status.readyReplicas != _|_ {
    34. readyReplicas: context.output.status.readyReplicas
    35. }
    36. if context.output.status.replicas != _|_ {
    37. replicas: context.output.status.replicas
    38. }
    39. if context.output.status.observedGeneration != _|_ {
    40. observedGeneration: context.output.status.observedGeneration
    41. }
    42. }
    43. isHealth: (context.output.spec.replicas == ready.readyReplicas) && (context.output.spec.replicas == ready.updatedReplicas) && (context.output.spec.replicas == ready.replicas) && (ready.observedGeneration == context.output.metadata.generation || ready.observedGeneration > context.output.metadata.generation)
    44. """#
    45. }
    46. }
    47. description: ""
    48. labels: {}
    49. type: "component"
    50. }
    51. template: {
    52. output: {
    53. apiVersion: "apps/v1"
    54. kind: "Deployment"
    55. metadata: {
    56. name: context.name
    57. namespace: context.namespace
    58. }
    59. spec: {
    60. replicas: parameter.replicas
    61. selector: {
    62. matchLabels: {
    63. "app.oam.dev/component": context.name
    64. }
    65. }
    66. template: {
    67. metadata: {
    68. labels: {
    69. "app.oam.dev/name": context.appName
    70. "app.oam.dev/component": context.name
    71. "app.oam.dev/revision": context.revision
    72. }
    73. spec: {
    74. initContainers: [{
    75. name: "prepare-war"
    76. image: "busybox"
    77. if parameter["deployToRoot"] != _|_ {
    78. if parameter["deployToRoot"] {
    79. command: ["wget", "-O", "/usr/local/tomcat/webapps/ROOT.war", parameter["warURL"]]
    80. }
    81. }
    82. if parameter["deployToRoot"] == _|_ {
    83. command: ["wget", "-P", "/usr/local/tomcat/webapps/", parameter["warURL"]]
    84. }
    85. volumeMounts: [{
    86. name: "webapps"
    87. mountPath: "/usr/local/tomcat/webapps"
    88. }]
    89. }]
    90. containers: [{
    91. name: context.name
    92. image: "tomcat:" + parameter["envVersion"]
    93. if parameter["cpu"] != _|_ {
    94. resources: {
    95. limits: cpu: parameter.cpu
    96. requests: cpu: parameter.cpu
    97. }
    98. }
    99. if parameter["memory"] != _|_ {
    100. resources: {
    101. limits: memory: parameter.memory
    102. requests: memory: parameter.memory
    103. }
    104. }
    105. ports: [{
    106. containerPort: 8080
    107. name: "webapp"
    108. }]
    109. _envs: {
    110. custom: *parameter["env"] | []
    111. inner: [
    112. if parameter["javaOpts"] != _|_ {
    113. {
    114. name: "JAVA_OPTS"
    115. value: parameter.javaOpts
    116. }
    117. },
    118. ]
    119. }
    120. env: _envs.custom + _envs.inner
    121. volumeMounts: [{
    122. name: "webapps"
    123. mountPath: "/usr/local/tomcat/webapps"
    124. }]
    125. }]
    126. volumes: [{
    127. name: "webapps"
    128. emptyDir: {}
    129. }]
    130. }
    131. }
    132. }
    133. }
    134. outputs: {
    135. services: {
    136. kind: "Service"
    137. apiVersion: "v1"
    138. metadata: {
    139. name: context.name
    140. namespace: context.namespace
    141. }
    142. spec: {
    143. selector: "app.oam.dev/component": context.name
    144. ports: [{
    145. port: 8080
    146. }]
    147. type: "ClusterIP"
    148. }
    149. }
    150. parameter: {
    151. // +usage=The URL of the war package.
    152. warURL: string
    153. // +usage=Select a environment version([tomcat version]-[jdk version])
    154. envVersion: *"8-jdk8" | "9-jdk8" | "10-jdk8" | "8-jdk11" | "9-jdk11" | "10-jdk11" | "8-jdk17" | "9-jdk17" | "10-jdk17"
    155. // +usage=Specifies the number of replicas.
    156. replicas: *1 | int
    157. // +usage=Define arguments by using environment variables
    158. env?: [...{
    159. name: string
    160. value?: string
    161. }]
    162. // +usage=Setting the Java Opts configuration.
    163. javaOpts?: string
    164. // +usage=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
    165. cpu?: string
    166. // +usage=Specifies the attributes of the memory resource required for the container.
    167. memory?: =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"
    168. deployToRoot?: bool
    169. }
    170. }

    Copy the definition and create a file java-war.cue, then:

    Now, other developers could create the application with a war URL, for example:

    1. apiVersion: core.oam.dev/v1beta1
    2. kind: Application
    3. metadata:
    4. name: nanoservice
    5. namespace: e2e-test
    6. spec:
    7. components:
    8. - name: catalog
    9. properties:
    10. envVersion: 8-jdk8
    11. replicas: 1
    12. warURL: https://static.kubevela.net/example/java-example/nanoservice/catalog.war
    13. type: java-war
    14. - name: customer
    15. properties:
    16. envVersion: 8-jdk8
    17. replicas: 1
    18. warURL: https://static.kubevela.net/example/java-example/nanoservice/customer.war
    19. type: java-war
    20. - dependsOn:
    21. - catalog
    22. - customer
    23. name: order
    24. properties:
    25. env:
    26. - name: CATALOG_HOST
    27. value: catalog
    28. - name: CUSTOMER_HOST
    29. value: customer
    30. envVersion: 8-jdk8
    31. javaOpts: -Xms512m -Xmx512m -Xss256K
    32. replicas: 1
    33. warURL: https://static.kubevela.net/example/java-example/nanoservice/order.war
    34. traits:
    35. - properties:
    36. domains:
    37. - nanoservice.beijing.kubevela.net
    38. rules:
    39. - path:
    40. type: PathPrefix
    41. value: /order
    42. port: 8080
    43. type: http-route
    44. type: java-war
    45. policies:
    46. - name: e2e-test
    47. properties:
    48. clusters:
    49. - local
    50. namespace: e2e-test
    51. type: topology
    52. workflow:
    53. steps:
    54. - name: deploy2-e2e-test
    55. properties:
    56. policies:

    java-app

    This example includes three components, and the order service depends on the catalog and the customer services. The developer only needs to care about the war package URL and the tomcat/JRE version, they are familiar to the Java developer. The developer should upload the war package to a repository, such as Jfrog. Get a download URL to assign to the warURL field.