Version: v1.8

Dry Run

The dry run feature is a very useful way to check the correctness of the application configuration and definitions. It will render the application and print the output resources that checked on the service side. If the definitions(component, trait) is invalid, the dry run will print the error message.

When you do the following things, you’d better use dry-run.

  • Create or update an application.
  • Create or update the definition, and dry run some example applications.

There is a simple application:

  1. kind: Application
  2. apiVersion: core.oam.dev/v1beta1
  3. metadata:
  4. name: webservice-app
  5. spec:
  6. components:
  7. - name: frontend
  8. type: webservice
  9. properties:
  10. image: oamdev/testapp:v1
  11. cmd: ["node", "server.js"]
  12. ports:
  13. - port: 8080
  14. expose: true
  15. traits:
  16. - type: scaler
  17. properties:
  18. replicas: 1

Copy it and write a file app.yaml, execute the following command, and then the resources will be printed.

  1. vela dry-run app.yaml

expected output

  1. ---
  2. # Application(webservice-app) -- Component(frontend)
  3. ---
  4. apiVersion: apps/v1
  5. kind: Deployment
  6. metadata:
  7. annotations: {}
  8. labels:
  9. app.oam.dev/appRevision: ""
  10. app.oam.dev/component: frontend
  11. app.oam.dev/name: webservice-app
  12. app.oam.dev/namespace: default
  13. app.oam.dev/resourceType: WORKLOAD
  14. workload.oam.dev/type: webservice
  15. name: frontend
  16. namespace: default
  17. spec:
  18. replicas: 1
  19. selector:
  20. matchLabels:
  21. app.oam.dev/component: frontend
  22. template:
  23. metadata:
  24. labels:
  25. app.oam.dev/component: frontend
  26. app.oam.dev/name: webservice-app
  27. spec:
  28. containers:
  29. - command:
  30. - node
  31. - server.js
  32. image: oamdev/testapp:v1
  33. name: frontend
  34. ports:
  35. - containerPort: 8080
  36. name: port-8080
  37. protocol: TCP
  38. ---
  39. ## From the auxiliary workload
  40. apiVersion: v1
  41. kind: Service
  42. metadata:
  43. annotations: {}
  44. labels:
  45. app.oam.dev/appRevision: ""
  46. app.oam.dev/component: frontend
  47. app.oam.dev/name: webservice-app
  48. app.oam.dev/namespace: default
  49. app.oam.dev/resourceType: TRAIT
  50. trait.oam.dev/resource: webserviceExpose
  51. trait.oam.dev/type: AuxiliaryWorkload
  52. name: frontend
  53. namespace: default
  54. spec:
  55. ports:
  56. - name: port-8080
  57. port: 8080
  58. targetPort: 8080
  59. selector:
  60. app.oam.dev/component: frontend
  61. type: ClusterIP
  62. ---

If we set the expose field of the port as false, the output resources do not include the Service. If we set the replicas field as “1”, the output will be an error message:

  1. Error: validate application: ./app.yaml by dry-run: admission webhook "validating.core.oam.dev.v1beta1.applications" denied the request: field "schematic": Invalid value error encountered, cannot evaluate trait "scaler": invalid template of trait scaler after merge with parameter and context: parameter.replicas: conflicting values (*1 | int) and "1" (mismatched types int and string) (and 1 more errors).

This means the replicas field is int type but we provide a string value, this application configuration is not valid.

Dry Run - 图1tip

Override/topology Policies and deploy workflow are supported in v1.7.0+ now. While there’re still some limitation that dry-run with policy and workflow will only take override, topology policies and deploy workflow step into considerations. Other workflow steps will be ignored.

Let’s take the following application as example, the application explicitly specify override, topology policies and deploy workflow step.

  1. apiVersion: core.oam.dev/v1beta1
  2. kind: Application
  3. metadata:
  4. name: first-vela-app
  5. spec:
  6. components:
  7. - name: express-server
  8. type: webservice
  9. properties:
  10. image: oamdev/hello-world
  11. ports:
  12. - port: 8000
  13. expose: true
  14. traits:
  15. - type: scaler
  16. properties:
  17. replicas: 1
  18. policies:
  19. - name: target-default
  20. type: topology
  21. properties:
  22. clusters: ["local"]
  23. namespace: "default"
  24. - name: target-prod
  25. type: topology
  26. properties:
  27. clusters: ["local"]
  28. namespace: "prod"
  29. - name: deploy-ha
  30. type: override
  31. properties:
  32. components:
  33. - type: webservice
  34. traits:
  35. - type: scaler
  36. properties:
  37. replicas: 5
  38. workflow:
  39. steps:
  40. - name: deploy2default
  41. type: deploy
  42. properties:
  43. policies: ["target-default"]
  44. - name: manual-approval
  45. type: suspend
  46. - name: deploy2prod
  47. type: deploy
  48. properties:
  49. policies: ["target-prod", "deploy-ha"]

