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

Feat: add step definitions to support deploying static site on OSS #5524

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

lunarwhite
Copy link
Contributor

@lunarwhite lunarwhite commented Feb 16, 2023

Description of your changes

Fixes #3898

I have:

  • Read and followed KubeVela's contribution process.
  • Related Docs updated properly. In a new feature or configuration option, an update to the documentation is necessary.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

Design of WorkflowStep

We design two workflow steps, mainly using cue actions to operate Kubernetes objects.

1 build-source-code.cue
  1. Init storage
    1. op.#Apply a PersistentVolumeClaim for a Job to mount
      • Specify PVC's name and storageClassName by the input parameter
      • storageClassName will specify which StorageClass that PVC will use
  2. Clone git repo, build source code, and persist generated files
    1. op.#Apply a Job
      • Mount the PVC and specify the claimName and mountPath
      • Using user-specified container image, execute user-specified commands to build
      • Get the recently generated folder and persist its files in mountPath
    2. op.#Log to collect Job's log using labelSelector
    3. op.#ConditionalWait for Job successfully created and executed
2 upload-to-bucket.cue
  1. Get the required credentials
    1. op.#Steps to combine a set of operations to get the accessKey(id and secret).
  2. Get files from PVC, and upload them to the object storage bucket
    1. op.#Apply a Job
      • Mount the PVC and specify the claimName and mountPath
      • In the container, it will prepare ossutils env first
      • And then config cloud provider with input parameters to get access
      • Clean the bucket first, then copy the static site files up to it
    2. op.#Log to collect Job's log using labelSelector
    3. op.#ConditionalWait for Job successfully created and executed

How has this code been tested

From the user's perspective, you can use these two workflow steps without any Components if you already have an OSS bucket ready to host a static site.

YAML example
apiVersion: core.oam.dev/v1beta1
kind: Application # or you can use WorkflowRun
metadata:
  name: test-build-and-upload
spec:
  components: []
  workflow:
    steps:
      - name: build
        type: build-source-code
        properties:
          image: node:14.17 # the base image where the source code is to be built
          cmd: "yarn install && yarn build" # the commands to build source code
          repo:
            url: https://github.com/open-gitops/website.git # repo's git URL
            branch: main # repo's branch, default to "master"
          pvc:
            name: my-pvc # the PVC name user want to apply
            storageClassName: my-storage # the StorageClass user want to use
            mountPath: /generated # the PVC mountPath user wants to persist in
      - name: upload
        type: upload-to-bucket
        properties:
          oss: # specify the Alibaba OSS bucket as backend storage
            accessKey: # the credentials to access Alibaba oss
              # User can either use `secretRef` to access the credentials or just use plaintext as input parameters `id` and `secret`.
              # id: <your_id>
              # secret: <your_secret>
              secretRef:
                name: my-secret
                keyId: ALICLOUD_ACCESS_KEY
                keySecret: ALICLOUD_SECRET_KEY
            bucket: opengitops-doc # the target OSS bucket
            endpoint: oss-cn-hangzhou.aliyuncs.com # the target OSS endpoint
          pvc: # the PVC to get generated files
            name: my-pvc
            mountPath: /generated

Or you can use them with the Component alibaba-oss-website to create an OSS bucket for you and config the static site setting. Don't forget to use inputs and outputs to pass data between workflow steps for simplification.

YAML example
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: beta
spec:
  components:
    - name: object-storage-service
      type: Alibaba-oss-website
      properties:
        bucket: opengitops-doc
        acl: public-read
        index_document: index.html
        error_document: 404.html
  workflow:
    steps:
      - name: create-bucket
        type: apply-component
        properties:
          component: oss-website
        outputs: # pass data between workflow steps
        - name: bucket
          valueFrom: output.status.apply.outputs.BUCKET_NAME.value
        - name: endpoint
          valueFrom: output.status.apply.outputs.EXTRANET_ENDPOINT.value
      - name: build
        type: build-source-code
        properties:
          image: node:14.17
          cmd: "yarn install && yarn build"
          repo:
            url: https://github.com/open-gitops/website.git
            branch: main
          pvc:
            name: my-pvc
            storageClassName: my-storage
            mountPath: /generated
      - name: upload
        type: upload-to-bucket
        inputs: # pass data between workflow steps
        - from: bucket 
          parameterKey: properties.oss.bucket
        - from: endpoint
          parameterKey: properties.oss.endpoint
        properties:
          oss:
            accessKey:
              # id: <your_id>
              # secret: <your_secret>
              secretRef:
                name: my-secret
                keyId: ALICLOUD_ACCESS_KEY
                keySecret: ALICLOUD_SECRET_KEY
          pvc:
            name: my-pvc
            mountPath: /generated

Special notes for your reviewer

Still WIP, I'll mark it ready to review if ready.

Followup works

  • Support Secrets mount
  • Add sufficient documents
  • Add annotations, labels field. like this
  • Optimize performance and resource
  • Generally stable and robust