Dry run will produce rendered results for both deploy2default and deploy2prod deploy steps as below:

expected output

  1. ---
  2. # Application(first-vela-app with topology target-default) -- Component(express-server)
  3. ---
  4. apiVersion: apps/v1
  5. kind: Deployment
  6. metadata:
  7. annotations: {}
  8. labels:
  9. app.oam.dev/appRevision: ""
  10. app.oam.dev/component: express-server
  11. app.oam.dev/name: first-vela-app
  12. app.oam.dev/namespace: default
  13. app.oam.dev/resourceType: WORKLOAD
  14. workload.oam.dev/type: webservice
  15. name: express-server
  16. namespace: default
  17. spec:
  18. replicas: 1
  19. selector:
  20. matchLabels:
  21. app.oam.dev/component: express-server
  22. template:
  23. metadata:
  24. labels:
  25. app.oam.dev/component: express-server
  26. app.oam.dev/name: first-vela-app
  27. spec:
  28. containers:
  29. - image: oamdev/hello-world
  30. name: express-server
  31. ports:
  32. - containerPort: 8000
  33. name: port-8000
  34. protocol: TCP
  35. ---
  36. ## From the auxiliary workload
  37. apiVersion: v1
  38. kind: Service
  39. metadata:
  40. annotations: {}
  41. labels:
  42. app.oam.dev/appRevision: ""
  43. app.oam.dev/component: express-server
  44. app.oam.dev/name: first-vela-app
  45. app.oam.dev/namespace: default
  46. app.oam.dev/resourceType: TRAIT
  47. trait.oam.dev/resource: webserviceExpose
  48. trait.oam.dev/type: AuxiliaryWorkload
  49. name: express-server
  50. namespace: default
  51. spec:
  52. ports:
  53. - name: port-8000
  54. port: 8000
  55. targetPort: 8000
  56. selector:
  57. app.oam.dev/component: express-server
  58. type: ClusterIP
  59. ---
  60. ---
  61. # Application(first-vela-app with topology target-prod) -- Component(express-server)
  62. ---
  63. apiVersion: apps/v1
  64. kind: Deployment
  65. metadata:
  66. annotations: {}
  67. labels:
  68. app.oam.dev/appRevision: ""
  69. app.oam.dev/component: express-server
  70. app.oam.dev/name: first-vela-app
  71. app.oam.dev/namespace: default
  72. app.oam.dev/resourceType: WORKLOAD
  73. workload.oam.dev/type: webservice
  74. name: express-server
  75. namespace: default
  76. spec:
  77. replicas: 5
  78. selector:
  79. matchLabels:
  80. app.oam.dev/component: express-server
  81. template:
  82. metadata:
  83. labels:
  84. app.oam.dev/component: express-server
  85. app.oam.dev/name: first-vela-app
  86. spec:
  87. containers:
  88. - image: oamdev/hello-world
  89. name: express-server
  90. ports:
  91. - containerPort: 8000
  92. name: port-8000
  93. protocol: TCP
  94. ---
  95. ## From the auxiliary workload
  96. apiVersion: v1
  97. kind: Service
  98. metadata:
  99. annotations: {}
  100. labels:
  101. app.oam.dev/appRevision: ""
  102. app.oam.dev/component: express-server
  103. app.oam.dev/name: first-vela-app
  104. app.oam.dev/namespace: default
  105. app.oam.dev/resourceType: TRAIT
  106. trait.oam.dev/resource: webserviceExpose
  107. trait.oam.dev/type: AuxiliaryWorkload
  108. name: express-server
  109. namespace: default
  110. spec:
  111. ports:
  112. - name: port-8000
  113. port: 8000
  114. targetPort: 8000
  115. selector:
  116. app.oam.dev/component: express-server
  117. type: ClusterIP
  118. ---

Each deploy workflow step with topology policy will render individual result.

It can be a bit redundant for you as you may just need to dry run for one environment at a time. The, you can use the external workflow feature like below.

Firstly, define policy and workflow as below in individual files:

  • The target-prod.yaml and ha.yaml corresponding to the production environment.

    1. # target-prod.yaml
    2. apiVersion: core.oam.dev/v1alpha1
    3. kind: Policy
    4. metadata:
    5. name: target-prod
    6. type: topology
    7. properties:
    8. clusters: ["local"]
    9. namespace: "prod"
    1. # ha.yaml
    2. apiVersion: core.oam.dev/v1alpha1
    3. kind: Policy
    4. metadata:
    5. name: ha
    6. type: override
    7. properties:
    8. components:
    9. - type: webservice
    10. traits:
    11. - type: scaler
    12. properties:
    13. replicas: 5
  • The prod-workflow.yaml can glue them together.

    1. # prod-workflow.yaml
    2. apiVersion: core.oam.dev/v1alpha1
    3. kind: Workflow
    4. metadata:
    5. name: deploy-prod
    6. steps:
    7. - type: deploy
    8. name: deploy-prod
    9. properties:
    10. policies: ["ha", "target-prod"]
  • Then the application can reference the workflow as below.

    1. apiVersion: core.oam.dev/v1beta1
    2. kind: Application
    3. metadata:
    4. name: first-vela-app
    5. spec:
    6. components:
    7. - name: express-server
    8. type: webservice
    9. properties:
    10. image: oamdev/hello-world
    11. ports:
    12. - port: 8000
    13. expose: true
    14. traits:
    15. - type: scaler
    16. properties:
    17. replicas: 1
    18. workflow:
    19. ref: deploy-prod

The dry run command can be:

  1. vela dry-run -f app.yaml -f target-prod.yaml -f ha.yaml -f prod-workflow.yaml

Then, the dry-run results will only contain resources in the production environment.

expected output

  1. ---
  2. # Application(first-vela-app with topology target-prod) -- Component(express-server)
  3. ---
  4. apiVersion: apps/v1
  5. kind: Deployment
  6. metadata:
  7. annotations: {}
  8. labels:
  9. app.oam.dev/appRevision: ""
  10. app.oam.dev/component: express-server
  11. app.oam.dev/name: first-vela-app
  12. app.oam.dev/namespace: default
  13. app.oam.dev/resourceType: WORKLOAD
  14. workload.oam.dev/type: webservice
  15. name: express-server
  16. namespace: default
  17. spec:
  18. replicas: 5
  19. selector:
  20. matchLabels:
  21. app.oam.dev/component: express-server
  22. template:
  23. metadata:
  24. labels:
  25. app.oam.dev/component: express-server
  26. app.oam.dev/name: first-vela-app
  27. spec:
  28. containers:
  29. - image: oamdev/hello-world
  30. name: express-server
  31. ports:
  32. - containerPort: 8000
  33. name: port-8000
  34. protocol: TCP
  35. ---
  36. ## From the auxiliary workload
  37. apiVersion: v1
  38. kind: Service
  39. metadata:
  40. annotations: {}
  41. labels:
  42. app.oam.dev/appRevision: ""
  43. app.oam.dev/component: express-server
  44. app.oam.dev/name: first-vela-app
  45. app.oam.dev/namespace: default
  46. app.oam.dev/resourceType: TRAIT
  47. trait.oam.dev/resource: webserviceExpose
  48. trait.oam.dev/type: AuxiliaryWorkload
  49. name: express-server
  50. namespace: default
  51. spec:
  52. ports:
  53. - name: port-8000
  54. port: 8000
  55. targetPort: 8000
  56. selector:
  57. app.oam.dev/component: express-server
  58. type: ClusterIP
  59. ---

Moreover, you can use --merge flag to merge external policies and workflow when application file is not reference to them.

For example, you can define the application as below, the only difference is there’s no workflow field.

  1. # app.yaml
  2. apiVersion: core.oam.dev/v1beta1
  3. kind: Application
  4. metadata:
  5. name: first-vela-app
  6. spec:
  7. components:
  8. - name: express-server
  9. type: webservice
  10. properties:
  11. image: oamdev/hello-world
  12. ports:
  13. - port: 8000
  14. expose: true
  15. traits:
  16. - type: scaler
  17. properties:
  18. replicas: 1

the workflow and policy can be defined the same way

  1. # workflow.yaml
  2. apiVersion: core.oam.dev/v1alpha1
  3. kind: Workflow
  4. metadata:
  5. name: deploy-demo
  6. steps:
  7. - type: deploy
  8. name: deploy-prod
  9. properties:
  10. policies: ["target-prod"]
  1. # target-prod.yaml
  2. apiVersion: core.oam.dev/v1alpha1
  3. kind: Policy
  4. metadata:
  5. name: target-prod
  6. type: topology
  7. properties:
  8. clusters: ["local"]
  9. namespace: "prod"

If you don’t use --merge flag in this way, it will report warnings as below.

  1. vela dry-run -f app.yaml -f target-prod.yaml -f workflow.yaml