Known issues

For security reasons, the policy for "accessing OSS static web page" had changed. When accessing the default domain name(https://{bucket_name}.oss-cn-hangzhou.aliyuncs.com) via browser, files will be downloaded as attachments, rather than previewed directly.

Source link

In this situation, the user should have a custom domain name in advance and bind it with the bucket. And it seems that the process needs the user to operate manually on the portal website.

In our original design(#3898 (comment)), "the endpoint should be printed after the whole process is finished". Now, the accessible endpoint is the user's domain name, it seems like the user doesn't need the default endpoint anymore.

Improvements outlook

Signed-off-by: Yuedong Wu <dwcn22@outlook.com>
@codecov
Copy link

codecov bot commented Feb 16, 2023

Codecov Report

Base: 61.33% // Head: 61.42% // Increases project coverage by +0.08% 🎉

Coverage data is based on head (dff414c) compared to base (e2ab8aa).
Patch has no changes to coverable lines.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5524      +/-   ##
==========================================
+ Coverage   61.33%   61.42%   +0.08%     
==========================================
  Files         310      311       +1     
  Lines       47313    47919     +606     
==========================================
+ Hits        29021    29432     +411     
- Misses      15290    15429     +139     
- Partials     3002     3058      +56     
Flag Coverage Δ
apiserver-e2etests 35.53% <ø> (-0.30%) ⬇️
apiserver-unittests 36.32% <ø> (+0.20%) ⬆️
core-unittests 55.61% <ø> (+0.36%) ⬆️
e2e-multicluster-test 18.65% <ø> (-0.34%) ⬇️
e2e-rollout-tests 21.02% <ø> (+0.01%) ⬆️
e2etests 26.63% <ø> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pkg/resourcekeeper/dispatch.go 75.00% <0.00%> (-6.25%) ⬇️
pkg/resourcekeeper/resourcekeeper.go 61.81% <0.00%> (-5.46%) ⬇️
pkg/multicluster/cluster_metrics_management.go 91.04% <0.00%> (-4.48%) ⬇️
pkg/workflow/operation/operation.go 40.05% <0.00%> (-4.48%) ⬇️
pkg/oam/util/helper.go 61.91% <0.00%> (-2.09%) ⬇️
...troller/core.oam.dev/v1alpha2/application/apply.go 86.07% <0.00%> (-1.90%) ⬇️
pkg/velaql/providers/query/collector.go 68.80% <0.00%> (-1.84%) ⬇️
pkg/apiserver/event/sync/convert/convert.go 80.35% <0.00%> (-1.79%) ⬇️
pkg/apiserver/domain/service/workflow.go 51.95% <0.00%> (-1.76%) ⬇️
pkg/cue/definition/template.go 66.76% <0.00%> (-1.49%) ⬇️
... and 23 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

// +usage=Specify the credentials to access alibaba oss
accessKey: {
id: string
secret: string
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will make the secret to be plaintext, it's dangerous, can we use the secret mount ?

Copy link
Contributor Author

@lunarwhite lunarwhite Feb 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can provide secretRef field, perhaps like this:

accessKey: close({
  id:     string
  secret: string
}) | close({
  secretRef: {
    // +usage=name is the name of the secret
    name: string
    // +usage=keyId is the key of oss access id in the secret
    keyId: string
    // +usage=keySecret is the key of oss access secret in the secret
    keySecret: string
  }
})

Now the user can use either secret or plaintext.

Signed-off-by: Yuedong Wu <dwcn22@outlook.com>
Signed-off-by: Yuedong Wu <dwcn22@outlook.com>
Signed-off-by: Yuedong Wu <dwcn22@outlook.com>
"vela/op"
)

"build-source-code": {
Copy link
Member

@FogDong FogDong Feb 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently support the step called build-push-image which uses kaniko to build images, maybe you can add the pvc capability in that step instead of creating a new one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'll try to make some adaptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that way, how can we get the generated build artifacts like the yarn build output files? Do we need kaniko's capability to build container images?

I've tried to deploy a app using step build-push-image and component webservice per this guide, and the process is simple and smooth enough. Users probably will rarely have such a need to persist files for later extra upload...

Copy link
Member

@FogDong FogDong Feb 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm, your step will only build the code but not the image, right? Maybe it should be separated with the step build-push-image, but a general step for code building is hard since there're multiple languages, I'm not sure if there're some mature tools in the community that we can combine with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I found that kaniko can also specify the arg like --destination=/output to persist the generated files in volume.
  • If only need to build code, maybe using a container is enough. The user provides a dockerfile to specify the base image and build commands in steps.
  • For multiple langs support, no suitable tools were found yet. I found that most of them are cicd platforms.

I currently think of two possible options for code building, one is user provides a dockerfile, or user provides the base image and build cmd which is the current draft implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Scenario] Build static site and serve it on OSS
3 participants