result with warning messages

  1. WARNING: workflow deploy-demo not referenced by application
  2. WARNING: policy target-prod not referenced by application
  3. ---
  4. # Application(default) -- Component(express-server)
  5. ---
  6. apiVersion: apps/v1
  7. kind: Deployment
  8. metadata:
  9. annotations: {}
  10. labels:
  11. app.oam.dev/appRevision: ""
  12. app.oam.dev/component: express-server
  13. app.oam.dev/name: first-vela-app
  14. app.oam.dev/namespace: default
  15. app.oam.dev/resourceType: WORKLOAD
  16. workload.oam.dev/type: webservice
  17. name: express-server
  18. namespace: default
  19. spec:
  20. replicas: 1
  21. selector:
  22. matchLabels:
  23. app.oam.dev/component: express-server
  24. template:
  25. metadata:
  26. labels:
  27. app.oam.dev/component: express-server
  28. app.oam.dev/name: first-vela-app
  29. spec:
  30. containers:
  31. - image: oamdev/hello-world
  32. name: express-server
  33. ports:
  34. - containerPort: 8000
  35. name: port-8000
  36. protocol: TCP
  37. ---
  38. ## From the auxiliary workload
  39. apiVersion: v1
  40. kind: Service
  41. metadata:
  42. annotations: {}
  43. labels:
  44. app.oam.dev/appRevision: ""
  45. app.oam.dev/component: express-server
  46. app.oam.dev/name: first-vela-app
  47. app.oam.dev/namespace: default
  48. app.oam.dev/resourceType: TRAIT
  49. trait.oam.dev/resource: webserviceExpose
  50. trait.oam.dev/type: AuxiliaryWorkload
  51. name: express-server
  52. namespace: default
  53. spec:
  54. ports:
  55. - name: port-8000
  56. port: 8000
  57. targetPort: 8000
  58. selector:
  59. app.oam.dev/component: express-server
  60. type: ClusterIP
  61. ---

In this case, the policy and workflow do not take effect. Because those are not referenced by the application and being viewed as standalone files and ignored.

So to make those external files work, please provide “—merge” flag as below:

  1. vela dry-run -f app.yaml -f target-prod.yaml -f workflow.yaml --merge

Then the application will be glued with external policies and workflows even no reference exists.

expected ouput

  1. ---
  2. # Application(first-vela-app with topology target-prod) -- Component(express-server)
  3. ---
  4. apiVersion: apps/v1
  5. kind: Deployment
  6. metadata:
  7. annotations: {}
  8. labels:
  9. app.oam.dev/appRevision: ""
  10. app.oam.dev/component: express-server
  11. app.oam.dev/name: first-vela-app
  12. app.oam.dev/namespace: default
  13. app.oam.dev/resourceType: WORKLOAD
  14. workload.oam.dev/type: webservice
  15. name: express-server
  16. namespace: default
  17. spec:
  18. replicas: 1
  19. selector:
  20. matchLabels:
  21. app.oam.dev/component: express-server
  22. template:
  23. metadata:
  24. labels:
  25. app.oam.dev/component: express-server
  26. app.oam.dev/name: first-vela-app
  27. spec:
  28. containers:
  29. - image: oamdev/hello-world
  30. name: express-server
  31. ports:
  32. - containerPort: 8000
  33. name: port-8000
  34. protocol: TCP
  35. ---
  36. ## From the auxiliary workload
  37. apiVersion: v1
  38. kind: Service
  39. metadata:
  40. annotations: {}
  41. labels:
  42. app.oam.dev/appRevision: ""
  43. app.oam.dev/component: express-server
  44. app.oam.dev/name: first-vela-app
  45. app.oam.dev/namespace: default
  46. app.oam.dev/resourceType: TRAIT
  47. trait.oam.dev/resource: webserviceExpose
  48. trait.oam.dev/type: AuxiliaryWorkload
  49. name: express-server
  50. namespace: default
  51. spec:
  52. ports:
  53. - name: port-8000
  54. port: 8000
  55. targetPort: 8000
  56. selector:
  57. app.oam.dev/component: express-server
  58. type: ClusterIP
  59. ---

You can refer to the Dry run command for more command line use cases.

dry-run

Clicking the Deploy button to open the workflow selector dialog. You could select a workflow(every workflow corresponding to an environment) and click the DryRun button to execute a dry run. If passed, the result is like this

dry-run-successfully

The result report is different from the CLI, there is a complete application configuration that is generated from the application metadata, you could check it. Different environments may have different application configurations.

Last updated on May 6, 2023 by Tianxin Dong