├── hack
├── custom-boilerplate.go.txt
├── nsswitch.conf
├── types.go
├── os.sh
├── jsonschema
│ └── types.go
├── swagger
│ ├── types.go
│ └── main.go
├── auto-gen-msg.sh
├── free-port.sh
├── null_docgen.go
├── pull-build-images.sh
├── arch.sh
├── update-image-tags.sh
├── recurl.sh
├── capture-pprof.sh
├── main.go
├── cli
│ └── main.go
└── test-examples.sh
├── server
├── .gitignore
├── auth
│ ├── rbac
│ │ └── config.go
│ └── authorizer.go
├── static
│ ├── files.go.stub
│ └── response-rewriter.go
├── apiserver
│ └── config.go
└── types
│ └── clients.go
├── test
├── e2e
│ ├── .gitignore
│ ├── functional
│ │ ├── ci.yaml
│ │ ├── loops.yaml
│ │ ├── steps.yaml
│ │ ├── secrets.yaml
│ │ ├── sidecar.yaml
│ │ ├── coinflip.yaml
│ │ ├── dag-nested.yaml
│ │ ├── k8s-jobs.yaml
│ │ ├── loops-dag.yaml
│ │ ├── loops-maps.yaml
│ │ ├── testvolume.yaml
│ │ ├── conditionals.yaml
│ │ ├── daemon-nginx.yaml
│ │ ├── daemon-step.yaml
│ │ ├── dag-coinflip.yaml
│ │ ├── dag-diamond.yaml
│ │ ├── dag-targets.yaml
│ │ ├── hello-world.yaml
│ │ ├── scripts-bash.yaml
│ │ ├── sidecar-dind.yaml
│ │ ├── volumes-pvc.yaml
│ │ ├── dag-daemon-task.yaml
│ │ ├── dag-multiroot.yaml
│ │ ├── global-outputs.yaml
│ │ ├── init-container.yaml
│ │ ├── loops-sequence.yaml
│ │ ├── nested-workflow.yaml
│ │ ├── node-selector.yaml
│ │ ├── retry-container.yaml
│ │ ├── scripts-python.yaml
│ │ ├── sidecar-nginx.yaml
│ │ ├── artifact-passing.yaml
│ │ ├── continue-on-fail.yaml
│ │ ├── dag-diamond-steps.yaml
│ │ ├── global-parameters.yaml
│ │ ├── k8s-orchestration.yaml
│ │ ├── output-parameter.yaml
│ │ ├── parallelism-limit.yaml
│ │ ├── retry-with-steps.yaml
│ │ ├── suspend-template.yaml
│ │ ├── volumes-emptydir.yaml
│ │ ├── volumes-existing.yaml
│ │ ├── arguments-artifacts.yaml
│ │ ├── arguments-parameters.yaml
│ │ ├── ci-output-artifact.yaml
│ │ ├── coinflip-recursive.yaml
│ │ ├── input-artifact-http.yaml
│ │ ├── input-artifact-raw.yaml
│ │ ├── loops-param-argument.yaml
│ │ ├── loops-param-result.yaml
│ │ ├── parallelism-nested.yaml
│ │ ├── scripts-javascript.yaml
│ │ ├── artifact-disable-archive.yaml
│ │ ├── parameter-aggregation-dag.yaml
│ │ ├── parameter-aggregation-script.yaml
│ │ ├── retry-container-to-completion.yaml
│ │ ├── success-event.yaml
│ │ ├── synchronization-mutex-wf-level.yaml
│ │ ├── synchronization-mutex-wf-level-1.yaml
│ │ ├── sidecar-force-kill.yaml
│ │ ├── workflow_level_host_aliases.yaml
│ │ ├── template_level_host_aliases.yaml
│ │ ├── hello-world.json
│ │ ├── script-with-volume.yaml
│ │ ├── stop-terminate-2.yaml
│ │ ├── workflow_teemplate_level_host_aliases.yaml
│ │ ├── stop-terminate.yaml
│ │ ├── dag-with-retries.yaml
│ │ ├── retry-script.yaml
│ │ └── script-with-input-art.yaml
│ ├── expectedfailures
│ │ ├── exit-handlers.yaml
│ │ ├── timeouts-step.yaml
│ │ ├── timeouts-workflow.yaml
│ │ ├── oom-kill.yaml
│ │ ├── failed-step-event.yaml
│ │ ├── large-workflow.yaml
│ │ ├── exit-handler-failed.yaml
│ │ └── unschedulable.yaml
│ ├── manifests
│ │ ├── argo-ns.yaml
│ │ ├── stress
│ │ │ ├── workflow-controller-pprof-service.yaml
│ │ │ ├── argo-server-deployment.yaml
│ │ │ ├── workflow-controller-configmap.yaml
│ │ │ ├── kustomization.yaml
│ │ │ └── workflow-controller-deployment.yaml
│ │ ├── mixins
│ │ │ ├── workflow-controller-deployment.yaml
│ │ │ ├── argo-server-deployment.yaml
│ │ │ └── workflow-controller-configmap.yaml
│ │ ├── sso
│ │ │ └── kustomization.yaml
│ │ ├── postgres
│ │ │ └── kustomization.yaml
│ │ └── prometheus
│ │ │ └── kustomization.yaml
│ ├── images
│ │ └── argosay
│ │ │ ├── v2
│ │ │ ├── Dockerfile
│ │ │ └── argosay
│ │ │ └── v1
│ │ │ └── Dockerfile
│ ├── http_logger.go
│ ├── smoke
│ │ ├── basic-2.yaml
│ │ ├── basic.yaml
│ │ ├── runasnonroot-workflow.yaml
│ │ └── hello-world-workflow-tmpl.yaml
│ ├── testdata
│ │ ├── wellformed
│ │ │ ├── wellformed-workflow-with-workflow-template-ref.yaml
│ │ │ ├── wellformed-workflow-with-malformed-workflow-template-ref.yaml
│ │ │ ├── wellformed-workflow-with-cluster-workflow-template-ref.yaml
│ │ │ ├── wellformed-workflow-with-malformed-cluster-workflow-template-ref.yaml
│ │ │ ├── wellformed-workflowtemplate.yaml
│ │ │ ├── wellformed-clusterworkflowtemplate.yaml
│ │ │ └── wellformed-cronworkflow.yaml
│ │ ├── malformed
│ │ │ ├── malformed-workflowtemplate-2.yaml
│ │ │ ├── malformed-workflow.yaml
│ │ │ ├── malformed-workflowtemplate.yaml
│ │ │ ├── malformed-clusterworkflowtemplate.yaml
│ │ │ └── malformed-cronworkflow.yaml
│ │ ├── exit-1.yaml
│ │ ├── sleep-3s.yaml
│ │ ├── workflow-templates
│ │ │ ├── workflowtemplate.yaml
│ │ │ └── invalid-workflowtemplate.yaml
│ │ ├── sleepy-workflow.yaml
│ │ ├── basic-workflow.yaml
│ │ ├── cannot-start-workflow.yaml
│ │ ├── basic-workflowtemplate.yaml
│ │ ├── basic-clusterworkflowtemplate.yaml
│ │ ├── pending-workflow.yaml
│ │ ├── workflow-template-ref.yaml
│ │ ├── argo-server-test-role.yaml
│ │ ├── workflow-template-ref-exithandler.yaml
│ │ ├── basic-cronworkflow.yaml
│ │ ├── retry-on-error-workflow.yaml
│ │ ├── semaphore-wf-level.yaml
│ │ ├── cluster-workflow-template-ref.yaml
│ │ ├── sidecar-workflow.yaml
│ │ ├── semaphore-wf-level-1.yaml
│ │ ├── two-items.yaml
│ │ ├── artifact-workflow.yaml
│ │ ├── output-on-input-workflow.yaml
│ │ ├── output-on-mount-workflow.yaml
│ │ ├── sidecar-injected-workflow.yaml
│ │ ├── retry-omit.yaml
│ │ ├── input-on-mount-workflow.yaml
│ │ ├── same-input-output-path-optional.yaml
│ │ └── storage-limit.yaml
│ ├── client.go
│ ├── lintfail
│ │ ├── disallow-unknown.yaml
│ │ ├── invalid-spec.yaml
│ │ └── malformed-spec.yaml
│ └── cron
│ │ └── basic.yaml
└── util
│ ├── workflow.go
│ └── unstructured.go
├── workflow
├── executor
│ ├── testdata
│ │ ├── file
│ │ ├── kubectl
│ │ ├── file.gz
│ │ ├── file.tgz
│ │ ├── file.zip
│ │ └── file.tar.gz
│ ├── os-specific
│ │ ├── chroot_windows.go
│ │ ├── chroot_darwin.go
│ │ ├── chroot_linux.go
│ │ ├── umask_windows.go
│ │ ├── umask_darwin.go
│ │ ├── umask_linux.go
│ │ ├── signal_darwin.go
│ │ ├── signal_linux.go
│ │ └── signal_windows.go
│ ├── k8sapi
│ │ └── k8sapi_test.go
│ └── emissary
│ │ ├── multi_reader_closer_test.go
│ │ └── multi_reader_closer.go
├── artifacts
│ ├── resource
│ │ └── resource.go
│ ├── common
│ │ └── common.go
│ └── s3
│ │ └── errors_test.go
├── controller
│ ├── testdata
│ │ ├── workflow-template-ref.yaml
│ │ └── workflow-template-submittable.yaml
│ ├── indexes
│ │ ├── pod_index.go
│ │ ├── uid_index.go
│ │ └── configmap_index.go
│ ├── estimation
│ │ ├── dummy_estimator_factory.go
│ │ └── dummy_estimator.go
│ ├── http_template.go
│ └── config_test.go
├── metrics
│ ├── pod_missing_metric.go
│ └── workflow_condition_metric.go
├── sync
│ ├── common.go
│ └── chain_throttler_test.go
├── common
│ └── placeholder_test.go
├── artifactrepositories
│ └── mocks
│ │ └── default.go
└── hydrator
│ └── fake
│ └── noop.go
├── ui
├── tsconfig.json
├── __mocks__
│ └── styleMock.js
├── .gitignore
├── src
│ ├── app
│ │ ├── typings.d.ts
│ │ ├── login
│ │ │ ├── components
│ │ │ │ └── login.scss
│ │ │ └── index.tsx
│ │ ├── pipelines
│ │ │ ├── components
│ │ │ │ ├── pipeline-list
│ │ │ │ │ └── pipeline-list.scss
│ │ │ │ ├── pipeline-details
│ │ │ │ │ ├── recent.ts
│ │ │ │ │ ├── recent.test.ts
│ │ │ │ │ └── pipeline.scss
│ │ │ │ └── pipeline-container.tsx
│ │ │ └── index.ts
│ │ ├── help
│ │ │ └── index.tsx
│ │ ├── event-sources
│ │ │ ├── components
│ │ │ │ ├── event-source-list
│ │ │ │ │ └── event-source-list.scss
│ │ │ │ └── event-source-container.tsx
│ │ │ └── index.ts
│ │ ├── apidocs
│ │ │ ├── index.tsx
│ │ │ └── components
│ │ │ │ └── apiDocs.tsx
│ │ ├── userinfo
│ │ │ └── index.tsx
│ │ ├── assets
│ │ │ └── fonts
│ │ │ │ └── Heebo-Regular.ttf
│ │ ├── shared
│ │ │ ├── services
│ │ │ │ ├── responses.ts
│ │ │ │ └── event-service.ts
│ │ │ ├── footnote.tsx
│ │ │ ├── components
│ │ │ │ ├── loading.tsx
│ │ │ │ ├── phase.tsx
│ │ │ │ ├── phase-icon.tsx
│ │ │ │ ├── notice.tsx
│ │ │ │ ├── link-button.tsx
│ │ │ │ ├── query.tsx
│ │ │ │ ├── text-input.tsx
│ │ │ │ ├── example-manifests.tsx
│ │ │ │ ├── namespace-filter.tsx
│ │ │ │ ├── zero-state.tsx
│ │ │ │ ├── fa-icons.tsx
│ │ │ │ ├── object-parser.ts
│ │ │ │ ├── number-input.tsx
│ │ │ │ ├── progress-line.tsx
│ │ │ │ ├── security-nudge.tsx
│ │ │ │ ├── inline-table
│ │ │ │ │ └── inline-table.scss
│ │ │ │ ├── toggle-button.tsx
│ │ │ │ ├── resource-editor
│ │ │ │ │ └── resource.scss
│ │ │ │ ├── drop-down-button.scss
│ │ │ │ ├── cost-optimisation-nudge.tsx
│ │ │ │ ├── graph
│ │ │ │ │ └── layout.ts
│ │ │ │ └── timestamp.tsx
│ │ │ ├── pagination.ts
│ │ │ ├── use-query-params.ts
│ │ │ ├── cron.tsx
│ │ │ ├── base.ts
│ │ │ ├── debounce.ts
│ │ │ └── context.ts
│ │ ├── reports
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ └── report-container.tsx
│ │ ├── sensors
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ └── sensors-container.tsx
│ │ ├── workflows
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── workflow-logs-viewer
│ │ │ │ └── workflow-logs-viewer.scss
│ │ │ │ ├── workflow-dag
│ │ │ │ ├── genres.ts
│ │ │ │ └── icons.ts
│ │ │ │ ├── workflow-link.tsx
│ │ │ │ ├── workflow-details
│ │ │ │ └── workflow-resource-panel.tsx
│ │ │ │ └── workflows-container.tsx
│ │ ├── event-flow
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── event-flow-container.tsx
│ │ │ │ └── event-flow-details
│ │ │ │ ├── genres.ts
│ │ │ │ └── event-flow-page.scss
│ │ ├── cron-workflows
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── cron-workflow-list
│ │ │ │ └── cron-workflow-list.scss
│ │ │ │ ├── cron-workflow-link.tsx
│ │ │ │ └── cron-workflow-container.tsx
│ │ ├── archived-workflows
│ │ │ └── index.ts
│ │ ├── workflow-templates
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── workflow-template-list
│ │ │ │ └── workflow-template-list.scss
│ │ │ │ └── workflow-template-link.tsx
│ │ ├── workflow-event-bindings
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── workflow-event-bindings
│ │ │ │ └── id.ts
│ │ │ │ └── workflow-event-bindings-container.tsx
│ │ ├── cluster-workflow-templates
│ │ │ ├── index.ts
│ │ │ └── components
│ │ │ │ ├── cluster-workflow-template-list
│ │ │ │ └── cluster-workflow-template-list.scss
│ │ │ │ └── cluster-workflow-template-link.tsx
│ │ ├── index.tsx
│ │ ├── tsconfig.json
│ │ └── index.html
│ └── models
│ │ ├── submit-opts.ts
│ │ ├── index.ts
│ │ ├── info.ts
│ │ ├── cluster-workflow-templates.ts
│ │ ├── pipeline.ts
│ │ └── workflow-templates.ts
├── .yarnrc
├── .prettierrc
├── jest.config.js
├── test
│ └── ui
│ │ └── ui-workflow-error.yaml
├── README.md
└── .snyk
├── pkg
├── apiclient
│ ├── clusterworkflowtemplate
│ │ └── testy.txt
│ ├── workflow
│ │ ├── workflow.go
│ │ └── forwarder_overwrite.go
│ ├── workflowtemplate
│ │ └── workflowtemplate.go
│ ├── sensor
│ │ └── forwarder_overwrite.go
│ ├── http1
│ │ ├── event-watch-client.go
│ │ ├── pod-logs-client.go
│ │ ├── watch-workflows-client.go
│ │ └── facade_test.go
│ ├── eventsource
│ │ └── forwarder_overwrite.go
│ ├── pipeline
│ │ └── forwarder_overwrite.go
│ └── apiclient_test.go
├── client
│ └── clientset
│ │ └── versioned
│ │ ├── doc.go
│ │ ├── fake
│ │ └── doc.go
│ │ ├── scheme
│ │ └── doc.go
│ │ └── typed
│ │ └── workflow
│ │ └── v1alpha1
│ │ ├── fake
│ │ └── doc.go
│ │ ├── doc.go
│ │ └── generated_expansion.go
└── apis
│ └── workflow
│ └── v1alpha1
│ ├── doc.go
│ ├── generated.swagger.json
│ ├── estimated_duration.go
│ ├── estimated_duration_test.go
│ ├── data_types_test.go
│ ├── cron_workflow_types_test.go
│ ├── workflow_phase_test.go
│ └── workflow_template_types_test.go
├── CODEOWNERS
├── docs
├── assets
│ ├── argo.png
│ ├── logo.png
│ ├── diagram.png
│ ├── videos.png
│ ├── ecosystem.png
│ ├── katacoda.png
│ ├── overview.jpeg
│ ├── ide-step-1.png
│ ├── ide-step-2.png
│ ├── ide-step-3.png
│ ├── screenshot.png
│ ├── architecture.jpeg
│ ├── intellij-ide-step-1-config.png
│ ├── vscode-ide-step-3-spec-schema.png
│ ├── vscode-ide-step-1-install-plugin.png
│ ├── vscode-ide-step-2-schema-settings.png
│ ├── vscode-ide-step-4-example-functionality.png
│ └── intellij-ide-step-1-example-functionality.png
├── swagger.md
├── architecture.md
├── versioning.md
├── static-code-analysis.md
├── public-api.md
├── widgets.md
├── disaster-recovery.md
├── kubectl.md
└── workflow-creator.md
├── manifests
├── base
│ ├── crds
│ │ ├── minimal
│ │ │ ├── README.md
│ │ │ └── kustomization.yaml
│ │ ├── kustomization.yaml
│ │ └── full
│ │ │ ├── README.md
│ │ │ └── kustomization.yaml
│ ├── argo-server
│ │ ├── argo-server-sa.yaml
│ │ ├── kustomization.yaml
│ │ └── argo-server-service.yaml
│ ├── workflow-controller
│ │ ├── workflow-controller-sa.yaml
│ │ ├── workflow-controller-configmap.yaml
│ │ ├── kustomization.yaml
│ │ └── workflow-controller-metrics-service.yaml
│ └── kustomization.yaml
├── quick-start
│ ├── sso
│ │ ├── dex
│ │ │ ├── dex-sa.yaml
│ │ │ ├── dev-svc.yaml
│ │ │ ├── dex-role.yaml
│ │ │ ├── dex-rb.yaml
│ │ │ └── kustomization.yaml
│ │ ├── kustomization.yaml
│ │ └── overlays
│ │ │ ├── argo-server-sa.yaml
│ │ │ └── workflow-controller-configmap.yaml
│ ├── base
│ │ ├── webhooks
│ │ │ ├── github.com-sa.yaml
│ │ │ ├── kustomization.yaml
│ │ │ └── github.com-rolebinding.yaml
│ │ ├── argo-server-sso-secret.yaml
│ │ ├── minio
│ │ │ ├── kustomization.yaml
│ │ │ ├── my-minio-cred-secret.yaml
│ │ │ └── minio-service.yaml
│ │ ├── prometheus
│ │ │ ├── kustomization.yaml
│ │ │ ├── prometheus-service.yaml
│ │ │ └── prometheus-config-cluster.yaml
│ │ ├── kubelet-executor-clusterrole.yaml
│ │ ├── workflow-default-rolebinding.yaml
│ │ ├── kubelet-executor-default-clusterrolebinding.yaml
│ │ ├── overlays
│ │ │ └── argo-server-deployment.yaml
│ │ └── kustomization.yaml
│ ├── minimal
│ │ └── kustomization.yaml
│ ├── mysql
│ │ ├── argo-mysql-config-secret.yaml
│ │ ├── mysql-service.yaml
│ │ └── kustomization.yaml
│ └── postgres
│ │ ├── argo-postgres-config-secret.yaml
│ │ ├── postgres-service.yaml
│ │ └── kustomization.yaml
├── namespace-install
│ ├── overlays
│ │ ├── argo-server-deployment.yaml
│ │ └── workflow-controller-deployment.yaml
│ ├── argo-server-rbac
│ │ ├── kustomization.yaml
│ │ └── argo-server-rolebinding.yaml
│ ├── workflow-controller-rbac
│ │ ├── kustomization.yaml
│ │ └── workflow-controller-rolebinding.yaml
│ └── kustomization.yaml
└── cluster-install
│ ├── kustomization.yaml
│ ├── argo-server-rbac
│ ├── kustomization.yaml
│ └── argo-server-clusterolebinding.yaml
│ └── workflow-controller-rbac
│ ├── workflow-controller-rolebinding.yaml
│ ├── kustomization.yaml
│ ├── workflow-controller-clusterrolebinding.yaml
│ └── workflow-controller-role.yaml
├── config
├── image.go
├── node_events.go
└── node_events_test.go
├── OWNERS
├── util
├── intstr
│ └── parse.go
├── json
│ ├── fix_test.go
│ ├── jsonify.go
│ └── fix.go
├── help
│ └── topics.go
├── cmd
│ └── glog.go
├── diff
│ └── diff.go
├── kubeconfig
│ └── roundtripper.go
├── logs
│ └── log-entries.go
├── template
│ ├── kind_test.go
│ ├── expression_template_test.go
│ └── validate.go
├── slice
│ └── slice.go
├── wait
│ └── backoff.go
└── python
│ └── python.go
├── examples
├── workflow-template
│ ├── workflow-template-ref.yaml
│ ├── workflow-template-ref-with-entrypoint-arg-passing.yaml
│ ├── workflow-archive-logs.yaml
│ └── hello-world.yaml
├── configmaps
│ └── simple-parameters-configmap.yaml
├── cluster-workflow-template
│ ├── workflow-template-ref.yaml
│ └── workflow-template-ref-with-entrypoint-arg-passing.yaml
├── forever.yaml
├── hello-windows.yaml
├── testvolume.yaml
├── dag-inline-cronworkflow.yaml
├── workflow-event-binding
│ └── event-consumer-workfloweventbinding.yaml
├── archive-location.yaml
├── sidecar-nginx.yaml
├── default-pdb-support.yaml
├── input-artifact-raw.yaml
├── pod-spec-patch.yaml
├── dag-inline-workflowtemplate.yaml
├── artifact-repository-ref.yaml
├── dag-inline-clusterworkflowtemplate.yaml
├── retry-container.yaml
├── pod-spec-yaml-patch.yaml
├── retry-container-to-completion.yaml
├── hello-world.yaml
├── init-container.yaml
├── retry-script.yaml
├── synchronization-mutex-wf-level.yaml
├── timeouts-step.yaml
├── validation_test.go
├── parallelism-limit.yaml
└── input-artifact-http.yaml
├── cmd
├── argo
│ ├── commands
│ │ ├── server_test.go
│ │ ├── auth
│ │ │ ├── root.go
│ │ │ └── token.go
│ │ ├── common_test.go
│ │ ├── archive
│ │ │ └── root.go
│ │ ├── client
│ │ │ └── conn_test.go
│ │ └── template
│ │ │ └── root.go
│ └── main.go
└── argoexec
│ └── commands
│ └── data.go
├── persist
└── sqldb
│ ├── ansi_sql_change.go
│ └── db_type.go
├── .dockerignore
├── community
└── README.md
├── .codecov.yml
├── .github
├── ISSUE_TEMPLATE
│ └── enhancement_proposal.md
└── pull_request_template.md
└── SECURITY.md
/hack/custom-boilerplate.go.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | /static/files.go
--------------------------------------------------------------------------------
/test/e2e/.gitignore:
--------------------------------------------------------------------------------
1 | kubeconfig
--------------------------------------------------------------------------------
/workflow/executor/testdata/file:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | src/app/tsconfig.json
--------------------------------------------------------------------------------
/hack/nsswitch.conf:
--------------------------------------------------------------------------------
1 | hosts: files dns
2 |
--------------------------------------------------------------------------------
/pkg/apiclient/clusterworkflowtemplate/testy.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ui/__mocks__/styleMock.js:
--------------------------------------------------------------------------------
1 | module.exports = {};
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | *.proto @jessesuen @alexec
2 |
3 |
--------------------------------------------------------------------------------
/test/e2e/functional/ci.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/ci.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/loops.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/loops.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/steps.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/steps.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/secrets.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/secrets.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/sidecar.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/sidecar.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/coinflip.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/coinflip.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/dag-nested.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-nested.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/k8s-jobs.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/k8s-jobs.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/loops-dag.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/loops-dag.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/loops-maps.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/loops-maps.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/testvolume.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/testvolume.yaml
--------------------------------------------------------------------------------
/ui/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | bundle
4 | .vscode
5 |
6 |
--------------------------------------------------------------------------------
/hack/types.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | type obj = map[string]interface{}
4 |
--------------------------------------------------------------------------------
/test/e2e/functional/conditionals.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/conditionals.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/daemon-nginx.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/daemon-nginx.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/daemon-step.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/daemon-step.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/dag-coinflip.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-coinflip.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/dag-diamond.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-diamond.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/dag-targets.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-targets.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/hello-world.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/hello-world.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/scripts-bash.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/scripts-bash.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/sidecar-dind.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/sidecar-dind.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/volumes-pvc.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/volumes-pvc.yaml
--------------------------------------------------------------------------------
/hack/os.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eu
3 |
4 | uname -s|tr '[:upper:]' '[:lower:]'
--------------------------------------------------------------------------------
/test/e2e/functional/dag-daemon-task.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-daemon-task.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/dag-multiroot.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-multiroot.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/global-outputs.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/global-outputs.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/init-container.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/init-container.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/loops-sequence.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/loops-sequence.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/nested-workflow.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/nested-workflow.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/node-selector.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/node-selector.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/retry-container.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/retry-container.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/scripts-python.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/scripts-python.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/sidecar-nginx.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/sidecar-nginx.yaml
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/exit-handlers.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/exit-handlers.yaml
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/timeouts-step.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/timeouts-step.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/artifact-passing.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/artifact-passing.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/continue-on-fail.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/continue-on-fail.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/dag-diamond-steps.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/dag-diamond-steps.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/global-parameters.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/global-parameters.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/k8s-orchestration.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/k8s-orchestration.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/output-parameter.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/output-parameter.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/parallelism-limit.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/parallelism-limit.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/retry-with-steps.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/retry-with-steps.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/suspend-template.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/suspend-template.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/volumes-emptydir.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/volumes-emptydir.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/volumes-existing.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/volumes-existing.yaml
--------------------------------------------------------------------------------
/ui/src/app/typings.d.ts:
--------------------------------------------------------------------------------
1 | declare var SYSTEM_INFO: { version: string; };
2 |
3 |
--------------------------------------------------------------------------------
/hack/jsonschema/types.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | type obj = map[string]interface{}
4 |
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/timeouts-workflow.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/timeouts-workflow.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/arguments-artifacts.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/arguments-artifacts.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/arguments-parameters.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/arguments-parameters.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/ci-output-artifact.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/ci-output-artifact.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/coinflip-recursive.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/coinflip-recursive.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/input-artifact-http.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/input-artifact-http.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/input-artifact-raw.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/input-artifact-raw.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/loops-param-argument.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/loops-param-argument.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/loops-param-result.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/loops-param-result.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/parallelism-nested.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/parallelism-nested.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/scripts-javascript.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/scripts-javascript.yaml
--------------------------------------------------------------------------------
/ui/src/app/login/components/login.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
--------------------------------------------------------------------------------
/workflow/executor/testdata/kubectl:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "i/o timeout" >&2
4 | exit 1
5 |
--------------------------------------------------------------------------------
/test/e2e/functional/artifact-disable-archive.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/artifact-disable-archive.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/parameter-aggregation-dag.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/parameter-aggregation-dag.yaml
--------------------------------------------------------------------------------
/test/e2e/manifests/argo-ns.yaml:
--------------------------------------------------------------------------------
1 | kind: Namespace
2 | apiVersion: v1
3 | metadata:
4 | name: argo
--------------------------------------------------------------------------------
/docs/assets/argo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/argo.png
--------------------------------------------------------------------------------
/docs/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/logo.png
--------------------------------------------------------------------------------
/manifests/base/crds/minimal/README.md:
--------------------------------------------------------------------------------
1 | # Minimal CRDs
2 |
3 | These CRDs omit schema validation.
4 |
--------------------------------------------------------------------------------
/docs/assets/diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/diagram.png
--------------------------------------------------------------------------------
/docs/assets/videos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/videos.png
--------------------------------------------------------------------------------
/test/e2e/functional/parameter-aggregation-script.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/parameter-aggregation-script.yaml
--------------------------------------------------------------------------------
/test/e2e/functional/retry-container-to-completion.yaml:
--------------------------------------------------------------------------------
1 | ../../../examples/retry-container-to-completion.yaml
--------------------------------------------------------------------------------
/docs/assets/ecosystem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/ecosystem.png
--------------------------------------------------------------------------------
/docs/assets/katacoda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/katacoda.png
--------------------------------------------------------------------------------
/docs/assets/overview.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/overview.jpeg
--------------------------------------------------------------------------------
/docs/assets/ide-step-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/ide-step-1.png
--------------------------------------------------------------------------------
/docs/assets/ide-step-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/ide-step-2.png
--------------------------------------------------------------------------------
/docs/assets/ide-step-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/ide-step-3.png
--------------------------------------------------------------------------------
/docs/assets/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/screenshot.png
--------------------------------------------------------------------------------
/manifests/quick-start/sso/dex/dex-sa.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: dex
5 |
--------------------------------------------------------------------------------
/pkg/apiclient/workflow/workflow.go:
--------------------------------------------------------------------------------
1 | package workflow
2 |
3 | //go:generate mockery -name WorkflowServiceClient
4 |
--------------------------------------------------------------------------------
/ui/src/app/pipelines/components/pipeline-list/pipeline-list.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
--------------------------------------------------------------------------------
/docs/assets/architecture.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/architecture.jpeg
--------------------------------------------------------------------------------
/hack/swagger/types.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | type (
4 | obj = map[string]interface{}
5 | array = []interface{}
6 | )
7 |
--------------------------------------------------------------------------------
/test/e2e/images/argosay/v2/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM argoproj/argosay:v1
2 |
3 | ADD argosay /
4 |
5 | ENTRYPOINT ["/argosay"]
6 |
--------------------------------------------------------------------------------
/manifests/base/argo-server/argo-server-sa.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: argo-server
5 |
--------------------------------------------------------------------------------
/ui/src/app/help/index.tsx:
--------------------------------------------------------------------------------
1 | import {Help} from './components/help';
2 |
3 | export default {
4 | component: Help
5 | };
6 |
--------------------------------------------------------------------------------
/hack/auto-gen-msg.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -eu -o pipefail
3 |
4 | echo "# This is an auto-generated file. DO NOT EDIT"
5 | cat
--------------------------------------------------------------------------------
/ui/src/app/event-sources/components/event-source-list/event-source-list.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
--------------------------------------------------------------------------------
/ui/src/app/login/index.tsx:
--------------------------------------------------------------------------------
1 | import {Login} from './components/login';
2 |
3 | export default {
4 | component: Login
5 | };
6 |
--------------------------------------------------------------------------------
/workflow/executor/testdata/file.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/workflow/executor/testdata/file.gz
--------------------------------------------------------------------------------
/workflow/executor/testdata/file.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/workflow/executor/testdata/file.tgz
--------------------------------------------------------------------------------
/workflow/executor/testdata/file.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/workflow/executor/testdata/file.zip
--------------------------------------------------------------------------------
/manifests/base/workflow-controller/workflow-controller-sa.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: argo
5 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/webhooks/github.com-sa.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: github.com
5 |
--------------------------------------------------------------------------------
/ui/src/app/apidocs/index.tsx:
--------------------------------------------------------------------------------
1 | import {ApiDocs} from './components/apiDocs';
2 |
3 | export default {
4 | component: ApiDocs
5 | };
6 |
--------------------------------------------------------------------------------
/workflow/executor/testdata/file.tar.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/workflow/executor/testdata/file.tar.gz
--------------------------------------------------------------------------------
/ui/src/app/userinfo/index.tsx:
--------------------------------------------------------------------------------
1 | import {UserInfo} from './components/user-info';
2 |
3 | export default {
4 | component: UserInfo
5 | };
6 |
--------------------------------------------------------------------------------
/docs/assets/intellij-ide-step-1-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/intellij-ide-step-1-config.png
--------------------------------------------------------------------------------
/manifests/base/crds/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - minimal
6 |
--------------------------------------------------------------------------------
/pkg/apiclient/workflowtemplate/workflowtemplate.go:
--------------------------------------------------------------------------------
1 | package workflowtemplate
2 |
3 | //go:generate mockery -name WorkflowTemplateServiceClient
4 |
--------------------------------------------------------------------------------
/ui/.yarnrc:
--------------------------------------------------------------------------------
1 | --add.ignore-optional true
2 | --install.ignore-optional true
3 | --install.frozen-lockfile true
4 | --install.non-interactive true
5 |
--------------------------------------------------------------------------------
/ui/src/app/assets/fonts/Heebo-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/ui/src/app/assets/fonts/Heebo-Regular.ttf
--------------------------------------------------------------------------------
/ui/src/app/shared/services/responses.ts:
--------------------------------------------------------------------------------
1 | export interface WorkflowDeleteResponse {
2 | workflowName: string;
3 | status: string;
4 | }
5 |
--------------------------------------------------------------------------------
/docs/assets/vscode-ide-step-3-spec-schema.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/vscode-ide-step-3-spec-schema.png
--------------------------------------------------------------------------------
/ui/src/models/submit-opts.ts:
--------------------------------------------------------------------------------
1 | export interface SubmitOpts {
2 | entryPoint?: string;
3 | parameters?: string[];
4 | labels?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/chroot_windows.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | func CallChroot() error {
4 | return nil // no chroot on windows
5 | }
6 |
--------------------------------------------------------------------------------
/config/image.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | type Image struct {
4 | Command []string `json:"command"`
5 | Args []string `json:"args,omitempty"`
6 | }
7 |
--------------------------------------------------------------------------------
/docs/assets/vscode-ide-step-1-install-plugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/vscode-ide-step-1-install-plugin.png
--------------------------------------------------------------------------------
/manifests/quick-start/minimal/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../base
6 |
--------------------------------------------------------------------------------
/docs/assets/vscode-ide-step-2-schema-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/vscode-ide-step-2-schema-settings.png
--------------------------------------------------------------------------------
/hack/free-port.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eu
3 |
4 | port=$1
5 |
6 | lsof -s TCP:LISTEN -i ":$port" | grep -v PID | awk '{print $2}' | xargs -L 1 kill || true
7 |
--------------------------------------------------------------------------------
/manifests/base/workflow-controller/workflow-controller-configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: workflow-controller-configmap
5 |
--------------------------------------------------------------------------------
/manifests/namespace-install/overlays/argo-server-deployment.yaml:
--------------------------------------------------------------------------------
1 | - op: add
2 | path: /spec/template/spec/containers/0/args/-
3 | value:
4 | --namespaced
5 |
--------------------------------------------------------------------------------
/ui/src/app/reports/index.ts:
--------------------------------------------------------------------------------
1 | import {ReportsContainer} from './components/report-container';
2 |
3 | export default {
4 | component: ReportsContainer
5 | };
6 |
--------------------------------------------------------------------------------
/ui/src/app/sensors/index.ts:
--------------------------------------------------------------------------------
1 | import {SensorsContainer} from './components/sensors-container';
2 |
3 | export default {
4 | component: SensorsContainer
5 | };
6 |
--------------------------------------------------------------------------------
/docs/assets/vscode-ide-step-4-example-functionality.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/vscode-ide-step-4-example-functionality.png
--------------------------------------------------------------------------------
/docs/swagger.md:
--------------------------------------------------------------------------------
1 | # Argo Server API
2 |
3 | [Open the Swagger API docs](https://raw.githubusercontent.com/argoproj/argo-workflows/master/api/openapi-spec/swagger.json).
4 |
--------------------------------------------------------------------------------
/manifests/namespace-install/overlays/workflow-controller-deployment.yaml:
--------------------------------------------------------------------------------
1 | - op: add
2 | path: /spec/template/spec/containers/0/args/-
3 | value:
4 | --namespaced
5 |
--------------------------------------------------------------------------------
/ui/src/app/pipelines/index.ts:
--------------------------------------------------------------------------------
1 | import {PipelineContainer} from './components/pipeline-container';
2 |
3 | export default {
4 | component: PipelineContainer
5 | };
6 |
--------------------------------------------------------------------------------
/ui/src/app/workflows/index.ts:
--------------------------------------------------------------------------------
1 | import {WorkflowsContainer} from './components/workflows-container';
2 |
3 | export default {
4 | component: WorkflowsContainer
5 | };
6 |
--------------------------------------------------------------------------------
/docs/assets/intellij-ide-step-1-example-functionality.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/canonical/argo-workflows/master/docs/assets/intellij-ide-step-1-example-functionality.png
--------------------------------------------------------------------------------
/pkg/client/clientset/versioned/doc.go:
--------------------------------------------------------------------------------
1 | // Code generated by client-gen. DO NOT EDIT.
2 |
3 | // This package has the automatically generated clientset.
4 | package versioned
5 |
--------------------------------------------------------------------------------
/ui/src/app/event-flow/index.ts:
--------------------------------------------------------------------------------
1 | import {EventFlowContainer} from './components/event-flow-container';
2 |
3 | export default {
4 | component: EventFlowContainer
5 | };
6 |
--------------------------------------------------------------------------------
/manifests/base/crds/full/README.md:
--------------------------------------------------------------------------------
1 | # Full CRDs
2 |
3 | These CRDs have full schema validation. As a result, they are large and probably not suitable to be used in your cluster.
4 |
--------------------------------------------------------------------------------
/manifests/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - crds
6 | - workflow-controller
7 | - argo-server
8 |
--------------------------------------------------------------------------------
/pkg/client/clientset/versioned/fake/doc.go:
--------------------------------------------------------------------------------
1 | // Code generated by client-gen. DO NOT EDIT.
2 |
3 | // This package has the automatically generated fake clientset.
4 | package fake
5 |
--------------------------------------------------------------------------------
/ui/src/app/cron-workflows/index.ts:
--------------------------------------------------------------------------------
1 | import {CronWorkflowContainer} from './components/cron-workflow-container';
2 |
3 | export default {
4 | component: CronWorkflowContainer
5 | };
6 |
--------------------------------------------------------------------------------
/ui/src/app/event-sources/index.ts:
--------------------------------------------------------------------------------
1 | import {EventSourceContainer} from './components/event-source-container';
2 |
3 | export default {
4 | component: EventSourceContainer
5 | };
6 |
--------------------------------------------------------------------------------
/ui/src/app/shared/footnote.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const Footnote = ({children}: {children: React.ReactNode}) =>
{children}
;
4 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/chroot_darwin.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import "syscall"
4 |
5 | func CallChroot() error {
6 | err := syscall.Chroot(".")
7 | return err
8 | }
9 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/chroot_linux.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import "syscall"
4 |
5 | func CallChroot() error {
6 | err := syscall.Chroot(".")
7 | return err
8 | }
9 |
--------------------------------------------------------------------------------
/hack/null_docgen.go:
--------------------------------------------------------------------------------
1 | // +build fields
2 |
3 | package main
4 |
5 | func generateDocs() {
6 | panic("hack package was built with 'fields' tag; doc generation code was not included")
7 | }
8 |
--------------------------------------------------------------------------------
/hack/pull-build-images.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -eu -o pipefail
3 |
4 | grep FROM Dockerfile.dev | grep 'builder$\|argoexec-base$' | awk '{print $2}' | while read image; do docker pull $image; done
5 |
--------------------------------------------------------------------------------
/pkg/client/clientset/versioned/scheme/doc.go:
--------------------------------------------------------------------------------
1 | // Code generated by client-gen. DO NOT EDIT.
2 |
3 | // This package contains the scheme of the automatically generated clientset.
4 | package scheme
5 |
--------------------------------------------------------------------------------
/pkg/client/clientset/versioned/typed/workflow/v1alpha1/fake/doc.go:
--------------------------------------------------------------------------------
1 | // Code generated by client-gen. DO NOT EDIT.
2 |
3 | // Package fake has the automatically generated clients.
4 | package fake
5 |
--------------------------------------------------------------------------------
/manifests/cluster-install/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../base
6 | - ./workflow-controller-rbac
7 | - ./argo-server-rbac
8 |
--------------------------------------------------------------------------------
/pkg/client/clientset/versioned/typed/workflow/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | // Code generated by client-gen. DO NOT EDIT.
2 |
3 | // This package has the automatically generated typed clients.
4 | package v1alpha1
5 |
--------------------------------------------------------------------------------
/ui/src/app/archived-workflows/index.ts:
--------------------------------------------------------------------------------
1 | import {ArchivedWorkflowContainer} from './components/archived-workflow-container';
2 |
3 | export default {
4 | component: ArchivedWorkflowContainer
5 | };
6 |
--------------------------------------------------------------------------------
/ui/src/app/workflow-templates/index.ts:
--------------------------------------------------------------------------------
1 | import {WorkflowTemplateContainer} from './components/workflow-template-container';
2 |
3 | export default {
4 | component: WorkflowTemplateContainer
5 | };
6 |
--------------------------------------------------------------------------------
/manifests/namespace-install/argo-server-rbac/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - argo-server-role.yaml
6 | - argo-server-rolebinding.yaml
7 |
--------------------------------------------------------------------------------
/manifests/quick-start/sso/dex/dev-svc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: dex
5 | spec:
6 | ports:
7 | - name: http
8 | port: 5556
9 | selector:
10 | app: dex
11 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | // Package v1alpha1 is the v1alpha1 version of the API.
2 | // +groupName=argoproj.io
3 | // +k8s:deepcopy-gen=package,register
4 | // +k8s:openapi-gen=true
5 | package v1alpha1
6 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/argo-server-sso-secret.yaml:
--------------------------------------------------------------------------------
1 | kind: Secret
2 | apiVersion: v1
3 | metadata:
4 | name: argo-server-sso
5 | stringData:
6 | clientID: argo-server
7 | clientSecret: ZXhhbXBsZS1hcHAtc2VjcmV0
8 |
--------------------------------------------------------------------------------
/server/auth/rbac/config.go:
--------------------------------------------------------------------------------
1 | package rbac
2 |
3 | type Config struct {
4 | Enabled bool `json:"enabled,omitempty"`
5 | }
6 |
7 | func (c *Config) IsEnabled() bool {
8 | return c != nil && c.Enabled
9 | }
10 |
--------------------------------------------------------------------------------
/server/static/files.go.stub:
--------------------------------------------------------------------------------
1 | // File built without static files
2 | package static
3 |
4 | import "net/http"
5 |
6 | func ServeHTTP(http.ResponseWriter, *http.Request) {}
7 |
8 | func Hash(string) string { return "" }
9 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/umask_windows.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | func AllowGrantingAccessToEveryone() {
4 | // There's no umask in Windows.
5 | // TODO: figure out how we can allow this in Windows.
6 | }
7 |
--------------------------------------------------------------------------------
/manifests/base/argo-server/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - argo-server-deployment.yaml
6 | - argo-server-sa.yaml
7 | - argo-server-service.yaml
8 |
--------------------------------------------------------------------------------
/manifests/cluster-install/argo-server-rbac/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - argo-server-clusterole.yaml
6 | - argo-server-clusterolebinding.yaml
7 |
--------------------------------------------------------------------------------
/ui/src/app/workflow-event-bindings/index.ts:
--------------------------------------------------------------------------------
1 | import {WorkflowEventBindingsContainer} from './components/workflow-event-bindings-container';
2 |
3 | export default {
4 | component: WorkflowEventBindingsContainer
5 | };
6 |
--------------------------------------------------------------------------------
/OWNERS:
--------------------------------------------------------------------------------
1 | owners:
2 | - alexec
3 |
4 | reviewers:
5 | - terrytangyuan
6 | - xianlubird
7 |
8 | approvers:
9 | - alexec
10 | - alexmt
11 | - dtaniwaki
12 | - edlee2121
13 | - jessesuen
14 | - sarabala1979
15 | - simster7
16 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/minio/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - minio-deploy.yaml
6 | - minio-service.yaml
7 | - my-minio-cred-secret.yaml
8 |
--------------------------------------------------------------------------------
/test/e2e/http_logger.go:
--------------------------------------------------------------------------------
1 | package e2e
2 |
3 | import log "github.com/sirupsen/logrus"
4 |
5 | type httpLogger struct{}
6 |
7 | func (d *httpLogger) Logf(fmt string, args ...interface{}) {
8 | log.Debugf(fmt, args...)
9 | }
10 |
--------------------------------------------------------------------------------
/ui/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "bracketSpacing": false,
3 | "jsxSingleQuote": true,
4 | "printWidth": 180,
5 | "singleQuote": true,
6 | "tabWidth": 4,
7 | "jsxBracketSameLine": true,
8 | "quoteProps": "consistent"
9 | }
10 |
--------------------------------------------------------------------------------
/ui/src/app/cluster-workflow-templates/index.ts:
--------------------------------------------------------------------------------
1 | import {ClusterWorkflowTemplateContainer} from './components/cluster-workflow-template-container';
2 |
3 | export default {
4 | component: ClusterWorkflowTemplateContainer
5 | };
6 |
--------------------------------------------------------------------------------
/hack/arch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eu
3 |
4 | arch=$(uname -m)
5 |
6 | case $arch in
7 | x86_64)
8 | echo amd64
9 | ;;
10 | aarch64)
11 | echo arm64
12 | ;;
13 | *)
14 | echo $arch
15 | ;;
16 | esac
17 |
--------------------------------------------------------------------------------
/manifests/namespace-install/workflow-controller-rbac/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - workflow-controller-role.yaml
6 | - workflow-controller-rolebinding.yaml
7 |
--------------------------------------------------------------------------------
/util/intstr/parse.go:
--------------------------------------------------------------------------------
1 | package intstr
2 |
3 | import "k8s.io/apimachinery/pkg/util/intstr"
4 |
5 | // convenience func to get a pointer
6 | func ParsePtr(val string) *intstr.IntOrString {
7 | x := intstr.Parse(val)
8 | return &x
9 | }
10 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/prometheus/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - prometheus-deployment.yaml
6 | - prometheus-config-cluster.yaml
7 | - prometheus-service.yaml
8 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/prometheus/prometheus-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: prometheus
5 | spec:
6 | selector:
7 | app: prometheus
8 | ports:
9 | - name: metrics
10 | port: 9090
11 |
--------------------------------------------------------------------------------
/examples/workflow-template/workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | workflowTemplateRef:
7 | name: workflow-template-submittable
8 |
9 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/minio/my-minio-cred-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | stringData:
3 | accesskey: admin
4 | secretkey: password
5 | kind: Secret
6 | metadata:
7 | name: my-minio-cred
8 | labels:
9 | app: minio
10 | type: Opaque
11 |
--------------------------------------------------------------------------------
/manifests/quick-start/mysql/argo-mysql-config-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | stringData:
3 | username: mysql
4 | password: password
5 | kind: Secret
6 | metadata:
7 | name: argo-mysql-config
8 | labels:
9 | app: mysql
10 | type: Opaque
11 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/loading.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {MockupList} from '../../../../node_modules/argo-ui';
3 |
4 | export const Loading = () => (
5 |
6 |
7 |
8 | );
9 |
--------------------------------------------------------------------------------
/examples/configmaps/simple-parameters-configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: simple-parameters
5 | namespace: argo
6 | labels:
7 | workflows.argoproj.io/configmap-type: Parameter
8 | data:
9 | msg: 'hello world'
10 |
--------------------------------------------------------------------------------
/manifests/base/argo-server/argo-server-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: argo-server
5 | spec:
6 | selector:
7 | app: argo-server
8 | ports:
9 | - name: web
10 | port: 2746
11 | targetPort: 2746
12 |
--------------------------------------------------------------------------------
/test/e2e/smoke/basic-2.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: basic-2
5 | spec:
6 | entrypoint: run-workflow
7 | templates:
8 | - name: run-workflow
9 | container:
10 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | "transformIgnorePatterns": [
4 | "node_modules/(?!(argo-ui)/)"
5 | ],
6 | "moduleNameMapper": {
7 | "\\.(css|scss)$": "/__mocks__/styleMock.js"
8 | },
9 | };
--------------------------------------------------------------------------------
/hack/update-image-tags.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -eu -o pipefail
3 |
4 | dir=$1
5 | image_tag=$2
6 |
7 | find "$dir" -type f -name '*.yaml' | while read -r f ; do
8 | sed "s|argoproj/\(.*\):.*|argoproj/\1:${image_tag}|" "$f" > .tmp
9 | mv .tmp "$f"
10 | done
11 |
--------------------------------------------------------------------------------
/manifests/quick-start/postgres/argo-postgres-config-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | stringData:
3 | username: postgres
4 | password: password
5 | kind: Secret
6 | metadata:
7 | name: argo-postgres-config
8 | labels:
9 | app: postgres
10 | type: Opaque
11 |
--------------------------------------------------------------------------------
/workflow/artifacts/resource/resource.go:
--------------------------------------------------------------------------------
1 | package resource
2 |
3 | import "context"
4 |
5 | type Interface interface {
6 | GetSecret(ctx context.Context, name, key string) (string, error)
7 | GetConfigMapKey(ctx context.Context, name, key string) (string, error)
8 | }
9 |
--------------------------------------------------------------------------------
/test/e2e/manifests/stress/workflow-controller-pprof-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: workflow-controller-pprof
5 | spec:
6 | selector:
7 | app: workflow-controller
8 | ports:
9 | - name: metrics
10 | port: 6060
11 |
--------------------------------------------------------------------------------
/workflow/controller/testdata/workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | namespace: test
6 | spec:
7 | workflowTemplateRef:
8 | name: workflow-template-submittable
9 |
--------------------------------------------------------------------------------
/config/node_events.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | type NodeEvents struct {
4 | Enabled *bool `json:"enabled,omitempty"`
5 | SendAsPod bool `json:"sendAsPod,omitempty"`
6 | }
7 |
8 | func (e NodeEvents) IsEnabled() bool {
9 | return e.Enabled == nil || *e.Enabled
10 | }
11 |
--------------------------------------------------------------------------------
/docs/architecture.md:
--------------------------------------------------------------------------------
1 | # Architecture
2 |
3 | ## Diagram
4 |
5 | 
6 |
7 | ## Argo Workflow Overview
8 |
9 | 
10 |
11 | ## Workflow controller architecture
12 |
13 | 
14 |
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-workflow-with-workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | workflowTemplateRef:
9 | name: wellformed
--------------------------------------------------------------------------------
/docs/versioning.md:
--------------------------------------------------------------------------------
1 | # Versioning
2 |
3 | Argo Workflows does not use Semantic Versioning, even though we have not introduced any breaking changes since v2.
4 |
5 | Breaking changes will be communicated in the release notes.
6 |
7 | See:
8 |
9 | * [Public API](public-api.md)
10 |
--------------------------------------------------------------------------------
/manifests/quick-start/mysql/mysql-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: mysql
5 | labels:
6 | app: mysql
7 | spec:
8 | selector:
9 | app: mysql
10 | ports:
11 | - protocol: TCP
12 | port: 3306
13 | targetPort: 3306
14 |
--------------------------------------------------------------------------------
/manifests/quick-start/sso/dex/dex-role.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: Role
3 | metadata:
4 | name: dex
5 | rules:
6 | - apiGroups:
7 | - ""
8 | resources:
9 | - secrets
10 | - configmaps
11 | verbs:
12 | - get
13 | - list
14 | - watch
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/malformed/malformed-workflowtemplate-2.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: malformed
5 | labels:
6 | argo-e2e: "true"
7 | spec:
8 | templates:
9 | - container:
10 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/src/app/cron-workflows/components/cron-workflow-list/cron-workflow-list.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | .argo-table-list {
4 | &__row:hover {
5 | box-shadow: 1px 2px 3px rgba($argo-color-gray-9, .1), 0 0 0 1px rgba($argo-color-teal-5, .5);
6 | }
7 | }
--------------------------------------------------------------------------------
/ui/src/app/pipelines/components/pipeline-details/recent.ts:
--------------------------------------------------------------------------------
1 | export const recent = (x: Date): boolean => {
2 | if (!x) {
3 | return false;
4 | }
5 | const minutesAgo = (new Date().getTime() - new Date(x).getTime()) / (1000 * 60);
6 | return minutesAgo < 15;
7 | };
8 |
--------------------------------------------------------------------------------
/ui/test/ui/ui-workflow-error.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: ui-workflow-error
5 | namespace: argo
6 | spec:
7 | entrypoint: main
8 | templates:
9 | - name: noop
10 | workflowTemplateRef:
11 | name: not-exists
12 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/umask_darwin.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import "syscall"
4 |
5 | func AllowGrantingAccessToEveryone() {
6 | // default umask can be 022
7 | // setting umask as 0 allow granting write access to other non-root users
8 | syscall.Umask(0)
9 | }
10 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/umask_linux.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import "syscall"
4 |
5 | func AllowGrantingAccessToEveryone() {
6 | // default umask can be 022
7 | // setting umask as 0 allow granting write access to other non-root users
8 | syscall.Umask(0)
9 | }
10 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/minio/minio-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: minio
5 | labels:
6 | app: minio
7 | spec:
8 | selector:
9 | app: minio
10 | ports:
11 | - protocol: TCP
12 | port: 9000
13 | targetPort: 9000
14 |
--------------------------------------------------------------------------------
/manifests/quick-start/sso/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../base
6 | - dex
7 |
8 | patchesStrategicMerge:
9 | - overlays/workflow-controller-configmap.yaml
10 | - overlays/argo-server-sa.yaml
11 |
--------------------------------------------------------------------------------
/pkg/apiclient/sensor/forwarder_overwrite.go:
--------------------------------------------------------------------------------
1 | package sensor
2 |
3 | import (
4 | "github.com/argoproj/pkg/grpc/http"
5 | )
6 |
7 | func init() {
8 | forward_SensorService_SensorsLogs_0 = http.StreamForwarder
9 | forward_SensorService_WatchSensors_0 = http.StreamForwarder
10 | }
11 |
--------------------------------------------------------------------------------
/test/e2e/testdata/exit-1.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: exit-1-
5 | spec:
6 | entrypoint: exit
7 | templates:
8 | - name: exit
9 | container:
10 | image: argoproj/argosay:v2
11 | args: [exit, "1"]
--------------------------------------------------------------------------------
/test/e2e/testdata/malformed/malformed-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: malformed
5 | labels:
6 | workflows.argoproj.io/test: malformed
7 | spec:
8 | arguments:
9 | parameters:
10 | someParam: "Hello, world!"
11 |
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-workflow-with-malformed-workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | workflowTemplateRef:
9 | name: malformed
--------------------------------------------------------------------------------
/hack/recurl.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -eux -o pipefail
3 |
4 | file=$1
5 | url=$2
6 |
7 | if [ ! -f "$file" ]; then
8 | # loop forever
9 | while ! curl -L -o "$file" -- "$url" ;do
10 | echo "sleeping before trying again"
11 | sleep 10s
12 | done
13 | fi
14 |
15 | chmod +x "$file"
--------------------------------------------------------------------------------
/manifests/quick-start/base/webhooks/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - submit-workflow-template-role.yaml
6 | - github.com-sa.yaml
7 | - github.com-rolebinding.yaml
8 | - argo-workflows-webhook-clients-secret.yaml
9 |
--------------------------------------------------------------------------------
/manifests/quick-start/postgres/postgres-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: postgres
5 | labels:
6 | app: postgres
7 | spec:
8 | selector:
9 | app: postgres
10 | ports:
11 | - protocol: TCP
12 | port: 5432
13 | targetPort: 5432
--------------------------------------------------------------------------------
/manifests/quick-start/sso/dex/dex-rb.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: dex
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: Role
8 | name: dex
9 | subjects:
10 | - kind: ServiceAccount
11 | name: dex
12 |
--------------------------------------------------------------------------------
/manifests/base/workflow-controller/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - workflow-controller-configmap.yaml
6 | - workflow-controller-deployment.yaml
7 | - workflow-controller-sa.yaml
8 | - workflow-controller-metrics-service.yaml
9 |
--------------------------------------------------------------------------------
/manifests/quick-start/sso/overlays/argo-server-sa.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: argo-server
5 | annotations:
6 | workflows.argoproj.io/rbac-rule: "'authors' in groups && email == 'kilgore@kilgore.trout'"
7 | workflows.argoproj.io/rbac-rule-precedence: "1"
8 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/phase.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {PhaseIcon} from './phase-icon';
3 |
4 | export const Phase = ({value}: {value: string}) => {
5 | return (
6 | <>
7 | {value}
8 | >
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/ui/src/app/workflows/components/workflow-logs-viewer/workflow-logs-viewer.scss:
--------------------------------------------------------------------------------
1 | .workflow-logs-viewer {
2 | .select {
3 | width: auto;
4 | }
5 | }
6 |
7 | .log-box {
8 | min-height: 500px;
9 | max-height: 800px;
10 | padding: 10px;
11 | margin: 10px;
12 | background-color: white;
13 | }
--------------------------------------------------------------------------------
/util/json/fix_test.go:
--------------------------------------------------------------------------------
1 | package json
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func Test_Fix(t *testing.T) {
10 | assert.Equal(t, "<", Fix("\\u003c"))
11 | assert.Equal(t, ">", Fix("\\u003e"))
12 | assert.Equal(t, "&", Fix("\\u0026"))
13 | }
14 |
--------------------------------------------------------------------------------
/docs/static-code-analysis.md:
--------------------------------------------------------------------------------
1 | # Static Code Analysis
2 |
3 | We use the following static code analysis tools:
4 |
5 | * golangci-lint and tslint for compile time linting
6 | * [snyk.io](https://app.snyk.io/org/argoproj/projects) - for image scanning
7 |
8 | These are at least run daily or on each pull request.
9 |
--------------------------------------------------------------------------------
/test/e2e/manifests/mixins/workflow-controller-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: workflow-controller
5 | spec:
6 | replicas: 0
7 | template:
8 | spec:
9 | containers:
10 | - name: workflow-controller
11 | imagePullPolicy: Never
--------------------------------------------------------------------------------
/test/e2e/smoke/basic.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: basic-
5 | spec:
6 | entrypoint: run-workflow
7 | templates:
8 | - name: run-workflow
9 | container:
10 | image: argoproj/argosay:v2
11 | args: [echo, ":) Hello Argo!"]
--------------------------------------------------------------------------------
/test/e2e/testdata/malformed/malformed-workflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: malformed
5 | labels:
6 | workflows.argoproj.io/test: malformed
7 | spec:
8 | arguments:
9 | parameters:
10 | someParam: "Hello, world!"
11 |
--------------------------------------------------------------------------------
/test/e2e/testdata/sleep-3s.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: sleep-3s-
5 | spec:
6 | entrypoint: sleep-3s
7 | templates:
8 | - name: sleep-3s
9 | container:
10 | image: argoproj/argosay:v2
11 | args: ["sleep", "3s"]
12 |
--------------------------------------------------------------------------------
/examples/cluster-workflow-template/workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: cluster-workflow-template-hello-world-
5 | spec:
6 | workflowTemplateRef:
7 | name: cluster-workflow-template-submittable
8 | clusterScope: true
9 |
10 |
--------------------------------------------------------------------------------
/hack/swagger/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 | )
6 |
7 | func main() {
8 | switch os.Args[1] {
9 | case "kubeifyswagger":
10 | kubeifySwagger(os.Args[2], os.Args[3])
11 | case "secondaryswaggergen":
12 | secondarySwaggerGen()
13 | default:
14 | panic(os.Args[1])
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/pkg/apiclient/http1/event-watch-client.go:
--------------------------------------------------------------------------------
1 | package http1
2 |
3 | import (
4 | corev1 "k8s.io/api/core/v1"
5 | )
6 |
7 | type eventWatchClient struct{ serverSentEventsClient }
8 |
9 | func (f eventWatchClient) Recv() (*corev1.Event, error) {
10 | v := &corev1.Event{}
11 | return v, f.RecvEvent(v)
12 | }
13 |
--------------------------------------------------------------------------------
/util/json/jsonify.go:
--------------------------------------------------------------------------------
1 | package json
2 |
3 | import "encoding/json"
4 |
5 | func Jsonify(v interface{}) (map[string]interface{}, error) {
6 | data, err := json.Marshal(v)
7 | if err != nil {
8 | return nil, err
9 | }
10 | x := make(map[string]interface{})
11 | return x, json.Unmarshal(data, &x)
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/apiclient/eventsource/forwarder_overwrite.go:
--------------------------------------------------------------------------------
1 | package eventsource
2 |
3 | import (
4 | "github.com/argoproj/pkg/grpc/http"
5 | )
6 |
7 | func init() {
8 | forward_EventSourceService_EventSourcesLogs_0 = http.StreamForwarder
9 | forward_EventSourceService_WatchEventSources_0 = http.StreamForwarder
10 | }
11 |
--------------------------------------------------------------------------------
/test/e2e/testdata/malformed/malformed-clusterworkflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: ClusterWorkflowTemplate
3 | metadata:
4 | name: malformed
5 | labels:
6 | workflows.argoproj.io/test: malformed
7 | spec:
8 | arguments:
9 | parameters:
10 | someParam: "Hello, world!"
11 |
--------------------------------------------------------------------------------
/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | .argo-table-list {
4 | margin: 1em;
5 | &__row:hover {
6 | box-shadow: 1px 2px 3px rgba($argo-color-gray-9, .1), 0 0 0 1px rgba($argo-color-teal-5, .5);
7 | }
8 | }
--------------------------------------------------------------------------------
/docs/public-api.md:
--------------------------------------------------------------------------------
1 | # Public API
2 |
3 | Argo Workflows public API is defined by the following:
4 |
5 | * The file `api/openapi-spec/swagger.json`
6 | * The schema of the table `argo_archived_workflows`.
7 | * The installation options listed in `manifests/README.md`.
8 |
9 | See:
10 |
11 | * [Versioning](versioning.md)
--------------------------------------------------------------------------------
/test/e2e/testdata/malformed/malformed-cronworkflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: CronWorkflow
3 | metadata:
4 | name: malformed
5 | labels:
6 | workflows.argoproj.io/test: malformed
7 | spec:
8 | workflowSpec:
9 | arguments:
10 | parameters:
11 | someParam: "Hello, world!"
12 |
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-workflow-with-cluster-workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | workflowTemplateRef:
9 | name: wellformed
10 | clusterScope: true
--------------------------------------------------------------------------------
/ui/src/app/shared/pagination.ts:
--------------------------------------------------------------------------------
1 | import {isNaN} from 'formik';
2 |
3 | export interface Pagination {
4 | offset?: string;
5 | limit?: number;
6 | nextOffset?: string;
7 | }
8 |
9 | export function parseLimit(str: string) {
10 | const v = parseInt(str, 10);
11 | return !isNaN(v) ? v : null;
12 | }
13 |
--------------------------------------------------------------------------------
/cmd/argo/commands/server_test.go:
--------------------------------------------------------------------------------
1 | package commands
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestDefaultSecureMode(t *testing.T) {
10 | // Secure mode by default
11 | cmd := NewServerCommand()
12 | assert.Equal(t, "true", cmd.Flag("secure").Value.String())
13 | }
14 |
--------------------------------------------------------------------------------
/test/e2e/testdata/workflow-templates/workflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: basic
5 | spec:
6 | workflowMetadata:
7 | labels:
8 |
9 | entrypoint: main
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/src/app/shared/components/phase-icon.tsx:
--------------------------------------------------------------------------------
1 | import * as classNames from 'classnames';
2 | import * as React from 'react';
3 | import {Utils} from '../utils';
4 |
5 | export const PhaseIcon = ({value}: {value: string}) => {
6 | return ;
7 | };
8 |
--------------------------------------------------------------------------------
/test/e2e/testdata/sleepy-workflow.yaml:
--------------------------------------------------------------------------------
1 | kind: Workflow
2 | apiVersion: argoproj.io/v1alpha1
3 | metadata:
4 | generateName: sleepy-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v2
11 | args:
12 | - sleep
13 | - 30s
14 |
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-workflow-with-malformed-cluster-workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | workflowTemplateRef:
9 | name: malformed
10 | clusterScope: true
--------------------------------------------------------------------------------
/workflow/controller/indexes/pod_index.go:
--------------------------------------------------------------------------------
1 | package indexes
2 |
3 | import (
4 | corev1 "k8s.io/api/core/v1"
5 | )
6 |
7 | func PodPhaseIndexFunc(obj interface{}) ([]string, error) {
8 | pod, ok := obj.(*corev1.Pod)
9 |
10 | if !ok {
11 | return nil, nil
12 | }
13 | return []string{string(pod.Status.Phase)}, nil
14 | }
15 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/kubelet-executor-clusterrole.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: ClusterRole
3 | metadata:
4 | name: kubelet-executor
5 | rules:
6 | # This allows the kubelet executor.
7 | - apiGroups:
8 | - ""
9 | resources:
10 | - nodes/proxy
11 | verbs:
12 | - get
13 |
--------------------------------------------------------------------------------
/manifests/quick-start/mysql/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../base
6 | - argo-mysql-config-secret.yaml
7 | - mysql-deployment.yaml
8 | - mysql-service.yaml
9 |
10 | patchesStrategicMerge:
11 | - overlays/workflow-controller-configmap.yaml
12 |
--------------------------------------------------------------------------------
/manifests/quick-start/sso/dex/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | commonLabels:
5 | "app.kubernetes.io/part-of": "dex"
6 |
7 | resources:
8 | - dex-cm.yaml
9 | - dex-role.yaml
10 | - dex-sa.yaml
11 | - dex-rb.yaml
12 | - dex-deploy.yaml
13 | - dev-svc.yaml
14 |
--------------------------------------------------------------------------------
/test/e2e/testdata/basic-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: basic-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v2
11 | args:
12 | - echo
13 | - ":) Hello Argo!"
--------------------------------------------------------------------------------
/ui/src/app/cluster-workflow-templates/components/cluster-workflow-template-list/cluster-workflow-template-list.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | .argo-table-list {
4 | margin: 1em;
5 | &__row:hover {
6 | box-shadow: 1px 2px 3px rgba($argo-color-gray-9, .1), 0 0 0 1px rgba($argo-color-teal-5, .5);
7 | }
8 | }
--------------------------------------------------------------------------------
/manifests/quick-start/base/workflow-default-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: workflow-default-binding
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: Role
8 | name: workflow-role
9 | subjects:
10 | - kind: ServiceAccount
11 | name: default
12 |
--------------------------------------------------------------------------------
/test/e2e/testdata/cannot-start-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: cannot-start-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v2
11 | # this cannot start
12 | command: [ invalid ]
--------------------------------------------------------------------------------
/ui/src/app/workflows/components/workflow-dag/genres.ts:
--------------------------------------------------------------------------------
1 | export const genres = {
2 | Collapsed: true,
3 | Container: true,
4 | DAG: true,
5 | HTTP: true,
6 | Pod: true,
7 | Retry: true,
8 | Skipped: true,
9 | StepGroup: false,
10 | Steps: true,
11 | Suspend: true,
12 | TaskGroup: false
13 | };
14 |
--------------------------------------------------------------------------------
/manifests/quick-start/postgres/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../base
6 | - argo-postgres-config-secret.yaml
7 | - postgres-deployment.yaml
8 | - postgres-service.yaml
9 |
10 | patchesStrategicMerge:
11 | - overlays/workflow-controller-configmap.yaml
12 |
--------------------------------------------------------------------------------
/test/e2e/smoke/runasnonroot-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: runasnonroot-
5 | spec:
6 | entrypoint: main
7 | securityContext:
8 | runAsNonRoot: true
9 | runAsUser: 8737
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-workflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | entrypoint: main
9 | templates:
10 | - name: main
11 | container:
12 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/src/app/pipelines/components/pipeline-details/recent.test.ts:
--------------------------------------------------------------------------------
1 | import {recent} from './recent';
2 |
3 | describe('recent', () => {
4 | test('recency', () => {
5 | expect(recent(null)).toEqual(false);
6 | expect(recent(new Date())).toEqual(true);
7 | expect(recent(new Date(0))).toEqual(false);
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/notice.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {CSSProperties, ReactNode} from 'react';
3 |
4 | export const Notice = (props: {style?: CSSProperties; children: ReactNode}) => (
5 |
6 | {props.children}
7 |
8 | );
9 |
--------------------------------------------------------------------------------
/manifests/cluster-install/workflow-controller-rbac/workflow-controller-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: argo-binding
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: Role
8 | name: argo-role
9 | subjects:
10 | - kind: ServiceAccount
11 | name: argo
12 |
--------------------------------------------------------------------------------
/test/e2e/client.go:
--------------------------------------------------------------------------------
1 | package e2e
2 |
3 | import (
4 | "crypto/tls"
5 | "net/http"
6 | )
7 |
8 | var httpClient = &http.Client{
9 | Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
10 | CheckRedirect: func(req *http.Request, via []*http.Request) error {
11 | return http.ErrUseLastResponse
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/examples/forever.yaml:
--------------------------------------------------------------------------------
1 | # run forever
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | name: forever
6 | spec:
7 | entrypoint: main
8 | templates:
9 | - name: main
10 | container:
11 | image: docker/whalesay:latest
12 | command: [sh, "-c", "for I in $(seq 1 1000) ; do echo $I ; sleep 1s; done"]
13 |
--------------------------------------------------------------------------------
/manifests/namespace-install/argo-server-rbac/argo-server-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: argo-server-binding
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: Role
8 | name: argo-server-role
9 | subjects:
10 | - kind: ServiceAccount
11 | name: argo-server
12 |
--------------------------------------------------------------------------------
/manifests/namespace-install/workflow-controller-rbac/workflow-controller-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: argo-binding
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: Role
8 | name: argo-role
9 | subjects:
10 | - kind: ServiceAccount
11 | name: argo
12 |
13 |
--------------------------------------------------------------------------------
/test/e2e/testdata/basic-workflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: basic
5 | spec:
6 | workflowMetadata:
7 | labels:
8 | workflows.argoproj.io/test: "true"
9 | entrypoint: main
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/hack/capture-pprof.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -eu -o pipefail
3 |
4 | echo " https://blog.golang.org/pprof"
5 |
6 | cd $(dirname $0)/..
7 |
8 | n=$(date +%s)
9 |
10 | go tool pprof -web http://localhost:6060/debug/pprof/allocs
11 | go tool pprof -web http://localhost:6060/debug/pprof/heap
12 | go tool pprof -web http://localhost:6060/debug/pprof/profile
--------------------------------------------------------------------------------
/persist/sqldb/ansi_sql_change.go:
--------------------------------------------------------------------------------
1 | package sqldb
2 |
3 | import "upper.io/db.v3/lib/sqlbuilder"
4 |
5 | // represent a straight forward change that is compatible with all database providers
6 | type ansiSQLChange string
7 |
8 | func (s ansiSQLChange) apply(session sqlbuilder.Database) error {
9 | _, err := session.Exec(string(s))
10 | return err
11 | }
12 |
--------------------------------------------------------------------------------
/pkg/apiclient/pipeline/forwarder_overwrite.go:
--------------------------------------------------------------------------------
1 | package pipeline
2 |
3 | import (
4 | "github.com/argoproj/pkg/grpc/http"
5 | )
6 |
7 | func init() {
8 | forward_PipelineService_WatchPipelines_0 = http.StreamForwarder
9 | forward_PipelineService_PipelineLogs_0 = http.StreamForwarder
10 | forward_PipelineService_WatchSteps_0 = http.StreamForwarder
11 | }
12 |
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-clusterworkflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: ClusterWorkflowTemplate
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | entrypoint: main
9 | templates:
10 | - name: main
11 | container:
12 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/manifests/quick-start/base/webhooks/github.com-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: github.com
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: Role
8 | name: submit-workflow-template
9 | subjects:
10 | - kind: ServiceAccount
11 | name: github.com
12 | namespace: argo
--------------------------------------------------------------------------------
/pkg/apiclient/http1/pod-logs-client.go:
--------------------------------------------------------------------------------
1 | package http1
2 |
3 | import (
4 | workflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflow"
5 | )
6 |
7 | type podLogsClient struct{ serverSentEventsClient }
8 |
9 | func (f *podLogsClient) Recv() (*workflowpkg.LogEntry, error) {
10 | v := &workflowpkg.LogEntry{}
11 | return v, f.RecvEvent(v)
12 | }
13 |
--------------------------------------------------------------------------------
/util/json/fix.go:
--------------------------------------------------------------------------------
1 | package json
2 |
3 | import "strings"
4 |
5 | func Fix(s string) string {
6 | // https://stackoverflow.com/questions/28595664/how-to-stop-json-marshal-from-escaping-and/28596225
7 | s = strings.Replace(s, "\\u003c", "<", -1)
8 | s = strings.Replace(s, "\\u003e", ">", -1)
9 | s = strings.Replace(s, "\\u0026", "&", -1)
10 | return s
11 | }
12 |
--------------------------------------------------------------------------------
/manifests/cluster-install/workflow-controller-rbac/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - workflow-aggregate-roles.yaml
6 | - workflow-controller-clusterrole.yaml
7 | - workflow-controller-clusterrolebinding.yaml
8 | - workflow-controller-role.yaml
9 | - workflow-controller-rolebinding.yaml
10 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/generated.swagger.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger": "2.0",
3 | "info": {
4 | "title": "pkg/apis/workflow/v1alpha1/generated.proto",
5 | "version": "version not set"
6 | },
7 | "consumes": [
8 | "application/json"
9 | ],
10 | "produces": [
11 | "application/json"
12 | ],
13 | "paths": {},
14 | "definitions": {}
15 | }
16 |
--------------------------------------------------------------------------------
/test/e2e/testdata/basic-clusterworkflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: ClusterWorkflowTemplate
3 | metadata:
4 | name: basic
5 | spec:
6 | workflowMetadata:
7 | labels:
8 | workflows.argoproj.io/test: "true"
9 | entrypoint: main
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/test/e2e/testdata/workflow-templates/invalid-workflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: basic
5 | spec:
6 | workflowMetadata:
7 | labels:
8 | workflows.argoproj.io/test: "true"
9 | entrypoints: main
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/README.md:
--------------------------------------------------------------------------------
1 | # Argo UI
2 |
3 | 
4 |
5 | A web-based UI for the Argo Workflow engine.
6 |
7 | The UI has the following features:
8 | * View live Argo Workflows running in the cluster
9 | * View completed Argo Workflows
10 | * Create new Argo Workflow templates
11 | * View and create Argo Cron Workflows
12 | * View container logs
13 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/link-button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {ReactNode} from 'react';
3 | import {Button} from './button';
4 |
5 | export const LinkButton = (props: {to: string; children?: ReactNode}) => (
6 |
9 | );
10 |
--------------------------------------------------------------------------------
/hack/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "os"
5 | )
6 |
7 | func main() {
8 | switch os.Args[1] {
9 | case "cleancrd":
10 | cleanCRD(os.Args[2])
11 | case "removecrdvalidation":
12 | removeCRDValidation(os.Args[2])
13 | case "docgen":
14 | generateDocs()
15 | case "parseexamples":
16 | parseExamples()
17 | default:
18 | panic(os.Args[1])
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/manifests/base/crds/full/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - argoproj.io_clusterworkflowtemplates.yaml
6 | - argoproj.io_cronworkflows.yaml
7 | - argoproj.io_workflows.yaml
8 | - argoproj.io_workflowtemplates.yaml
9 | - argoproj.io_workfloweventbindings.yaml
10 | - argoproj.io_workflowtasksets.yaml
11 |
--------------------------------------------------------------------------------
/manifests/base/crds/minimal/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - argoproj.io_clusterworkflowtemplates.yaml
6 | - argoproj.io_cronworkflows.yaml
7 | - argoproj.io_workflows.yaml
8 | - argoproj.io_workflowtemplates.yaml
9 | - argoproj.io_workfloweventbindings.yaml
10 | - argoproj.io_workflowtasksets.yaml
11 |
--------------------------------------------------------------------------------
/test/util/workflow.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "sigs.k8s.io/yaml"
5 |
6 | wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
7 | )
8 |
9 | func MustUnmarshalWorkflow(text string) *wfv1.Workflow {
10 | v := &wfv1.Workflow{}
11 | err := yaml.UnmarshalStrict([]byte(text), v)
12 | if err != nil {
13 | panic(err)
14 | }
15 | return v
16 | }
17 |
--------------------------------------------------------------------------------
/ui/src/app/shared/services/event-service.ts:
--------------------------------------------------------------------------------
1 | import {WorkflowEventBindingList} from '../../../models';
2 | import requests from './requests';
3 |
4 | export class EventService {
5 | public listWorkflowEventBindings(namespace: string) {
6 | return requests.get(`api/v1/workflow-event-bindings/${namespace}`).then(res => res.body as WorkflowEventBindingList);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/manifests/base/workflow-controller/workflow-controller-metrics-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: workflow-controller-metrics
5 | labels:
6 | app: workflow-controller
7 | spec:
8 | selector:
9 | app: workflow-controller
10 | ports:
11 | - name: metrics
12 | port: 9090
13 | targetPort: 9090
14 | protocol: TCP
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/pending-workflow.yaml:
--------------------------------------------------------------------------------
1 | kind: Workflow
2 | apiVersion: argoproj.io/v1alpha1
3 | metadata:
4 | generateName: pending-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v2
11 | # too much to be scheduled
12 | resources:
13 | requests:
14 | memory: 1000Gi
--------------------------------------------------------------------------------
/test/e2e/testdata/workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay-template
7 | arguments:
8 | parameters:
9 | - name: message
10 | value: "hello world"
11 | workflowTemplateRef:
12 | name: workflow-template-whalesay-template
13 |
--------------------------------------------------------------------------------
/workflow/controller/indexes/uid_index.go:
--------------------------------------------------------------------------------
1 | package indexes
2 |
3 | import (
4 | "k8s.io/apimachinery/pkg/api/meta"
5 | "k8s.io/client-go/tools/cache"
6 | )
7 |
8 | var MetaUIDFunc cache.IndexFunc = func(obj interface{}) ([]string, error) {
9 | v, err := meta.Accessor(obj)
10 | if err != nil {
11 | return nil, nil
12 | }
13 | return []string{string(v.GetUID())}, nil
14 | }
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/argo-server-test-role.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: Role
3 | metadata:
4 | name: argotest-role
5 | rules:
6 | - apiGroups:
7 | - "argoproj.io"
8 | resources:
9 | - workflows
10 | - workflowtemplates
11 | - cronworkflows
12 | verbs:
13 | - create
14 | - get
15 | - list
16 | - delete
17 |
--------------------------------------------------------------------------------
/test/util/unstructured.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
5 | "sigs.k8s.io/yaml"
6 | )
7 |
8 | func MustUnmarshalUnstructured(text string) *unstructured.Unstructured {
9 | v := &unstructured.Unstructured{}
10 | err := yaml.UnmarshalStrict([]byte(text), v)
11 | if err != nil {
12 | panic(err)
13 | }
14 | return v
15 | }
16 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/query.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import {Consumer} from '../context';
4 |
5 | /**
6 | * @deprecated Use React hooks instead.
7 | */
8 | export const Query = (props: {children: (params: URLSearchParams) => React.ReactNode}) => (
9 | {ctx => props.children(new URLSearchParams(ctx.history.location.search))}
10 | );
11 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/text-input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const TextInput = ({placeholder, value, onChange, readOnly}: {value: string; onChange: (value: string) => void; readOnly?: boolean; placeholder?: string}) =>
4 | readOnly ? <>{value}> : onChange(e.target.value)} placeholder={placeholder} />;
5 |
--------------------------------------------------------------------------------
/ui/src/models/index.ts:
--------------------------------------------------------------------------------
1 | export * from './events';
2 | export * from './info';
3 | export * from './workflows';
4 | export * from './workflow-templates';
5 | export * from './cron-workflows';
6 | export * from './cluster-workflow-templates';
7 | export {EventSource} from './event-source';
8 | export {Sensor, SensorList} from './sensor';
9 | export {models as kubernetes} from 'argo-ui';
10 |
--------------------------------------------------------------------------------
/util/help/topics.go:
--------------------------------------------------------------------------------
1 | package help
2 |
3 | const (
4 | root = "https://argoproj.github.io/argo-workflows"
5 | ArgoServer = root + "/argo-server/"
6 | CLI = root + "/cli/"
7 |
8 | WorkflowTemplates = root + "/workflow-templates/"
9 | WorkflowTemplatesReferencingOtherTemplates = WorkflowTemplates + "#referencing-other-workflowtemplates"
10 | )
11 |
--------------------------------------------------------------------------------
/hack/cli/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/spf13/cobra/doc"
5 |
6 | "github.com/argoproj/argo-workflows/v3/cmd/argo/commands"
7 | )
8 |
9 | func main() {
10 | println("generating docs/cli")
11 | cmd := commands.NewCommand()
12 | cmd.DisableAutoGenTag = true
13 | err := doc.GenMarkdownTree(cmd, "docs/cli")
14 | if err != nil {
15 | panic(err)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/e2e/lintfail/disallow-unknown.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: disallow-unknown-
5 | spec:
6 | entrypoint: whalesay
7 | templates:
8 | - name: whalesay
9 | container:
10 | image: argoproj/argosay:v1
11 | command:
12 | - cowsay
13 | args:
14 | - hello world
15 | someExtraField: foo
16 |
--------------------------------------------------------------------------------
/manifests/cluster-install/workflow-controller-rbac/workflow-controller-clusterrolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: ClusterRoleBinding
3 | metadata:
4 | name: argo-binding
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: ClusterRole
8 | name: argo-cluster-role
9 | subjects:
10 | - kind: ServiceAccount
11 | name: argo
12 | namespace: argo
13 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/kubelet-executor-default-clusterrolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: ClusterRoleBinding
3 | metadata:
4 | name: kubelet-executor-default
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: ClusterRole
8 | name: kubelet-executor
9 | subjects:
10 | - kind: ServiceAccount
11 | name: default
12 | namespace: argo
13 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/prometheus/prometheus-config-cluster.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: prometheus-config
5 | data:
6 | prometheus.yaml: |
7 | global:
8 | scrape_interval: 15s
9 | scrape_configs:
10 | - job_name: 'argo'
11 | static_configs:
12 | - targets: ['workflow-controller-metrics:9090', 'argo-server:2746']
13 |
--------------------------------------------------------------------------------
/server/apiserver/config.go:
--------------------------------------------------------------------------------
1 | package apiserver
2 |
3 | import (
4 | "github.com/argoproj/argo-workflows/v3/config"
5 | "github.com/argoproj/argo-workflows/v3/server/auth/sso"
6 | )
7 |
8 | var emptyConfigFunc = func() interface{} { return &Config{} }
9 |
10 | type Config struct {
11 | config.Config
12 | // SSO in settings for single-sign on
13 | SSO sso.Config `json:"sso,omitempty"`
14 | }
15 |
--------------------------------------------------------------------------------
/test/e2e/functional/success-event.yaml:
--------------------------------------------------------------------------------
1 | # e2e test to ensure the controller publishes
2 | # an audit event marking the success
3 | # in case of workflow success
4 | apiVersion: argoproj.io/v1alpha1
5 | kind: Workflow
6 | metadata:
7 | generateName: success-event-
8 | spec:
9 | entrypoint: exit
10 | templates:
11 | - name: exit
12 | container:
13 | image: argoproj/argosay:v2
14 |
--------------------------------------------------------------------------------
/test/e2e/testdata/workflow-template-ref-exithandler.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay-template
7 | arguments:
8 | parameters:
9 | - name: message
10 | value: "hello world"
11 | workflowTemplateRef:
12 | name: workflow-template-whalesay-template
13 |
--------------------------------------------------------------------------------
/ui/.snyk:
--------------------------------------------------------------------------------
1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
2 | version: v1.19.0
3 | ignore: {}
4 | # patches apply the minimum changes required to fix a vulnerability
5 | patch:
6 | SNYK-JS-LODASH-567746:
7 | - dagre > lodash:
8 | patched: '2020-09-15T03:26:03.517Z'
9 | - dagre > graphlib > lodash:
10 | patched: '2020-09-15T03:26:03.517Z'
11 |
--------------------------------------------------------------------------------
/ui/src/app/shared/use-query-params.ts:
--------------------------------------------------------------------------------
1 | import {History} from 'history';
2 |
3 | export function useQueryParams(history: History, set: (p: URLSearchParams) => void): () => void {
4 | return () => {
5 | history.listen(newLocation => {
6 | const newQueryParams = new URLSearchParams(newLocation.search);
7 | set(newQueryParams);
8 | });
9 | };
10 | }
11 |
--------------------------------------------------------------------------------
/pkg/apiclient/http1/watch-workflows-client.go:
--------------------------------------------------------------------------------
1 | package http1
2 |
3 | import (
4 | workflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflow"
5 | )
6 |
7 | type watchWorkflowsClient struct{ serverSentEventsClient }
8 |
9 | func (f watchWorkflowsClient) Recv() (*workflowpkg.WorkflowWatchEvent, error) {
10 | v := &workflowpkg.WorkflowWatchEvent{}
11 | return v, f.RecvEvent(v)
12 | }
13 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/estimated_duration.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | import "time"
4 |
5 | // EstimatedDuration is in seconds.
6 | type EstimatedDuration int
7 |
8 | func (d EstimatedDuration) ToDuration() time.Duration {
9 | return time.Second * time.Duration(d)
10 | }
11 |
12 | func NewEstimatedDuration(d time.Duration) EstimatedDuration {
13 | return EstimatedDuration(d.Seconds())
14 | }
15 |
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/oom-kill.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: oop-kill-
5 | spec:
6 | entrypoint: fork-bomb
7 | templates:
8 | - name: fork-bomb
9 | script:
10 | image: debian:9.5-slim
11 | command: [bash, -c]
12 | args: [":(){ : $@$@;};: :"]
13 | resources:
14 | limits:
15 | memory: 5M
16 |
--------------------------------------------------------------------------------
/test/e2e/functional/synchronization-mutex-wf-level.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: synchronization-wf-level-mutex-
5 | spec:
6 | entrypoint: main
7 | synchronization:
8 | mutex:
9 | name: test
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
14 | args: ["sleep", "2s"]
15 |
--------------------------------------------------------------------------------
/manifests/cluster-install/argo-server-rbac/argo-server-clusterolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: ClusterRoleBinding
3 | metadata:
4 | name: argo-server-binding
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: ClusterRole
8 | name: argo-server-cluster-role
9 | subjects:
10 | - kind: ServiceAccount
11 | name: argo-server
12 | namespace: argo
13 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/estimated_duration_test.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | import (
4 | "testing"
5 | "time"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestEstimatedDuration(t *testing.T) {
11 | duration := NewEstimatedDuration(time.Minute)
12 | assert.Equal(t, EstimatedDuration(60), duration)
13 | assert.Equal(t, time.Duration(time.Minute), duration.ToDuration())
14 | }
15 |
--------------------------------------------------------------------------------
/test/e2e/functional/synchronization-mutex-wf-level-1.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: synchronization-wf-level-mutex-1-
5 | spec:
6 | entrypoint: main
7 | synchronization:
8 | mutex:
9 | name: test
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
14 | args: ["sleep", "2s"]
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/basic-cronworkflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: CronWorkflow
3 | metadata:
4 | name: basic
5 | spec:
6 | schedule: "* * * * *"
7 | workflowMetadata:
8 | labels:
9 | workflows.argoproj.io/test: "true"
10 | workflowSpec:
11 | entrypoint: main
12 | templates:
13 | - name: main
14 | container:
15 | image: argoproj/argosay:v2
16 |
--------------------------------------------------------------------------------
/test/e2e/testdata/retry-on-error-workflow.yaml:
--------------------------------------------------------------------------------
1 | kind: Workflow
2 | apiVersion: argoproj.io/v1alpha1
3 | metadata:
4 | generateName: retry-on-error-
5 | spec:
6 | retryStrategy:
7 | retryPolicy: OnError
8 | limit: 1
9 | entrypoint: main
10 | templates:
11 | - name: main
12 | container:
13 | image: argoproj/argosay:v2
14 | args:
15 | - exit
16 | - "1"
--------------------------------------------------------------------------------
/test/e2e/testdata/semaphore-wf-level.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: semaphore-wf-level-
5 | spec:
6 | entrypoint: whalesay
7 | synchronization:
8 | semaphore:
9 | configMapKeyRef:
10 | name: my-config
11 | key: workflow
12 | templates:
13 | - name: whalesay
14 | container:
15 | image: argoproj/argosay:v2
16 |
--------------------------------------------------------------------------------
/ui/src/app/reports/components/report-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {Reports} from './reports';
4 |
5 | export const ReportsContainer = (props: RouteComponentProps) => (
6 |
7 |
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/example-manifests.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const ExampleManifests = () => (
4 | <>
5 | You can find manifests in the examples or templates in{' '}
6 | Workflow Template Catalog
7 | >
8 | );
9 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/namespace-filter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Utils} from '../utils';
3 | import {InputFilter} from './input-filter';
4 |
5 | export const NamespaceFilter = (props: {value: string; onChange: (namespace: string) => void}) =>
6 | Utils.managedNamespace ? <>{Utils.managedNamespace}> : props.onChange(ns)} />;
7 |
--------------------------------------------------------------------------------
/ui/src/app/shared/cron.tsx:
--------------------------------------------------------------------------------
1 | import parser = require('cron-parser');
2 |
3 | export function getNextScheduledTime(schedule: string, tz: string): Date {
4 | let out: Date;
5 | try {
6 | out = parser
7 | .parseExpression(schedule, {utc: !tz, tz})
8 | .next()
9 | .toDate();
10 | } catch (e) {
11 | // Do nothing
12 | }
13 | return out;
14 | }
15 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | # Prevent vendor directory from being copied to ensure we are not not pulling unexpected cruft from
2 | # a user's workspace, and are only building off of what is locked by dep.
3 | *.iml
4 | *.md
5 | *.yaml
6 | .github
7 | .idea
8 | .run
9 | assets
10 | community
11 | coverage.out
12 | dist
13 | docs
14 | examples
15 | manifests
16 | sdks
17 | test/e2e
18 | ui/dist
19 | ui/node_modules
20 | v3
21 | vendor
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/data_types_test.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestGetArtifactIfNeeded(t *testing.T) {
10 | data := &DataSource{ArtifactPaths: &ArtifactPaths{Artifact{Name: "foo"}}}
11 | art, needed := data.GetArtifactIfNeeded()
12 | if assert.True(t, needed) {
13 | assert.Equal(t, "foo", art.Name)
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/workflow/controller/testdata/workflow-template-submittable.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: workflow-template-submittable
5 | namespace: test
6 | spec:
7 | entrypoint: whalesay-template
8 | templates:
9 | - name: whalesay-template
10 | container:
11 | image: docker/whalesay
12 | command: [cowsay]
13 | args: ['hello']
14 |
--------------------------------------------------------------------------------
/cmd/argo/commands/auth/root.go:
--------------------------------------------------------------------------------
1 | package auth
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 | )
6 |
7 | func NewAuthCommand() *cobra.Command {
8 | command := &cobra.Command{
9 | Use: "auth",
10 | Short: "manage authentication settings",
11 | Run: func(cmd *cobra.Command, args []string) {
12 | cmd.HelpFunc()(cmd, args)
13 | },
14 | }
15 | command.AddCommand(NewTokenCommand())
16 | return command
17 | }
18 |
--------------------------------------------------------------------------------
/community/README.md:
--------------------------------------------------------------------------------
1 | # Argo Community
2 |
3 | Welcome to the Argo community!
4 |
5 | Argo is an open, community driven project to make it easy to use Kubernetes for getting useful work done. [This document](https://github.com/argoproj/argoproj/blob/master/community/README.md) describes the organizational structure of the Argo Community including the roles, responsibilities and processes that govern Argo projects and community.
6 |
--------------------------------------------------------------------------------
/config/node_events_test.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | "k8s.io/utils/pointer"
8 | )
9 |
10 | func TestNodeEvents_IsEnabled(t *testing.T) {
11 | assert.True(t, NodeEvents{}.IsEnabled())
12 | assert.False(t, NodeEvents{Enabled: pointer.BoolPtr(false)}.IsEnabled())
13 | assert.True(t, NodeEvents{Enabled: pointer.BoolPtr(true)}.IsEnabled())
14 | }
15 |
--------------------------------------------------------------------------------
/hack/test-examples.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -eu -o pipefail
3 |
4 | ./dist/argo delete -l workflows.argoproj.io/test
5 |
6 | # Load the configmaps that contains the parameter values used for certain examples.
7 | kubectl apply -f examples/configmaps/simple-parameters-configmap.yaml
8 |
9 | grep -lR 'workflows.argoproj.io/test' examples/* | while read f ; do
10 | ./dist/argo submit --watch --verify $f
11 | done
12 |
--------------------------------------------------------------------------------
/pkg/apiclient/workflow/forwarder_overwrite.go:
--------------------------------------------------------------------------------
1 | package workflow
2 |
3 | import (
4 | "github.com/argoproj/pkg/grpc/http"
5 | )
6 |
7 | func init() {
8 | forward_WorkflowService_WatchWorkflows_0 = http.StreamForwarder
9 | forward_WorkflowService_WatchEvents_0 = http.StreamForwarder
10 | forward_WorkflowService_PodLogs_0 = http.StreamForwarder
11 | forward_WorkflowService_WorkflowLogs_0 = http.StreamForwarder
12 | }
13 |
--------------------------------------------------------------------------------
/cmd/argo/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | // load authentication plugin for obtaining credentials from cloud providers.
8 | _ "k8s.io/client-go/plugin/pkg/client/auth"
9 |
10 | "github.com/argoproj/argo-workflows/v3/cmd/argo/commands"
11 | )
12 |
13 | func main() {
14 | if err := commands.NewCommand().Execute(); err != nil {
15 | fmt.Println(err)
16 | os.Exit(1)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/overlays/argo-server-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: argo-server
5 | spec:
6 | template:
7 | spec:
8 | containers:
9 | - name: argo-server
10 | args:
11 | - server
12 | - --namespaced
13 | - --auth-mode
14 | - server
15 | - --auth-mode
16 | - client
17 |
--------------------------------------------------------------------------------
/test/e2e/manifests/stress/argo-server-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: argo-server
5 | spec:
6 | template:
7 | spec:
8 | containers:
9 | - name: argo-server
10 | args:
11 | - server
12 | - --secure=false
13 | - --auth-mode=server
14 | readinessProbe:
15 | httpGet:
16 | scheme: HTTP
--------------------------------------------------------------------------------
/test/e2e/testdata/cluster-workflow-template-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay-template
7 | arguments:
8 | parameters:
9 | - name: message
10 | value: "hello world"
11 | workflowTemplateRef:
12 | name: cluster-workflow-template-whalesay-template
13 | clusterScope: true
14 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/zero-state.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {ReactNode} from 'react';
3 |
4 | // https://designsystem.quickbooks.com/pattern/zero-states/
5 | export const ZeroState = (props: {title?: string; children: ReactNode}) => (
6 |
7 |
{props.title || 'Nothing to show'}
8 | {props.children}
9 |
10 | );
11 |
--------------------------------------------------------------------------------
/ui/src/app/workflows/components/workflow-dag/icons.ts:
--------------------------------------------------------------------------------
1 | import {Icon} from '../../../shared/components/icon';
2 |
3 | export const icons: {[key: string]: Icon} = {
4 | Collapsed: 'ellipsis-h',
5 | Error: 'times',
6 | Failed: 'times',
7 | Omitted: 'forward',
8 | Pending: 'clock',
9 | Running: 'circle-notch',
10 | Skipped: 'forward',
11 | Succeeded: 'check',
12 | Suspended: 'pause'
13 | };
14 |
--------------------------------------------------------------------------------
/workflow/controller/indexes/configmap_index.go:
--------------------------------------------------------------------------------
1 | package indexes
2 |
3 | import (
4 | corev1 "k8s.io/api/core/v1"
5 | )
6 |
7 | const ConfigMapTypeLabel = "workflows.argoproj.io/configmap-type"
8 |
9 | func ConfigMapIndexFunc(obj interface{}) ([]string, error) {
10 | cm, ok := obj.(*corev1.ConfigMap)
11 |
12 | if !ok {
13 | return nil, nil
14 | }
15 | return []string{cm.GetLabels()[ConfigMapTypeLabel]}, nil
16 | }
17 |
--------------------------------------------------------------------------------
/examples/workflow-template/workflow-template-ref-with-entrypoint-arg-passing.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay-template
7 | arguments:
8 | parameters:
9 | - name: message
10 | value: "hello world"
11 | workflowTemplateRef:
12 | name: workflow-template-whalesay-template
13 |
14 |
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/sidecar-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: sidecar-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v1
11 | sidecars:
12 | - name: sidecar
13 | image: argoproj/argosay:v1
14 | command: [ sh, -c ]
15 | args: [ "sleep 999" ]
16 |
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/failed-step-event.yaml:
--------------------------------------------------------------------------------
1 | # e2e test to ensure the controller publishes
2 | # an audit event marking the failure
3 | # in case of node failure
4 | apiVersion: argoproj.io/v1alpha1
5 | kind: Workflow
6 | metadata:
7 | generateName: failed-step-event-
8 | spec:
9 | entrypoint: exit
10 | templates:
11 | - name: exit
12 | container:
13 | image: argoproj/argosay:v2
14 | args: [exit, 1]
15 |
--------------------------------------------------------------------------------
/test/e2e/functional/sidecar-force-kill.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: sidecar-force-kill-
5 | spec:
6 | entrypoint: sidecar-force-kill
7 | templates:
8 | - name: sidecar-force-kill
9 | container:
10 | image: alpine:latest
11 | command: [sleep, 5s]
12 | sidecars:
13 | - name: sleep
14 | image: alpine:latest
15 | command: [sleep, 1d]
16 |
--------------------------------------------------------------------------------
/test/e2e/testdata/semaphore-wf-level-1.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: semaphore-wf-level-1
5 | spec:
6 | entrypoint: whalesay
7 | synchronization:
8 | semaphore:
9 | configMapKeyRef:
10 | name: my-config
11 | key: workflow
12 | templates:
13 | - name: whalesay
14 | container:
15 | image: argoproj/argosay:v2
16 | args: ["sleep", "5s"]
17 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/fa-icons.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const InfoIcon = () => ;
4 | export const SuccessIcon = () => ;
5 | export const WarningIcon = () => ;
6 | export const ErrorIcon = () => ;
7 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/object-parser.ts:
--------------------------------------------------------------------------------
1 | import jsyaml = require('js-yaml');
2 |
3 | export function parse(value: string) {
4 | if (value.startsWith('{')) {
5 | return JSON.parse(value);
6 | }
7 | return jsyaml.load(value);
8 | }
9 |
10 | export function stringify(value: T, type: string) {
11 | return type === 'yaml' ? jsyaml.dump(value, {noRefs: true}) : JSON.stringify(value, null, ' ');
12 | }
13 |
--------------------------------------------------------------------------------
/workflow/controller/estimation/dummy_estimator_factory.go:
--------------------------------------------------------------------------------
1 | package estimation
2 |
3 | import (
4 | wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
5 | )
6 |
7 | type dummyEstimatorFactory struct{}
8 |
9 | func (d dummyEstimatorFactory) NewEstimator(*wfv1.Workflow) (Estimator, error) {
10 | return &dummyEstimator{}, nil
11 | }
12 |
13 | var DummyEstimatorFactory EstimatorFactory = &dummyEstimatorFactory{}
14 |
--------------------------------------------------------------------------------
/docs/widgets.md:
--------------------------------------------------------------------------------
1 | # Widgets
2 |
3 | > v3.0 and after
4 |
5 | Widgets are intended to be embedded into other applications using iframes. This is may not work with your configuration. You may need to:
6 |
7 | * Run the Argo Server with an account that can read workflows. That can be done using `--auth-mode=server` and configuring the `argo-server` service account.
8 | * Run the Argo Server with `--x-frame-options=SAMEORIGIN` or `--x-frame-options=`.
9 |
--------------------------------------------------------------------------------
/ui/src/app/event-flow/components/event-flow-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {EventFlowPage} from './event-flow-details/event-flow-page';
4 |
5 | export const EventFlowContainer = (props: RouteComponentProps) => (
6 |
7 |
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/number-input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {TextInput} from './text-input';
3 |
4 | export const NumberInput = ({onChange, value, placeholder, readOnly}: {value: number; onChange: (value: number) => void; readOnly?: boolean; placeholder?: string}) =>
5 | readOnly ? <>{value}> : onChange(parseInt(x, 10))} placeholder={placeholder} />;
6 |
--------------------------------------------------------------------------------
/cmd/argo/commands/common_test.go:
--------------------------------------------------------------------------------
1 | package commands
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func Test_ansiColorCode(t *testing.T) {
10 | // check we get a nice range of colours
11 | assert.Equal(t, FgYellow, ansiColorCode("foo"))
12 | assert.Equal(t, FgGreen, ansiColorCode("bar"))
13 | assert.Equal(t, FgYellow, ansiColorCode("baz"))
14 | assert.Equal(t, FgRed, ansiColorCode("qux"))
15 | }
16 |
--------------------------------------------------------------------------------
/examples/hello-windows.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: hello-windows-
5 | spec:
6 | entrypoint: hello-win
7 | templates:
8 | - name: hello-win
9 | nodeSelector:
10 | kubernetes.io/os: windows
11 | container:
12 | image: mcr.microsoft.com/windows/nanoserver:1809
13 | command: ["cmd", "/c"]
14 | args: ["echo", "Hello from Windows Container!"]
--------------------------------------------------------------------------------
/examples/testvolume.yaml:
--------------------------------------------------------------------------------
1 | # This PVC manifest is to be used in conjunction with the
2 | # volumes-existing.yaml example. Create this PVC using
3 | # `kubectl create -f testvolume.yaml`, then submit this
4 | # volumes-existing.yaml example.
5 | kind: PersistentVolumeClaim
6 | apiVersion: v1
7 | metadata:
8 | name: my-existing-volume
9 | spec:
10 | accessModes: [ "ReadWriteOnce" ]
11 | resources:
12 | requests:
13 | storage: 1Gi
14 |
--------------------------------------------------------------------------------
/ui/src/app/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import * as ReactDOM from 'react-dom';
3 | import {App} from './app';
4 |
5 | ReactDOM.render(, document.getElementById('app'));
6 |
7 | const mdl = module as any;
8 | if (mdl.hot) {
9 | mdl.hot.accept('./app.tsx', () => {
10 | const UpdatedApp = require('./app.tsx').App;
11 | ReactDOM.render(, document.getElementById('app'));
12 | });
13 | }
14 |
--------------------------------------------------------------------------------
/ui/src/app/workflows/components/workflow-link.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {uiUrl} from '../../shared/base';
3 | import {LinkButton} from '../../shared/components/link-button';
4 |
5 | export const WorkflowLink = (props: {namespace: string; name: string}) => (
6 |
7 | {props.name}
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/workflow/metrics/pod_missing_metric.go:
--------------------------------------------------------------------------------
1 | package metrics
2 |
3 | import "github.com/prometheus/client_golang/prometheus"
4 |
5 | var PodMissingMetric = prometheus.NewGaugeVec(
6 | prometheus.GaugeOpts{
7 | Namespace: argoNamespace,
8 | Name: "pod_missing",
9 | Help: "Incidents of pod missing. https://argoproj.github.io/argo-workflows/metrics/#argo_pod_missing",
10 | },
11 | []string{"recently_started", "node_phase"},
12 | )
13 |
--------------------------------------------------------------------------------
/examples/dag-inline-cronworkflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: CronWorkflow
3 | metadata:
4 | name: dag-inline
5 | annotations:
6 | workflows.argoproj.io/description: |
7 | This example demonstrates running cron workflow that has a DAG with inline templates.
8 | workflows.argoproj.io/version: ">= 3.2.0"
9 | spec:
10 | schedule: "*/5 * * * *"
11 | workflowSpec:
12 | workflowTemplateRef:
13 | name: dag-inline
--------------------------------------------------------------------------------
/test/e2e/functional/workflow_level_host_aliases.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-level-host-aliases-
5 | spec:
6 | entrypoint: nslookup
7 | hostAliases:
8 | - ip: "127.0.0.1"
9 | hostnames:
10 | - "argo.io"
11 | templates:
12 | - name: nslookup
13 | container:
14 | image: alpine:latest
15 | command: [sh, -c]
16 | args: ["nslookup argo.io"]
--------------------------------------------------------------------------------
/.codecov.yml:
--------------------------------------------------------------------------------
1 | ignore:
2 | - "**/*.pb.go"
3 | - "**/*.pb.gw.go"
4 | - "**/*generated.go"
5 | - "**/*generated.deepcopy.go"
6 | - "**/*_test.go"
7 | - "pkg/apis/client/.*"
8 | - "pkg/client/.*"
9 | - "vendor/.*"
10 | coverage:
11 | status:
12 | # we've found this not to be useful
13 | patch: off
14 | project:
15 | default:
16 | # allow test coverage to drop by 2%, assume that it's typically due to CI problems
17 | threshold: 2
--------------------------------------------------------------------------------
/examples/workflow-event-binding/event-consumer-workfloweventbinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowEventBinding
3 | metadata:
4 | name: event-consumer
5 | spec:
6 | event:
7 | selector: payload.appellation != ""
8 | submit:
9 | workflowTemplateRef:
10 | name: event-consumer
11 | arguments:
12 | parameters:
13 | - name: appellation
14 | valueFrom:
15 | event: payload.appellation
--------------------------------------------------------------------------------
/examples/workflow-template/workflow-archive-logs.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: archive-location-
5 | spec:
6 | # archiveLogs allows configuring the archive location for the workflow
7 | archiveLogs: true
8 | entrypoint: whalesay
9 | templates:
10 | - name: whalesay
11 | container:
12 | image: docker/whalesay:latest
13 | command: [cowsay]
14 | args: ["hello world"]
15 |
--------------------------------------------------------------------------------
/docs/disaster-recovery.md:
--------------------------------------------------------------------------------
1 | # Disaster Recovery (DR)
2 |
3 | We only store data in your Kubernetes cluster. You should consider backing this up regularly.
4 |
5 | Exporting example:
6 |
7 | ```
8 | kubectl get wf,cwf,cwft,wftmpl -o yaml > backup.yaml
9 | ```
10 |
11 | Importing example:
12 |
13 | ```
14 | kubectl apply -f backup.yaml
15 |
16 | ```
17 |
18 | You should also back-up any SQL persistence you use regularly with whatever tool is provided with it.
--------------------------------------------------------------------------------
/manifests/cluster-install/workflow-controller-rbac/workflow-controller-role.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: Role
3 | metadata:
4 | name: argo-role
5 | rules:
6 | - apiGroups:
7 | - coordination.k8s.io
8 | resources:
9 | - leases
10 | verbs:
11 | - create
12 | - get
13 | - update
14 | - apiGroups:
15 | - ""
16 | resources:
17 | - secrets
18 | verbs:
19 | - get
20 |
21 |
--------------------------------------------------------------------------------
/server/auth/authorizer.go:
--------------------------------------------------------------------------------
1 | package auth
2 |
3 | import (
4 | "context"
5 |
6 | authUtil "github.com/argoproj/argo-workflows/v3/util/auth"
7 | )
8 |
9 | func CanI(ctx context.Context, verb, resource, namespace, name string) (bool, error) {
10 | kubeClientset := GetKubeClient(ctx)
11 | allowed, err := authUtil.CanI(ctx, kubeClientset, verb, resource, namespace, name)
12 | if err != nil {
13 | return false, err
14 | }
15 | return allowed, nil
16 | }
17 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/progress-line.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export const ProgressLine = (props: {progress: number; width: number; height: number}) => (
4 |
8 | );
9 |
--------------------------------------------------------------------------------
/ui/src/app/workflow-event-bindings/components/workflow-event-bindings/id.ts:
--------------------------------------------------------------------------------
1 | type Type = 'ClusterWorkflowTemplate' | 'WorkflowEventBinding' | 'WorkflowTemplate';
2 |
3 | export const ID = {
4 | join: (type: Type, namespace: string, name: string) => type + '/' + namespace + '/' + name,
5 | split: (id: string) => ({
6 | type: id.split('/')[0] as Type,
7 | namespace: id.split('/')[1],
8 | name: id.split('/')[2]
9 | })
10 | };
11 |
--------------------------------------------------------------------------------
/util/cmd/glog.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "flag"
5 | "strconv"
6 |
7 | "k8s.io/klog/v2"
8 | )
9 |
10 | // SetGLogLevel set the glog level for the k8s go-client
11 | // this is taken from argoproj/pkg but uses v2 of klog here
12 | // to be compatible with k8s clients v0.19.x and above
13 | func SetGLogLevel(glogLevel int) {
14 | klog.InitFlags(nil)
15 | _ = flag.Set("logtostderr", "true")
16 | _ = flag.Set("v", strconv.Itoa(glogLevel))
17 | }
18 |
--------------------------------------------------------------------------------
/util/diff/diff.go:
--------------------------------------------------------------------------------
1 | package diff
2 |
3 | import (
4 | "encoding/json"
5 |
6 | jsonpatch "github.com/evanphx/json-patch"
7 | log "github.com/sirupsen/logrus"
8 | )
9 |
10 | func LogChanges(old, new interface{}) {
11 | if !log.IsLevelEnabled(log.DebugLevel) {
12 | return
13 | }
14 | a, _ := json.Marshal(old)
15 | b, _ := json.Marshal(new)
16 | patch, _ := jsonpatch.CreateMergePatch(a, b)
17 | log.Debugf("Log changes patch: %s", string(patch))
18 | }
19 |
--------------------------------------------------------------------------------
/cmd/argoexec/commands/data.go:
--------------------------------------------------------------------------------
1 | package commands
2 |
3 | import (
4 | "context"
5 |
6 | "github.com/spf13/cobra"
7 | )
8 |
9 | func NewDataCommand() *cobra.Command {
10 | command := cobra.Command{
11 | Use: "data",
12 | Short: "Process data",
13 | RunE: func(cmd *cobra.Command, args []string) error {
14 | ctx := context.Background()
15 | wfExecutor := initExecutor()
16 | return wfExecutor.Data(ctx)
17 | },
18 | }
19 | return &command
20 | }
21 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/cron_workflow_types_test.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | v1 "k8s.io/api/core/v1"
8 | )
9 |
10 | func TestCronWorkflowStatus_HasActiveUID(t *testing.T) {
11 | cwfStatus := CronWorkflowStatus{
12 | Active: []v1.ObjectReference{{UID: "123"}},
13 | }
14 |
15 | assert.True(t, cwfStatus.HasActiveUID("123"))
16 | assert.False(t, cwfStatus.HasActiveUID("foo"))
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/client/clientset/versioned/typed/workflow/v1alpha1/generated_expansion.go:
--------------------------------------------------------------------------------
1 | // Code generated by client-gen. DO NOT EDIT.
2 |
3 | package v1alpha1
4 |
5 | type ClusterWorkflowTemplateExpansion interface{}
6 |
7 | type CronWorkflowExpansion interface{}
8 |
9 | type WorkflowExpansion interface{}
10 |
11 | type WorkflowEventBindingExpansion interface{}
12 |
13 | type WorkflowTaskSetExpansion interface{}
14 |
15 | type WorkflowTemplateExpansion interface{}
16 |
--------------------------------------------------------------------------------
/test/e2e/functional/template_level_host_aliases.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: template-level-host-aliases-
5 | spec:
6 | entrypoint: nslookup
7 |
8 | templates:
9 | - name: nslookup
10 | hostAliases:
11 | - ip: "127.0.0.1"
12 | hostnames:
13 | - "argo.io"
14 | container:
15 | image: alpine:latest
16 | command: [sh, -c]
17 | args: [" nslookup argo.io"]
--------------------------------------------------------------------------------
/ui/src/app/cron-workflows/components/cron-workflow-link.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {uiUrl} from '../../shared/base';
3 | import {LinkButton} from '../../shared/components/link-button';
4 |
5 | export const CronWorkflowLink = (props: {namespace: string; name: string}) => (
6 |
7 | {props.name}
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/security-nudge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {ReactNode} from 'react';
3 | import {Nudge} from './nudge';
4 |
5 | export const SecurityNudge = (props: {children: ReactNode}) => (
6 |
7 | {props.children} Learn more
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/ui/src/app/event-flow/components/event-flow-details/genres.ts:
--------------------------------------------------------------------------------
1 | import {EventSourceTypes} from '../../../../models/event-source';
2 | import {TriggerTypes} from '../../../../models/sensor';
3 |
4 | export const genres = (() => {
5 | const v: {[label: string]: boolean} = {sensor: true, conditions: true, workflow: true, collapsed: true};
6 | EventSourceTypes.forEach(x => (v[x] = true));
7 | TriggerTypes.forEach(x => (v[x] = true));
8 | return v;
9 | })();
10 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/signal_darwin.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import (
4 | "os"
5 | "syscall"
6 | )
7 |
8 | func IsSIGCHLD(s os.Signal) bool { return s == syscall.SIGCHLD }
9 |
10 | func Kill(pid int, s syscall.Signal) error {
11 | pgid, err := syscall.Getpgid(pid)
12 | if err == nil {
13 | return syscall.Kill(-pgid, s)
14 | }
15 | return syscall.Kill(pid, s)
16 | }
17 |
18 | func Setpgid(a *syscall.SysProcAttr) {
19 | a.Setpgid = true
20 | }
21 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/signal_linux.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import (
4 | "os"
5 | "syscall"
6 | )
7 |
8 | func IsSIGCHLD(s os.Signal) bool { return s == syscall.SIGCHLD }
9 |
10 | func Kill(pid int, s syscall.Signal) error {
11 | pgid, err := syscall.Getpgid(pid)
12 | if err == nil {
13 | return syscall.Kill(-pgid, s)
14 | }
15 | return syscall.Kill(pid, s)
16 | }
17 |
18 | func Setpgid(a *syscall.SysProcAttr) {
19 | a.Setpgid = true
20 | }
21 |
--------------------------------------------------------------------------------
/workflow/sync/common.go:
--------------------------------------------------------------------------------
1 | package sync
2 |
3 | import "time"
4 |
5 | type Semaphore interface {
6 | acquire(holderKey string) bool
7 | tryAcquire(holderKey string) (bool, string)
8 | release(key string) bool
9 | addToQueue(holderKey string, priority int32, creationTime time.Time)
10 | removeFromQueue(holderKey string)
11 | getCurrentHolders() []string
12 | getCurrentPending() []string
13 | getName() string
14 | getLimit() int
15 | resize(n int) bool
16 | }
17 |
--------------------------------------------------------------------------------
/examples/archive-location.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: archive-location-
5 | spec:
6 | entrypoint: whalesay
7 | templates:
8 | - name: whalesay
9 | container:
10 | image: docker/whalesay:latest
11 | command: [cowsay]
12 | args: ["hello world"]
13 | # archiveLocation allows configuring the archive location for a specific step
14 | archiveLocation:
15 | archiveLogs: true
16 |
--------------------------------------------------------------------------------
/test/e2e/manifests/stress/workflow-controller-configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: workflow-controller-configmap
5 | data:
6 | containerRuntimeExecutor: pns
7 | namespaceParallelism: "99999"
8 | executor: |
9 | imagePullPolicy: IfNotPresent
10 | resources:
11 | requests:
12 | cpu: 0.1
13 | memory: 64Mi
14 | limits:
15 | cpu: 0.5
16 | memory: 128Mi
17 | kubeletInsecure: "true"
18 |
--------------------------------------------------------------------------------
/ui/src/app/cluster-workflow-templates/components/cluster-workflow-template-link.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {uiUrl} from '../../shared/base';
3 | import {LinkButton} from '../../shared/components/link-button';
4 |
5 | export const ClusterWorkflowTemplateLink = (props: {name: string}) => (
6 |
7 | {props.name}
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/inline-table/inline-table.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | .it {
4 | padding: 1em 0;
5 | &--row {
6 | display: flex;
7 | }
8 |
9 | &--col {
10 | line-height: 2em;
11 | }
12 |
13 | &--key {
14 | display: flex;
15 | align-items: center;
16 | border-right: 1px solid $argo-color-gray-3;
17 | min-width: 150px;
18 | padding-right: 10px;
19 | margin-right: 10px;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/toggle-button.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {ReactNode} from 'react';
3 | import {Button} from './button';
4 |
5 | export const ToggleButton = ({title, children, onToggle, toggled}: {toggled: boolean; onToggle: () => void; children: ReactNode; title?: string}) => (
6 |
9 | );
10 |
--------------------------------------------------------------------------------
/examples/cluster-workflow-template/workflow-template-ref-with-entrypoint-arg-passing.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: cluster-workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay-template
7 | arguments:
8 | parameters:
9 | - name: message
10 | value: "hello world"
11 | workflowTemplateRef:
12 | name: cluster-workflow-template-whalesay-template
13 | clusterScope: true
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/e2e/testdata/wellformed/wellformed-cronworkflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: CronWorkflow
3 | metadata:
4 | name: wellformed
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | schedule: "* * * * *"
9 | workflowMetadata:
10 | labels:
11 | workflows.argoproj.io/test: "true"
12 | workflowSpec:
13 | entrypoint: main
14 | templates:
15 | - name: main
16 | container:
17 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/src/app/workflows/components/workflow-details/workflow-resource-panel.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Workflow} from '../../../../models';
3 | import {ObjectEditor} from '../../../shared/components/object-editor/object-editor';
4 |
5 | export const WorkflowResourcePanel = (props: {workflow: Workflow}) => (
6 |
7 |
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/test/e2e/manifests/mixins/argo-server-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: argo-server
5 | spec:
6 | replicas: 0
7 | template:
8 | spec:
9 | containers:
10 | - name: argo-server
11 | imagePullPolicy: Never
12 | args:
13 | - server
14 | - --secure=false
15 | - --auth-mode=hybrid
16 | readinessProbe:
17 | httpGet:
18 | scheme: HTTP
--------------------------------------------------------------------------------
/test/e2e/testdata/two-items.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: two-items-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | dag:
10 | tasks:
11 | - name: task
12 | template: sleep
13 | withItems:
14 | - "1"
15 | - "2"
16 | - name: sleep
17 | container:
18 | image: argoproj/argosay:v2
19 | args: ["sleep", "3s"]
--------------------------------------------------------------------------------
/pkg/apiclient/apiclient_test.go:
--------------------------------------------------------------------------------
1 | package apiclient
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestOpts_String(t *testing.T) {
10 | assert.Equal(t, "(argoServerOpts=(url=,path=,secure=false,insecureSkipVerify=false,http=false),instanceID=)", Opts{}.String())
11 | assert.Equal(t, "(argoServerOpts=(url=,path=,secure=false,insecureSkipVerify=false,http=false),instanceID=my-instanceid)", Opts{InstanceID: "my-instanceid"}.String())
12 | }
13 |
--------------------------------------------------------------------------------
/test/e2e/manifests/sso/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../../../../manifests/quick-start/sso
6 |
7 | patchesStrategicMerge:
8 | - ../mixins/argo-server-deployment.yaml
9 | - ../mixins/workflow-controller-configmap.yaml
10 | - ../mixins/workflow-controller-deployment.yaml
11 | - ../mixins/cluster-workflow-template-rbac.yaml
12 |
13 | commonLabels:
14 | app.kubernetes.io/part-of: argo
15 | namespace: argo
16 |
--------------------------------------------------------------------------------
/ui/src/app/workflow-templates/components/workflow-template-link.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {uiUrl} from '../../shared/base';
3 | import {LinkButton} from '../../shared/components/link-button';
4 |
5 | export const WorkflowTemplateLink = (props: {namespace: string; name: string}) => (
6 |
7 | {props.name}
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/workflow/common/placeholder_test.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | // TestNextPlaceholder verifies dynamically-generated placeholder strings.
10 | func TestNextPlaceholder(t *testing.T) {
11 | pg := NewPlaceholderGenerator()
12 | assert.Equal(t, pg.NextPlaceholder(), "placeholder-0")
13 | assert.Equal(t, pg.NextPlaceholder(), "placeholder-1")
14 | assert.Equal(t, pg.NextPlaceholder(), "placeholder-2")
15 | }
16 |
--------------------------------------------------------------------------------
/ui/src/app/pipelines/components/pipeline-details/pipeline.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | .graph.pipeline {
4 | .edge {
5 | path {
6 | stroke-dasharray: 8;
7 | }
8 | }
9 |
10 | .node {
11 | &.Running {
12 | text.icon {
13 | animation: none;
14 | }
15 | }
16 | }
17 |
18 | .edge.flow {
19 | path {
20 | stroke: $argo-running-color;
21 | animation: flowing infinite linear 4s;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/ui/src/app/shared/components/resource-editor/resource.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | .resource {
4 | padding-top: 1em;
5 | white-space: pre;
6 | color: $argo-color-gray-7;
7 | width: 100%;
8 | min-height: 300px;
9 | }
10 |
11 | .resource-editor-panel {
12 | &__editor {
13 | border: 1px solid $argo-color-gray-3;
14 | border-radius: 5px;
15 | margin-top: 1em;
16 | padding-bottom: 1em;
17 | overflow: hidden;
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/examples/sidecar-nginx.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: sidecar-nginx-
5 | spec:
6 | entrypoint: sidecar-nginx-example
7 | templates:
8 | - name: sidecar-nginx-example
9 | container:
10 | image: appropriate/curl
11 | command: [sh, -c]
12 | args: ["until `curl -G 'http://127.0.0.1/' >& /tmp/out`; do echo sleep && sleep 1; done && cat /tmp/out"]
13 | sidecars:
14 | - name: nginx
15 | image: nginx:1.13
16 |
--------------------------------------------------------------------------------
/test/e2e/manifests/postgres/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../../../../manifests/quick-start/postgres
6 |
7 | patchesStrategicMerge:
8 | - ../mixins/argo-server-deployment.yaml
9 | - ../mixins/workflow-controller-configmap.yaml
10 | - ../mixins/workflow-controller-deployment.yaml
11 | - ../mixins/cluster-workflow-template-rbac.yaml
12 |
13 | commonLabels:
14 | app.kubernetes.io/part-of: argo
15 | namespace: argo
16 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/drop-down-button.scss:
--------------------------------------------------------------------------------
1 | .drop-down-button {
2 | display: inline-block;
3 |
4 | .items {
5 | position: absolute; // hover at the bottom left of the containing element
6 | z-index: 1; // must above other elements
7 | box-shadow: 1px 1px 1px 1px; // add a small shadow to lift it off the page a tiny amount
8 |
9 | .item {
10 | border-radius: 0; // remove the 24px button radius which looks odd on a menu
11 | width: 100%
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/util/kubeconfig/roundtripper.go:
--------------------------------------------------------------------------------
1 | package kubeconfig
2 |
3 | import "net/http"
4 |
5 | type userAgentRoundTripper struct {
6 | agent string
7 | rt http.RoundTripper
8 | }
9 |
10 | func (rt userAgentRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
11 | req.Header.Set("User-Agent", rt.agent)
12 | return rt.rt.RoundTrip(req)
13 | }
14 |
15 | func NewUserAgentRoundTripper(agent string, rt http.RoundTripper) http.RoundTripper {
16 | return &userAgentRoundTripper{agent, rt}
17 | }
18 |
--------------------------------------------------------------------------------
/util/logs/log-entries.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "time"
5 | )
6 |
7 | type logEntry struct {
8 | timestamp time.Time
9 | podName string
10 | content string
11 | }
12 |
13 | type logEntries []logEntry
14 |
15 | func (l logEntries) Len() int {
16 | return len(l)
17 | }
18 |
19 | func (l logEntries) Less(i, j int) bool {
20 | return l[i].timestamp.Before(l[j].timestamp)
21 | }
22 |
23 | func (l logEntries) Swap(i, j int) {
24 | tmp := l[i]
25 | l[i] = l[j]
26 | l[j] = tmp
27 | }
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancement_proposal.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Enhancement proposal
3 | about: Propose an enhancement for this project
4 | labels: 'enhancement'
5 | ---
6 | # Summary
7 |
8 | What change needs making?
9 |
10 | # Use Cases
11 |
12 | When would you use this?
13 |
14 | ---
15 |
16 | **Message from the maintainers**:
17 |
18 | Impacted by this bug? Give it a 👍. We prioritise the issues with the most 👍.
--------------------------------------------------------------------------------
/examples/default-pdb-support.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: default-pdb-support-
5 |
6 | spec:
7 | entrypoint: pdbcreate
8 | serviceAccountName: default
9 | podDisruptionBudget:
10 | minAvailable: "9999" # Provide arbitrary big number if you don't know how many pods workflow creates
11 | templates:
12 | - name: pdbcreate
13 | container:
14 | image: alpine:latest
15 | command: [sh, -c]
16 | args: ["sleep 10"]
17 |
--------------------------------------------------------------------------------
/server/static/response-rewriter.go:
--------------------------------------------------------------------------------
1 | package static
2 |
3 | import (
4 | "bytes"
5 | "net/http"
6 | "strconv"
7 | )
8 |
9 | type responseRewriter struct {
10 | http.ResponseWriter
11 | old []byte
12 | new []byte
13 | }
14 |
15 | func (w *responseRewriter) Write(a []byte) (int, error) {
16 | b := bytes.Replace(a, w.old, w.new, 1)
17 | // status code and headers are printed out when we write data
18 | w.Header().Set("Content-Length", strconv.Itoa(len(b)))
19 | return w.ResponseWriter.Write(b)
20 | }
21 |
--------------------------------------------------------------------------------
/test/e2e/manifests/stress/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../../../../manifests/quick-start/minimal
6 | - ../../../../manifests/quick-start/base/prometheus
7 | - workflow-controller-pprof-service.yaml
8 |
9 | patchesStrategicMerge:
10 | - workflow-controller-configmap.yaml
11 | - workflow-controller-deployment.yaml
12 | - argo-server-deployment.yaml
13 |
14 | commonLabels:
15 | "app.kubernetes.io/part-of": "argo"
16 |
--------------------------------------------------------------------------------
/ui/src/app/apidocs/components/apiDocs.tsx:
--------------------------------------------------------------------------------
1 | import {Page} from 'argo-ui';
2 | import * as React from 'react';
3 | import SwaggerUI from 'swagger-ui-react';
4 | import 'swagger-ui-react/swagger-ui.css';
5 | import {uiUrl} from '../../shared/base';
6 |
7 | export const ApiDocs = () => (
8 |
9 |
10 |
11 |
12 |
13 | );
14 |
--------------------------------------------------------------------------------
/cmd/argo/commands/archive/root.go:
--------------------------------------------------------------------------------
1 | package archive
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 | )
6 |
7 | func NewArchiveCommand() *cobra.Command {
8 | command := &cobra.Command{
9 | Use: "archive",
10 | Short: "manage the workflow archive",
11 | Run: func(cmd *cobra.Command, args []string) {
12 | cmd.HelpFunc()(cmd, args)
13 | },
14 | }
15 | command.AddCommand(NewListCommand())
16 | command.AddCommand(NewGetCommand())
17 | command.AddCommand(NewDeleteCommand())
18 | return command
19 | }
20 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/workflow_phase_test.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestWorkflowPhase_Completed(t *testing.T) {
10 | assert.False(t, WorkflowUnknown.Completed())
11 | assert.False(t, WorkflowPending.Completed())
12 | assert.False(t, WorkflowRunning.Completed())
13 | assert.True(t, WorkflowSucceeded.Completed())
14 | assert.True(t, WorkflowFailed.Completed())
15 | assert.True(t, WorkflowError.Completed())
16 | }
17 |
--------------------------------------------------------------------------------
/test/e2e/images/argosay/v1/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:14.04
2 |
3 | RUN apt-get update && \
4 | apt-get install -y apt-utils ca-certificates apt-transport-https cowsay --no-install-recommends && \
5 | apt-get clean \
6 | && rm -rf \
7 | /var/lib/apt/lists/* \
8 | /tmp/* \
9 | /var/tmp/* \
10 | /usr/share/man \
11 | /usr/share/doc \
12 | /usr/share/doc-base
13 |
14 | # "cowsay" installs to /usr/games
15 | ENV PATH $PATH:/usr/games
16 |
17 | CMD ["cowsay"]
18 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/cost-optimisation-nudge.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {ReactNode} from 'react';
3 | import {Nudge} from './nudge';
4 |
5 | export const CostOptimisationNudge = (props: {name: string; children: ReactNode}) => (
6 |
7 | {props.children} Learn more
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/util/template/kind_test.go:
--------------------------------------------------------------------------------
1 | package template
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func Test_parseTag(t *testing.T) {
10 | t.Run("Simple", func(t *testing.T) {
11 | kind, tag := parseTag("tag")
12 | assert.Equal(t, kindSimple, kind)
13 | assert.Equal(t, "tag", tag)
14 | })
15 | t.Run("Expression", func(t *testing.T) {
16 | kind, tag := parseTag("=tag")
17 | assert.Equal(t, kindExpression, kind)
18 | assert.Equal(t, "tag", tag)
19 | })
20 | }
21 |
--------------------------------------------------------------------------------
/workflow/artifactrepositories/mocks/default.go:
--------------------------------------------------------------------------------
1 | package mocks
2 |
3 | import (
4 | "github.com/stretchr/testify/mock"
5 |
6 | wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
7 | )
8 |
9 | func DummyArtifactRepositories(repo *wfv1.ArtifactRepository) *Interface {
10 | i := &Interface{}
11 | i.On("Resolve", mock.Anything, mock.Anything, mock.Anything).Return(&wfv1.ArtifactRepositoryRefStatus{}, nil)
12 | i.On("Get", mock.Anything, mock.Anything).Return(repo, nil)
13 | return i
14 | }
15 |
--------------------------------------------------------------------------------
/workflow/metrics/workflow_condition_metric.go:
--------------------------------------------------------------------------------
1 | package metrics
2 |
3 | import (
4 | "github.com/prometheus/client_golang/prometheus"
5 | )
6 |
7 | var WorkflowConditionMetric = prometheus.NewGaugeVec(
8 | prometheus.GaugeOpts{
9 | Namespace: argoNamespace,
10 | Subsystem: workflowsSubsystem,
11 | Name: "workflow_condition",
12 | Help: "Workflow condition. https://argoproj.github.io/argo-workflows/metrics/#argo_workflows_workflow_condition",
13 | },
14 | []string{"type", "status"},
15 | )
16 |
--------------------------------------------------------------------------------
/ui/src/app/workflow-event-bindings/components/workflow-event-bindings-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {WorkflowEventBindings} from './workflow-event-bindings/workflow-event-bindings';
4 |
5 | export const WorkflowEventBindingsContainer = (props: RouteComponentProps) => (
6 |
7 |
8 |
9 | );
10 |
--------------------------------------------------------------------------------
/ui/src/models/info.ts:
--------------------------------------------------------------------------------
1 | export interface Link {
2 | name: string;
3 | scope: string;
4 | url: string;
5 | }
6 |
7 | export interface Info {
8 | managedNamespace?: string;
9 | links?: Link[];
10 | }
11 |
12 | export interface Version {
13 | version: string;
14 | }
15 |
16 | export interface GetUserInfoResponse {
17 | subject?: string;
18 | issuer?: string;
19 | groups?: string[];
20 | email?: string;
21 | emailVerified?: boolean;
22 | serviceAccountName?: string;
23 | }
24 |
--------------------------------------------------------------------------------
/util/slice/slice.go:
--------------------------------------------------------------------------------
1 | package slice
2 |
3 | func RemoveString(slice []string, element string) []string {
4 | for i, v := range slice {
5 | if element == v {
6 | ret := make([]string, 0, len(slice)-1)
7 | ret = append(ret, slice[:i]...)
8 | return append(ret, slice[i+1:]...)
9 | }
10 | }
11 | return slice
12 | }
13 |
14 | func ContainsString(slice []string, element string) bool {
15 | for _, item := range slice {
16 | if item == element {
17 | return true
18 | }
19 | }
20 | return false
21 | }
22 |
--------------------------------------------------------------------------------
/workflow/controller/estimation/dummy_estimator.go:
--------------------------------------------------------------------------------
1 | package estimation
2 |
3 | import (
4 | "time"
5 |
6 | wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
7 | )
8 |
9 | type dummyEstimator struct{}
10 |
11 | func (e *dummyEstimator) EstimateWorkflowDuration() wfv1.EstimatedDuration {
12 | return wfv1.NewEstimatedDuration(time.Second)
13 | }
14 |
15 | func (e *dummyEstimator) EstimateNodeDuration(string) wfv1.EstimatedDuration {
16 | return wfv1.NewEstimatedDuration(time.Second)
17 | }
18 |
--------------------------------------------------------------------------------
/pkg/apiclient/http1/facade_test.go:
--------------------------------------------------------------------------------
1 | package http1
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8 | )
9 |
10 | func TestFacade_do(t *testing.T) {
11 | f := Facade{baseUrl: "http://my-url"}
12 | u, err := f.url("GET", "/{namespace}/{name}", &metav1.ObjectMeta{Namespace: "my-ns", Labels: map[string]string{"foo": "1"}})
13 | if assert.NoError(t, err) {
14 | assert.Equal(t, "http://my-url/my-ns/?labels.foo=1", u.String())
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/manifests/quick-start/sso/overlays/workflow-controller-configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | data:
3 | sso: |
4 | issuer: http://dex:5556/dex
5 | clientId:
6 | name: argo-server-sso
7 | key: clientID
8 | clientSecret:
9 | name: argo-server-sso
10 | key: clientSecret
11 | redirectUrl: http://localhost:8080/oauth2/callback
12 | scopes:
13 | - groups
14 | - email
15 | rbac:
16 | enabled: true
17 | kind: ConfigMap
18 | metadata:
19 | name: workflow-controller-configmap
20 |
--------------------------------------------------------------------------------
/ui/src/app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./../../dist/app",
4 | "sourceMap": true,
5 | "noImplicitAny": true,
6 | "module": "commonjs",
7 | "target": "es5",
8 | "jsx": "react",
9 | "experimentalDecorators": true,
10 | "noUnusedLocals": true,
11 | "declaration": false,
12 | "lib": [
13 | "es2017",
14 | "dom"
15 | ]
16 | },
17 | "include": [
18 | "./**/*"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security
2 |
3 | ## Reporting Vulnerabilities
4 |
5 | Please report security vulnerabilities by e-mailing:
6 |
7 | * [Jesse_Suen@intuit.com](mailto:Jesse_Suen@intuit.com)
8 | * [Alex_Collins@intuit.com](mailto:Alex_Collins@intuit.com)
9 | * [Edward_Lee@intuit.com](mailto:Edward_Lee@intuit.com)
10 |
11 | ## Public Disclosure
12 |
13 | Security vulnerabilities will be disclosed via [release notes](docs/releasing.md).
14 |
15 | ## Vulnerability Scanning
16 |
17 | See [static code analysis](docs/static-code-analysis.md).
18 |
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/large-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: large-workflow-
5 | spec:
6 | entrypoint: large-workflow
7 | templates:
8 | - name: large-workflow
9 | steps:
10 | - - name: large-results
11 | template: large-result
12 | withItems: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
13 | - name: large-result
14 | script:
15 | image: alpine:latest
16 | command: [sh]
17 | source: dd if=/dev/urandom bs=128KB count=1 | base64
18 |
--------------------------------------------------------------------------------
/test/e2e/lintfail/invalid-spec.yaml:
--------------------------------------------------------------------------------
1 | # e2e test to ensure the controller will fail the workflow during validation.
2 | # Submit this using kubectl to bypass argo cli YAML validation. Then ensure the
3 | # proper error message is displayed
4 | apiVersion: argoproj.io/v1alpha1
5 | kind: Workflow
6 | metadata:
7 | generateName: invalid-spec-
8 | spec:
9 | entrypoint: doesnotexist
10 | templates:
11 | - name: whalesay
12 | container:
13 | image: argoproj/argosay:v1
14 | command: [cowsay]
15 | args: ["hello world"]
16 |
--------------------------------------------------------------------------------
/examples/input-artifact-raw.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: input-artifact-raw-
5 | spec:
6 | entrypoint: raw-contents
7 | templates:
8 | - name: raw-contents
9 | inputs:
10 | artifacts:
11 | - name: myfile
12 | path: /tmp/file
13 | raw:
14 | data: |
15 | this is
16 | the raw file
17 | contents
18 | container:
19 | image: alpine:latest
20 | command: [sh, -c]
21 | args: ["cat /tmp/file"]
--------------------------------------------------------------------------------
/test/e2e/testdata/artifact-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: artifact-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v2
11 | args:
12 | - echo
13 | - ":) Hello Argo!"
14 | - /tmp/main-file
15 | outputs:
16 | artifacts:
17 | - name: main-file
18 | path: /tmp/main-file
19 | archive:
20 | none: { }
21 |
--------------------------------------------------------------------------------
/examples/pod-spec-patch.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: pod-spec-patch-
5 | spec:
6 | entrypoint: whalesay
7 | arguments:
8 | parameters:
9 | - name: cpu-limit
10 | value: 100m
11 | templates:
12 | - name: whalesay
13 | podSpecPatch: '{"containers":[{"name":"main", "resources":{"limits":{"cpu": "{{workflow.parameters.cpu-limit}}" }}}]}'
14 | container:
15 | image: docker/whalesay:latest
16 | command: [cowsay]
17 | args: ["hello world"]
18 |
--------------------------------------------------------------------------------
/test/e2e/manifests/prometheus/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../../../../manifests/quick-start/minimal
6 | - ../../../../manifests/quick-start/base/prometheus
7 |
8 | patchesStrategicMerge:
9 | - ../mixins/argo-server-deployment.yaml
10 | - ../mixins/workflow-controller-configmap.yaml
11 | - ../mixins/workflow-controller-deployment.yaml
12 | - ../mixins/cluster-workflow-template-rbac.yaml
13 |
14 | commonLabels:
15 | "app.kubernetes.io/part-of": "argo"
16 |
--------------------------------------------------------------------------------
/cmd/argo/commands/auth/token.go:
--------------------------------------------------------------------------------
1 | package auth
2 |
3 | import (
4 | "fmt"
5 | "os"
6 |
7 | "github.com/spf13/cobra"
8 |
9 | "github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client"
10 | )
11 |
12 | func NewTokenCommand() *cobra.Command {
13 | return &cobra.Command{
14 | Use: "token",
15 | Short: "Print the auth token",
16 | Run: func(cmd *cobra.Command, args []string) {
17 | if len(args) != 0 {
18 | cmd.HelpFunc()(cmd, args)
19 | os.Exit(1)
20 | }
21 | fmt.Println(client.GetAuthString())
22 | },
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/cmd/argo/commands/client/conn_test.go:
--------------------------------------------------------------------------------
1 | package client
2 |
3 | import (
4 | "os"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func TestGetAuthString(t *testing.T) {
11 | _ = os.Setenv("ARGO_TOKEN", "my-token")
12 | defer func() { _ = os.Unsetenv("ARGO_TOKEN") }()
13 | assert.Equal(t, "my-token", GetAuthString())
14 | }
15 |
16 | func TestNamespace(t *testing.T) {
17 | _ = os.Setenv("ARGO_NAMESPACE", "my-ns")
18 | defer func() { _ = os.Unsetenv("ARGO_NAMESPACE") }()
19 | assert.Equal(t, "my-ns", Namespace())
20 | }
21 |
--------------------------------------------------------------------------------
/examples/dag-inline-workflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: WorkflowTemplate
3 | metadata:
4 | name: dag-inline
5 | annotations:
6 | workflows.argoproj.io/description: |
7 | This example demonstrates running a DAG with inline templates.
8 | workflows.argoproj.io/version: ">= 3.2.0"
9 | spec:
10 | entrypoint: main
11 | templates:
12 | - name: main
13 | dag:
14 | tasks:
15 | - name: a
16 | inline:
17 | container:
18 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/examples/workflow-template/hello-world.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay
7 | templates:
8 | - name: whalesay
9 | steps:
10 | - - name: call-whalesay-template
11 | templateRef:
12 | name: workflow-template-whalesay-template
13 | template: whalesay-template
14 | arguments:
15 | parameters:
16 | - name: message
17 | value: "hello world"
18 |
--------------------------------------------------------------------------------
/ui/src/models/cluster-workflow-templates.ts:
--------------------------------------------------------------------------------
1 | import * as kubernetes from 'argo-ui/src/models/kubernetes';
2 | import {WorkflowTemplateSpec} from './workflow-templates';
3 |
4 | export interface ClusterWorkflowTemplate {
5 | apiVersion?: string;
6 | kind?: string;
7 | metadata: kubernetes.ObjectMeta;
8 | spec: WorkflowTemplateSpec;
9 | }
10 |
11 | export interface ClusterWorkflowTemplateList {
12 | apiVersion?: string;
13 | kind?: string;
14 | metadata: kubernetes.ListMeta;
15 | items: ClusterWorkflowTemplate[];
16 | }
17 |
--------------------------------------------------------------------------------
/examples/artifact-repository-ref.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: artifactory-repository-ref-
5 | spec:
6 | entrypoint: main
7 | artifactRepositoryRef:
8 | key: my-key
9 | templates:
10 | - name: main
11 | container:
12 | image: docker/whalesay:latest
13 | command: [ sh, -c ]
14 | args: [ "cowsay hello world | tee /tmp/hello_world.txt" ]
15 | outputs:
16 | artifacts:
17 | - name: hello_world
18 | path: /tmp/hello_world.txt
19 |
--------------------------------------------------------------------------------
/test/e2e/functional/hello-world.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": "argoproj.io/v1alpha1",
3 | "kind": "Workflow",
4 | "metadata": {
5 | "generateName": "hello-world-"
6 | },
7 | "spec": {
8 | "entrypoint": "whalesay",
9 | "templates": [
10 | {
11 | "name": "whalesay",
12 | "container": {
13 | "image": "argoproj/argosay:v1",
14 | "command": [
15 | "cowsay"
16 | ],
17 | "args": [
18 | "hello world"
19 | ]
20 | }
21 | }
22 | ]
23 | }
24 | }
--------------------------------------------------------------------------------
/test/e2e/smoke/hello-world-workflow-tmpl.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-hello-world-
5 | spec:
6 | entrypoint: whalesay
7 | templates:
8 | - name: whalesay
9 | steps:
10 | - - name: step
11 | templateRef:
12 | name: workflow-template-whalesay-template
13 | template: whalesay-template
14 | arguments:
15 | parameters:
16 | - name: message
17 | value: "hello world"
18 |
--------------------------------------------------------------------------------
/test/e2e/testdata/output-on-input-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: output-on-input-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | container:
10 | image: argoproj/argosay:v2
11 | args: [ echo , hi, /file ]
12 | inputs:
13 | artifacts:
14 | - name: in-0
15 | path: /file
16 | raw:
17 | data: hi
18 | outputs:
19 | artifacts:
20 | - name: out-0
21 | path: /file
--------------------------------------------------------------------------------
/workflow/executor/k8sapi/k8sapi_test.go:
--------------------------------------------------------------------------------
1 | package k8sapi
2 |
3 | import (
4 | "testing"
5 | "time"
6 |
7 | "github.com/stretchr/testify/assert"
8 | )
9 |
10 | func Test_backoffOver30s(t *testing.T) {
11 | x := backoffOver30s
12 | assert.Equal(t, 1*time.Second, x.Step())
13 | assert.Equal(t, 2*time.Second, x.Step())
14 | assert.Equal(t, 4*time.Second, x.Step())
15 | assert.Equal(t, 8*time.Second, x.Step())
16 | assert.Equal(t, 16*time.Second, x.Step())
17 | assert.Equal(t, 32*time.Second, x.Step())
18 | assert.Equal(t, 64*time.Second, x.Step())
19 | }
20 |
--------------------------------------------------------------------------------
/examples/dag-inline-clusterworkflowtemplate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: ClusterWorkflowTemplate
3 | metadata:
4 | name: dag-inline
5 | annotations:
6 | workflows.argoproj.io/description: |
7 | This examples demonstrates running a DAG with inline templates.
8 | workflows.argoproj.io/version: ">= 3.2.0"
9 | spec:
10 | entrypoint: main
11 | templates:
12 | - name: main
13 | dag:
14 | tasks:
15 | - name: a
16 | inline:
17 | container:
18 | image: argoproj/argosay:v2
--------------------------------------------------------------------------------
/ui/src/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Argo
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/util/template/expression_template_test.go:
--------------------------------------------------------------------------------
1 | package template
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func Test_hasRetries(t *testing.T) {
10 | t.Run("hasRetiresInExpression", func(t *testing.T) {
11 | assert.True(t, hasRetries("retries"))
12 | assert.True(t, hasRetries("retries + 1"))
13 | assert.True(t, hasRetries("sprig(retries)"))
14 | assert.True(t, hasRetries("sprig(retries + 1) * 64"))
15 | assert.False(t, hasRetries("foo"))
16 | assert.False(t, hasRetries("retriesCustom + 1"))
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/workflow/executor/emissary/multi_reader_closer_test.go:
--------------------------------------------------------------------------------
1 | package emissary
2 |
3 | import (
4 | "bufio"
5 | "io/ioutil"
6 | "strings"
7 | "testing"
8 |
9 | "github.com/stretchr/testify/assert"
10 | )
11 |
12 | func Test_multiReaderCloser(t *testing.T) {
13 | a := ioutil.NopCloser(strings.NewReader("a"))
14 | b := ioutil.NopCloser(strings.NewReader("b"))
15 | c := newMultiReaderCloser(a, b)
16 | s := bufio.NewScanner(c)
17 | assert.True(t, s.Scan())
18 | assert.Equal(t, "ab", s.Text())
19 | assert.False(t, s.Scan())
20 | assert.NoError(t, c.Close())
21 | }
22 |
--------------------------------------------------------------------------------
/examples/retry-container.yaml:
--------------------------------------------------------------------------------
1 | # This example demonstrates the use of retries for a single container.
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: retry-container-
6 | spec:
7 | entrypoint: retry-container
8 | templates:
9 | - name: retry-container
10 | retryStrategy:
11 | limit: "10"
12 | container:
13 | image: python:alpine3.6
14 | command: ["python", -c]
15 | # fail with a 66% probability
16 | args: ["import random; import sys; exit_code = random.choice([0, 1, 1]); sys.exit(exit_code)"]
17 |
--------------------------------------------------------------------------------
/test/e2e/functional/script-with-volume.yaml:
--------------------------------------------------------------------------------
1 | # This is a test to verify volumes are supported in script templates
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: script-with-vol-
6 | spec:
7 | entrypoint: script-with-vol
8 | volumes:
9 | - name: workdir
10 | emptyDir: {}
11 | templates:
12 | - name: script-with-vol
13 | script:
14 | image: alpine:latest
15 | command: [sh]
16 | source: |
17 | ls /mnt/vol
18 | volumeMounts:
19 | - name: workdir
20 | mountPath: /mnt/vol
21 |
22 |
--------------------------------------------------------------------------------
/workflow/executor/os-specific/signal_windows.go:
--------------------------------------------------------------------------------
1 | package os_specific
2 |
3 | import (
4 | "os"
5 | "syscall"
6 | )
7 |
8 | func IsSIGCHLD(s os.Signal) bool {
9 | return false // this does not exist on windows
10 | }
11 |
12 | func Kill(pid int, s syscall.Signal) error {
13 | if pid < 0 {
14 | pid = -pid // // we cannot kill a negative process on windows
15 | }
16 | p, err := os.FindProcess(pid)
17 | if err != nil {
18 | return err
19 | }
20 | return p.Signal(s)
21 | }
22 |
23 | func Setpgid(a *syscall.SysProcAttr) {
24 | // this does not exist on windows
25 | }
26 |
--------------------------------------------------------------------------------
/test/e2e/functional/stop-terminate-2.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: stop-terminate-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | steps:
10 | - - name: A
11 | template: sleep
12 | - - name: B
13 | template: pass
14 |
15 | - name: sleep
16 | container:
17 | image: argoproj/argosay:v1
18 | command: [ sleep ]
19 | args: [ "999" ]
20 |
21 | - name: pass
22 | container:
23 | image: argoproj/argosay:v1
24 |
--------------------------------------------------------------------------------
/test/e2e/functional/workflow_teemplate_level_host_aliases.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: workflow-template-level-host-aliases-
5 | spec:
6 | entrypoint: nslookup
7 | hostAliases:
8 | - ip: "127.0.0.1"
9 | hostnames:
10 | - "argo.io"
11 |
12 | templates:
13 | - name: nslookup
14 | hostAliases:
15 | - ip: "124.0.0.1"
16 | hostnames:
17 | - "argo1.io"
18 | container:
19 | image: alpine:latest
20 | command: [sh, -c]
21 | args: ["nslookup argo.io argo1.io "]
--------------------------------------------------------------------------------
/test/e2e/testdata/output-on-mount-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: output-on-mount-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | volumes:
10 | - name: mnt
11 | emptyDir: { }
12 | container:
13 | image: argoproj/argosay:v2
14 | args: [ echo , hi, /mnt/out-0 ]
15 | volumeMounts:
16 | - name: mnt
17 | mountPath: /mnt
18 | outputs:
19 | artifacts:
20 | - name: out-0
21 | path: /mnt/out-0
--------------------------------------------------------------------------------
/test/e2e/testdata/sidecar-injected-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: sidecar-injected-
5 | spec:
6 | entrypoint: main
7 | podSpecPatch: |
8 | terminationGracePeriodSeconds: 3
9 | containers:
10 | - name: wait
11 | - name: main
12 | - name: sidecar
13 | image: argoproj/argosay:v1
14 | command:
15 | - sh
16 | - -c
17 | args:
18 | - "sleep 999"
19 | templates:
20 | - name: main
21 | container:
22 | image: argoproj/argosay:v1
--------------------------------------------------------------------------------
/ui/src/app/shared/components/graph/layout.ts:
--------------------------------------------------------------------------------
1 | import {layoutGraphFast} from './fast-layout';
2 | import {layoutGraphPretty} from './pretty-layout';
3 | import {Graph, Node} from './types';
4 |
5 | export const layout = (graph: Graph, nodeSize: number, horizontal: boolean, hidden: (id: Node) => boolean, fast: boolean) => {
6 | // TODO - we should not re-layout the graph if options have not changed
7 | // if (Array.from(graph.nodes).find(([, l]) => l.x === undefined)) {
8 | (fast ? layoutGraphFast : layoutGraphPretty)(graph, nodeSize, horizontal, hidden);
9 | // }
10 | };
11 |
--------------------------------------------------------------------------------
/workflow/artifacts/common/common.go:
--------------------------------------------------------------------------------
1 | package common
2 |
3 | import "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
4 |
5 | // ArtifactDriver is the interface for loading and saving of artifacts
6 | type ArtifactDriver interface {
7 | // Load accepts an artifact source URL and places it at specified path
8 | Load(inputArtifact *v1alpha1.Artifact, path string) error
9 |
10 | // Save uploads the path to artifact destination
11 | Save(path string, outputArtifact *v1alpha1.Artifact) error
12 |
13 | ListObjects(artifact *v1alpha1.Artifact) ([]string, error)
14 | }
15 |
--------------------------------------------------------------------------------
/persist/sqldb/db_type.go:
--------------------------------------------------------------------------------
1 | package sqldb
2 |
3 | import (
4 | "database/sql"
5 |
6 | "github.com/go-sql-driver/mysql"
7 | "upper.io/db.v3"
8 | )
9 |
10 | type dbType string
11 |
12 | const (
13 | MySQL dbType = "mysql"
14 | Postgres dbType = "postgres"
15 | )
16 |
17 | func dbTypeFor(session db.Database) dbType {
18 | switch session.Driver().(*sql.DB).Driver().(type) {
19 | case *mysql.MySQLDriver:
20 | return MySQL
21 | }
22 | return Postgres
23 | }
24 |
25 | func (t dbType) intType() string {
26 | if t == MySQL {
27 | return "signed"
28 | }
29 | return "int"
30 | }
31 |
--------------------------------------------------------------------------------
/test/e2e/functional/stop-terminate.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: stop-terminate-
5 | spec:
6 | entrypoint: main
7 | onExit: exit
8 | templates:
9 | - name: main
10 | dag:
11 | tasks:
12 | - name: A
13 | template: echo
14 | onExit: exit
15 |
16 | - name: echo
17 | container:
18 | image: argoproj/argosay:v1
19 | command: [ sleep ]
20 | args: [ "999" ]
21 |
22 | - name: exit
23 | container:
24 | image: argoproj/argosay:v1
25 |
--------------------------------------------------------------------------------
/test/e2e/lintfail/malformed-spec.yaml:
--------------------------------------------------------------------------------
1 | # This spec cannot be unmarshalled to a workflow (entrypoint should not be an array)
2 | # The controller should still be able to handle this case and mark this workflow failed.
3 | # Submit this using kubectl create -f instead of argo cli.
4 | apiVersion: argoproj.io/v1alpha1
5 | kind: Workflow
6 | metadata:
7 | generateName: invalid-spec2-
8 | spec:
9 | entrypoint: [thisshouldnotbeanarray]
10 | templates:
11 | - name: whalesay
12 | container:
13 | image: argoproj/argosay:v1
14 | command: [cowsay]
15 | args: ["hello world"]
16 |
--------------------------------------------------------------------------------
/ui/src/app/shared/components/timestamp.tsx:
--------------------------------------------------------------------------------
1 | import {Ticker} from 'argo-ui';
2 | import * as React from 'react';
3 | import {ago} from '../duration';
4 |
5 | export const Timestamp = ({date}: {date: Date | string | number}) => {
6 | return (
7 |
8 | {date === null || date === undefined ? (
9 | '-'
10 | ) : (
11 |
12 | {() => ago(new Date(date))}
13 |
14 | )}
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/examples/pod-spec-yaml-patch.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: pod-spec-patch-
5 | spec:
6 | entrypoint: whalesay
7 | arguments:
8 | parameters:
9 | - name: mem-limit
10 | value: 100Mi
11 | podSpecPatch: |
12 | containers:
13 | - name: main
14 | resources:
15 | limits:
16 | memory: "{{workflow.parameters.mem-limit}}"
17 | templates:
18 | - name: whalesay
19 | container:
20 | image: docker/whalesay:latest
21 | command: [cowsay]
22 | args: ["hello world"]
23 |
--------------------------------------------------------------------------------
/manifests/namespace-install/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../base
6 | - ./argo-server-rbac
7 | - ./workflow-controller-rbac
8 |
9 | patchesJson6902:
10 | - target:
11 | version: v1
12 | group: apps
13 | kind: Deployment
14 | name: workflow-controller
15 | path: ./overlays/workflow-controller-deployment.yaml
16 | - target:
17 | version: v1
18 | group: apps
19 | kind: Deployment
20 | name: argo-server
21 | path: ./overlays/argo-server-deployment.yaml
22 |
--------------------------------------------------------------------------------
/test/e2e/cron/basic.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: CronWorkflow
3 | metadata:
4 | name: test-cron-wf-basic
5 | labels:
6 | workflows.argoproj.io/test: "true"
7 | spec:
8 | schedule: "* * * * *"
9 | concurrencyPolicy: "Allow"
10 | startingDeadlineSeconds: 0
11 | successfulJobsHistoryLimit: 4
12 | failedJobsHistoryLimit: 2
13 | workflowMetadata:
14 | labels:
15 | workflows.argoproj.io/test: "true"
16 | workflowSpec:
17 | entrypoint: main
18 | templates:
19 | - name: main
20 | container:
21 | image: argoproj/argosay:v2
22 |
--------------------------------------------------------------------------------
/ui/src/app/shared/base.ts:
--------------------------------------------------------------------------------
1 | function baseUrl(): string {
2 | const base = document.querySelector('base');
3 | return base ? base.getAttribute('href') : '/';
4 | }
5 |
6 | export function uiUrl(uiPath: string): string {
7 | return baseUrl() + uiPath;
8 | }
9 |
10 | export function uiUrlWithParams(uiPath: string, params: string[]): string {
11 | if (!params) {
12 | return uiUrl(uiPath);
13 | }
14 | return baseUrl() + uiPath + '?' + params.join('&');
15 | }
16 |
17 | export function apiUrl(apiPath: string): string {
18 | return `${baseUrl()}${apiPath}`;
19 | }
20 |
--------------------------------------------------------------------------------
/examples/retry-container-to-completion.yaml:
--------------------------------------------------------------------------------
1 | # This example demonstrates the use of infinite retries for running the container to completion.
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: retry-to-completion-
6 | spec:
7 | entrypoint: retry-to-completion
8 | templates:
9 | - name: retry-to-completion
10 | retryStrategy: {}
11 | container:
12 | image: python
13 | command: ["python", "-c"]
14 | # fail with a 80% probability
15 | args: ["import random; import sys; exit_code = random.choice(range(0, 5)); sys.exit(exit_code)"]
16 |
--------------------------------------------------------------------------------
/test/e2e/functional/dag-with-retries.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: dag-with-retries-
5 | spec:
6 | entrypoint: dag-with-retries
7 | templates:
8 | - name: dag-with-retries
9 | dag:
10 | tasks:
11 | -
12 | name: step1
13 | template: randomly-fail
14 | inputs: {}
15 | metadata: {}
16 | outputs: {}
17 | - name: randomly-fail
18 | retryStrategy:
19 | limit: 20
20 | container:
21 | image: alpine:latest
22 | command: [sh, -c]
23 | args: ["exit $(( ${RANDOM} % 5 ))"]
24 |
--------------------------------------------------------------------------------
/ui/src/app/sensors/components/sensors-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {SensorDetails} from './sensor-details/sensor-details';
4 | import {SensorList} from './sensor-list/sensor-list';
5 |
6 | export const SensorsContainer = (props: RouteComponentProps) => (
7 |
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/workflow/artifacts/s3/errors_test.go:
--------------------------------------------------------------------------------
1 | package s3
2 |
3 | import (
4 | "errors"
5 | "testing"
6 |
7 | "github.com/minio/minio-go/v7"
8 | "github.com/stretchr/testify/assert"
9 | )
10 |
11 | func TestIsTransientOSSErr(t *testing.T) {
12 | for _, errCode := range s3TransientErrorCodes {
13 | err := minio.ErrorResponse{Code: errCode}
14 | assert.True(t, isTransientS3Err(err))
15 | }
16 |
17 | err := minio.ErrorResponse{Code: "NoSuchBucket"}
18 | assert.False(t, isTransientS3Err(err))
19 |
20 | nonOSSErr := errors.New("UnseenError")
21 | assert.False(t, isTransientS3Err(nonOSSErr))
22 | }
23 |
--------------------------------------------------------------------------------
/examples/hello-world.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: hello-world-
5 | labels:
6 | workflows.argoproj.io/archive-strategy: "false"
7 | annotations:
8 | workflows.argoproj.io/description: |
9 | This is a simple hello world example.
10 | You can also run it in Python: https://couler-proj.github.io/couler/examples/#hello-world
11 | spec:
12 | entrypoint: whalesay
13 | templates:
14 | - name: whalesay
15 | container:
16 | image: docker/whalesay:latest
17 | command: [cowsay]
18 | args: ["hello world"]
19 |
--------------------------------------------------------------------------------
/examples/init-container.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: init-container-
5 | spec:
6 | entrypoint: init-container-example
7 | templates:
8 | - name: init-container-example
9 | container:
10 | image: alpine:latest
11 | command: ["echo", "bye"]
12 | volumeMounts:
13 | - name: foo
14 | mountPath: /foo
15 | initContainers:
16 | - name: hello
17 | image: alpine:latest
18 | command: ["echo", "hello"]
19 | mirrorVolumeMounts: true
20 | volumes:
21 | - name: foo
22 | emptyDir: {}
23 |
--------------------------------------------------------------------------------
/examples/retry-script.yaml:
--------------------------------------------------------------------------------
1 | # This example demonstrates the use of retries for a single script.
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: retry-script-
6 | spec:
7 | entrypoint: retry-script
8 | templates:
9 | - name: retry-script
10 | retryStrategy:
11 | limit: "10"
12 | script:
13 | image: python:alpine3.6
14 | command: ["python"]
15 | # fail with a 66% probability
16 | source: |
17 | import random;
18 | import sys;
19 | exit_code = random.choice([0, 1, 1]);
20 | sys.exit(exit_code)
21 |
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/exit-handler-failed.yaml:
--------------------------------------------------------------------------------
1 | # Test to make sure when exit handler fails it overrides the workflow status as failed
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: exit-handlers-
6 | spec:
7 | entrypoint: pass
8 | onExit: fail
9 | templates:
10 | # primary workflow template
11 | - name: pass
12 | container:
13 | image: alpine:latest
14 | command: [sh, -c]
15 | args: ["exit 0"]
16 |
17 | - name: fail
18 | container:
19 | image: alpine:latest
20 | command: [sh, -c]
21 | args: ["exit 1"]
22 |
--------------------------------------------------------------------------------
/test/e2e/testdata/retry-omit.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: retry-omit-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - dag:
9 | tasks:
10 | - name: F
11 | template: fail
12 | - name: O
13 | depends: F
14 | template: pass
15 | name: main
16 | - name: pass
17 | container:
18 | image: argoproj/argosay:v2
19 | - name: fail
20 | container:
21 | args:
22 | - exit
23 | - "1"
24 | image: argoproj/argosay:v2
25 |
26 |
--------------------------------------------------------------------------------
/server/types/clients.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | eventsource "github.com/argoproj/argo-events/pkg/client/eventsource/clientset/versioned"
5 | sensor "github.com/argoproj/argo-events/pkg/client/sensor/clientset/versioned"
6 | "k8s.io/client-go/dynamic"
7 | "k8s.io/client-go/kubernetes"
8 |
9 | workflow "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned"
10 | )
11 |
12 | type Clients struct {
13 | Dynamic dynamic.Interface
14 | Workflow workflow.Interface
15 | Sensor sensor.Interface
16 | EventSource eventsource.Interface
17 | Kubernetes kubernetes.Interface
18 | }
19 |
--------------------------------------------------------------------------------
/test/e2e/functional/retry-script.yaml:
--------------------------------------------------------------------------------
1 | # This example demonstrates the use of retries for a single script.
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: retry-script-
6 | spec:
7 | entrypoint: retry-script
8 | templates:
9 | - name: retry-script
10 | retryStrategy:
11 | limit: 10
12 | script:
13 | image: python:alpine3.6
14 | command: ["python"]
15 | # fail with a 66% probability
16 | source: |
17 | import random;
18 | import sys;
19 | exit_code = random.choice([0, 1, 1]);
20 | sys.exit(exit_code)
21 |
--------------------------------------------------------------------------------
/test/e2e/functional/script-with-input-art.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: script-with-input-artifact-
5 | spec:
6 | entrypoint: script-with-input-artifact
7 | templates:
8 | - name: script-with-input-artifact
9 | inputs:
10 | artifacts:
11 | - name: kubectl
12 | path: /bin/kubectl
13 | http:
14 | url: https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl
15 | script:
16 | image: alpine:latest
17 | command: [sh]
18 | source: |
19 | ls /bin/kubectl
20 |
--------------------------------------------------------------------------------
/ui/src/app/shared/debounce.ts:
--------------------------------------------------------------------------------
1 | export default function debounce any>(fn: T, debounceMs: number) {
2 | let timer: number | null = null;
3 |
4 | const cancel = () => {
5 | if (timer !== null) {
6 | clearTimeout(timer);
7 | timer = null;
8 | }
9 | };
10 |
11 | const debouncedFn = (...args: Parameters) => {
12 | cancel();
13 |
14 | timer = window.setTimeout(() => {
15 | fn(...args);
16 | timer = null;
17 | }, debounceMs);
18 | };
19 |
20 | return [debouncedFn, cancel];
21 | }
22 |
--------------------------------------------------------------------------------
/cmd/argo/commands/template/root.go:
--------------------------------------------------------------------------------
1 | package template
2 |
3 | import (
4 | "github.com/spf13/cobra"
5 | )
6 |
7 | func NewTemplateCommand() *cobra.Command {
8 | command := &cobra.Command{
9 | Use: "template",
10 | Short: "manipulate workflow templates",
11 | Run: func(cmd *cobra.Command, args []string) {
12 | cmd.HelpFunc()(cmd, args)
13 | },
14 | }
15 |
16 | command.AddCommand(NewGetCommand())
17 | command.AddCommand(NewListCommand())
18 | command.AddCommand(NewCreateCommand())
19 | command.AddCommand(NewDeleteCommand())
20 | command.AddCommand(NewLintCommand())
21 |
22 | return command
23 | }
24 |
--------------------------------------------------------------------------------
/examples/synchronization-mutex-wf-level.yaml:
--------------------------------------------------------------------------------
1 | # This example demonstrates the use of a Synchronization Mutex lock on workflow execution. Mutex lock limits
2 | # only one of the workflow execution in the namespace which has same Mutex lock.
3 | apiVersion: argoproj.io/v1alpha1
4 | kind: Workflow
5 | metadata:
6 | generateName: synchronization-wf-level-
7 | spec:
8 | entrypoint: whalesay
9 | synchronization:
10 | mutex:
11 | name: test
12 | templates:
13 | - name: whalesay
14 | container:
15 | image: docker/whalesay:latest
16 | command: [cowsay]
17 | args: ["hello world"]
18 |
--------------------------------------------------------------------------------
/manifests/quick-start/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - ../../namespace-install
6 | - minio
7 | - webhooks
8 | - argo-server-sso-secret.yaml
9 | - workflow-role.yaml
10 | - kubelet-executor-clusterrole.yaml
11 | - kubelet-executor-default-clusterrolebinding.yaml
12 | - workflow-default-rolebinding.yaml
13 | - cluster-workflow-template-rbac.yaml
14 | - artifact-repositories-configmap.yaml
15 |
16 | patchesStrategicMerge:
17 | - overlays/workflow-controller-configmap.yaml
18 | - overlays/argo-server-deployment.yaml
19 |
--------------------------------------------------------------------------------
/test/e2e/testdata/input-on-mount-workflow.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: input-on-mount-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | volumes:
10 | - name: mnt
11 | emptyDir: { }
12 | container:
13 | image: argoproj/argosay:v2
14 | args: [ cat , /mnt/in-0 ]
15 | volumeMounts:
16 | - name: mnt
17 | mountPath: /mnt
18 | inputs:
19 | artifacts:
20 | - name: in-0
21 | path: /mnt/in-0
22 | raw:
23 | data: hi
--------------------------------------------------------------------------------
/test/e2e/testdata/same-input-output-path-optional.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: optional-input-output-artifact-same-location-
5 | spec:
6 | entrypoint: main
7 | templates:
8 | - name: main
9 | inputs:
10 | artifacts:
11 | - name: file
12 | path: /tmp/file1.txt
13 | optional: true
14 | container:
15 | image: argoproj/argosay:v2
16 | args: ["echo", "test", "/tmp/file1.txt"]
17 | outputs:
18 | artifacts:
19 | - name: file
20 | path: /tmp/file1.txt
21 |
22 |
--------------------------------------------------------------------------------
/ui/src/app/pipelines/components/pipeline-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {PipelineDetails} from './pipeline-details/pipeline-details';
4 | import {PipelineList} from './pipeline-list/pipeline-list';
5 |
6 | export const PipelineContainer = (props: RouteComponentProps) => (
7 |
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/workflow/controller/http_template.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
5 | )
6 |
7 | func (woc *wfOperationCtx) executeHTTPTemplate(nodeName string, templateScope string, tmpl *wfv1.Template, orgTmpl wfv1.TemplateReferenceHolder, opts *executeTemplateOpts) *wfv1.NodeStatus {
8 | node := woc.wf.GetNodeByName(nodeName)
9 | if node == nil {
10 | node = woc.initializeExecutableNode(nodeName, wfv1.NodeTypeHTTP, templateScope, tmpl, orgTmpl, opts.boundaryID, wfv1.NodePending)
11 | woc.taskSet[node.ID] = *tmpl
12 | }
13 | return node
14 | }
15 |
--------------------------------------------------------------------------------
/test/e2e/testdata/storage-limit.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | name: storage-quota-limit
5 | spec:
6 | entrypoint: wait
7 | volumeClaimTemplates: # define volume, same syntax as k8s Pod spec
8 | - metadata:
9 | name: workdir1 # name of volume claim
10 | spec:
11 | accessModes: [ "ReadWriteMany" ]
12 | resources:
13 | requests:
14 | storage: 20Mi
15 |
16 | templates:
17 | - name: wait
18 | script:
19 | image: argoproj/argosay:v2
20 | args: [echo, ":) Hello Argo!"]
21 |
--------------------------------------------------------------------------------
/ui/src/app/workflows/components/workflows-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {WorkflowDetails} from './workflow-details/workflow-details';
4 | import {WorkflowsList} from './workflows-list/workflows-list';
5 |
6 | export const WorkflowsContainer = (props: RouteComponentProps) => (
7 |
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/workflow/controller/config_test.go:
--------------------------------------------------------------------------------
1 | package controller
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 |
8 | "github.com/argoproj/argo-workflows/v3/config"
9 | )
10 |
11 | func TestUpdateConfig(t *testing.T) {
12 | cancel, controller := newController()
13 | defer cancel()
14 | err := controller.updateConfig(&config.Config{ExecutorImage: "argoexec:latest"})
15 | assert.NoError(t, err)
16 | assert.NotNil(t, controller.Config)
17 | assert.NotNil(t, controller.archiveLabelSelector)
18 | assert.NotNil(t, controller.wfArchive)
19 | assert.NotNil(t, controller.offloadNodeStatusRepo)
20 | }
21 |
--------------------------------------------------------------------------------
/workflow/sync/chain_throttler_test.go:
--------------------------------------------------------------------------------
1 | package sync
2 |
3 | import (
4 | "testing"
5 | "time"
6 |
7 | "github.com/stretchr/testify/assert"
8 |
9 | "github.com/argoproj/argo-workflows/v3/workflow/sync/mocks"
10 | )
11 |
12 | func TestChainThrottler(t *testing.T) {
13 | m := &mocks.Throttler{}
14 | m.On("Add", "foo", int32(1), time.Time{}).Return()
15 | m.On("Admit", "foo").Return(false)
16 | m.On("Remove", "foo").Return()
17 |
18 | c := ChainThrottler{m}
19 | c.Add("foo", 1, time.Time{})
20 | assert.False(t, c.Admit("foo"))
21 | c.Remove("foo")
22 |
23 | assert.True(t, ChainThrottler{}.Admit("foo"))
24 | }
25 |
--------------------------------------------------------------------------------
/ui/src/models/pipeline.ts:
--------------------------------------------------------------------------------
1 | import {ListMeta, ObjectMeta, Time, WatchEvent} from 'argo-ui/src/models/kubernetes';
2 |
3 | export interface Pipeline {
4 | metadata: ObjectMeta;
5 | status?: {
6 | conditions?: {type?: string}[];
7 | phase?: string;
8 | message?: string;
9 | };
10 | }
11 |
12 | export interface PipelineList {
13 | metadata: ListMeta;
14 | items: Pipeline[];
15 | }
16 |
17 | export interface LogEntry {
18 | namespace: string;
19 | stepName?: string;
20 | time: Time;
21 | msg: string;
22 | }
23 |
24 | export type PipelineWatchEvent = WatchEvent;
25 |
--------------------------------------------------------------------------------
/util/wait/backoff.go:
--------------------------------------------------------------------------------
1 | package wait
2 |
3 | import (
4 | "fmt"
5 |
6 | "k8s.io/apimachinery/pkg/util/wait"
7 | )
8 |
9 | // the underlying ExponentialBackoff does not retain the underlying error
10 | // so this addresses this
11 | func Backoff(b wait.Backoff, f func() (bool, error)) error {
12 | var err error
13 | waitErr := wait.ExponentialBackoff(b, func() (bool, error) {
14 | var done bool
15 | done, err = f()
16 | return done, nil
17 | })
18 | if waitErr != nil {
19 | if err != nil {
20 | return fmt.Errorf("%v: %v", waitErr, err)
21 | } else {
22 | return waitErr
23 | }
24 | }
25 | return err
26 | }
27 |
--------------------------------------------------------------------------------
/ui/src/models/workflow-templates.ts:
--------------------------------------------------------------------------------
1 | import * as kubernetes from 'argo-ui/src/models/kubernetes';
2 | import {WorkflowSpec} from './workflows';
3 |
4 | export interface WorkflowTemplate {
5 | apiVersion?: string;
6 | kind?: string;
7 | metadata: kubernetes.ObjectMeta;
8 | spec: WorkflowTemplateSpec;
9 | }
10 |
11 | export interface WorkflowTemplateSpec extends WorkflowSpec {
12 | workflowMetadata?: kubernetes.ObjectMeta;
13 | }
14 |
15 | export interface WorkflowTemplateList {
16 | apiVersion?: string;
17 | kind?: string;
18 | metadata: kubernetes.ListMeta;
19 | items: WorkflowTemplate[];
20 | }
21 |
--------------------------------------------------------------------------------
/docs/kubectl.md:
--------------------------------------------------------------------------------
1 | # Kubectl
2 |
3 | You can also create Workflows directly with `kubectl`. However, the Argo CLI offers extra features
4 | that `kubectl` does not, such as YAML validation, workflow visualization, parameter passing, retries
5 | and resubmits, suspend and resume, and more.
6 |
7 | ```sh
8 | kubectl create -n argo -f https://raw.githubusercontent.com/argoproj/argo-workflows/master/examples/hello-world.yaml
9 | kubectl get wf -n argo
10 | kubectl get wf hello-world-xxx -n argo
11 | kubectl get po -n argo --selector=workflows.argoproj.io/workflow=hello-world-xxx
12 | kubectl logs hello-world-yyy -c main -n argo
13 | ```
14 |
15 |
--------------------------------------------------------------------------------
/util/template/validate.go:
--------------------------------------------------------------------------------
1 | package template
2 |
3 | import (
4 | "io"
5 | "io/ioutil"
6 |
7 | "github.com/valyala/fasttemplate"
8 | )
9 |
10 | func Validate(s string, validator func(tag string) error) error {
11 | t, err := fasttemplate.NewTemplate(s, prefix, suffix)
12 | if err != nil {
13 | return err
14 | }
15 | _, err = t.ExecuteFunc(ioutil.Discard, func(w io.Writer, tag string) (int, error) {
16 | kind, _ := parseTag(tag)
17 | switch kind {
18 | case kindExpression:
19 | return 0, nil // we do not validate expression templates
20 | default:
21 | return 0, validator(tag)
22 | }
23 | })
24 | return err
25 | }
26 |
--------------------------------------------------------------------------------
/examples/timeouts-step.yaml:
--------------------------------------------------------------------------------
1 | # To enforce a timeout to a template, specify a value for activeDeadlineSeconds.
2 | # This value represents the duration in seconds relative to the pod StartTime
3 | # that the pod may be active on a node before the system actively tries to
4 | # terminate it. This field is only applicable to container and script templates.
5 | apiVersion: argoproj.io/v1alpha1
6 | kind: Workflow
7 | metadata:
8 | generateName: timeouts-step-
9 | spec:
10 | entrypoint: sleep
11 | templates:
12 | - name: sleep
13 | container:
14 | image: debian:9.5-slim
15 | command: [sleep, 1d]
16 | activeDeadlineSeconds: 10
17 |
--------------------------------------------------------------------------------
/test/e2e/expectedfailures/unschedulable.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: unschedulable-
5 | spec:
6 | entrypoint: unschedulable
7 | templates:
8 | - name: unschedulable
9 | steps:
10 | - - name: image-pull-fail
11 | template: image-pull-fail
12 | - name: bad-node-selector
13 | template: bad-node-selector
14 |
15 | - name: image-pull-fail
16 | container:
17 | image: alpine:doesntexist
18 |
19 | - name: bad-node-selector
20 | nodeSelector:
21 | beta.kubernetes.io/arch: no-such-arch
22 | container:
23 | image: alpine:latest
--------------------------------------------------------------------------------
/test/e2e/manifests/stress/workflow-controller-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: workflow-controller
5 | spec:
6 | template:
7 | spec:
8 | containers:
9 | - name: workflow-controller
10 | args:
11 | - --loglevel=warn
12 | - --configmap=workflow-controller-configmap
13 | - --executor-image=argoproj/argoexec:latest
14 | - --namespaced
15 | - --burst=2048
16 | - --qps=512
17 | - --workflow-workers=128
18 | env:
19 | - name: PNS_PRIVILEGED
20 | value: "true"
--------------------------------------------------------------------------------
/ui/src/app/event-flow/components/event-flow-details/event-flow-page.scss:
--------------------------------------------------------------------------------
1 | @import 'node_modules/argo-ui/src/styles/config';
2 |
3 | @keyframes flowing {
4 | 50% {
5 | stroke: $argo-running-color;
6 | }
7 | to {
8 | stroke-dashoffset: -128;
9 | }
10 | }
11 |
12 | .graph {
13 | overflow: scroll;
14 | }
15 |
16 | .graph.events {
17 | .node {
18 | &.Ready {
19 | .bg {
20 | fill: $argo-running-color;
21 | }
22 | }
23 | }
24 |
25 | .edge {
26 | path {
27 | stroke-dasharray: 8;
28 | }
29 |
30 | &.flow path {
31 | animation: flowing 3s ease-in-out none;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/ui/src/app/shared/context.ts:
--------------------------------------------------------------------------------
1 | import {AppContext as ArgoAppContext, NavigationApi, NotificationsApi, PopupApi} from 'argo-ui';
2 | import {History} from 'history';
3 | import * as React from 'react';
4 |
5 | export type AppContext = ArgoAppContext & {apis: {popup: PopupApi; notifications: NotificationsApi; navigation: NavigationApi; baseHref: string}};
6 |
7 | export interface ContextApis {
8 | popup: PopupApi;
9 | notifications: NotificationsApi;
10 | navigation: NavigationApi;
11 | history: History;
12 | }
13 |
14 | export const Context = React.createContext(null);
15 | export const {Provider, Consumer} = Context;
16 |
--------------------------------------------------------------------------------
/pkg/apis/workflow/v1alpha1/workflow_template_types_test.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | import (
4 | "sort"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9 | )
10 |
11 | func TestWorkflowTemplates(t *testing.T) {
12 | tmpls := WorkflowTemplates{
13 | {ObjectMeta: v1.ObjectMeta{Name: "1"}},
14 | {ObjectMeta: v1.ObjectMeta{Name: "2"}},
15 | {ObjectMeta: v1.ObjectMeta{Name: "0"}},
16 | }
17 | sort.Sort(tmpls)
18 | if assert.Len(t, tmpls, 3) {
19 | assert.Equal(t, "0", tmpls[0].Name)
20 | assert.Equal(t, "1", tmpls[1].Name)
21 | assert.Equal(t, "2", tmpls[2].Name)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/workflow/hydrator/fake/noop.go:
--------------------------------------------------------------------------------
1 | package fake
2 |
3 | import (
4 | wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
5 | "github.com/argoproj/argo-workflows/v3/workflow/hydrator"
6 | )
7 |
8 | // this test fake does nothing
9 | type noop struct{}
10 |
11 | func (i noop) IsHydrated(wf *wfv1.Workflow) bool {
12 | return true
13 | }
14 |
15 | func (i noop) Hydrate(wf *wfv1.Workflow) error {
16 | return nil
17 | }
18 |
19 | func (i noop) Dehydrate(wf *wfv1.Workflow) error {
20 | return nil
21 | }
22 |
23 | func (i noop) HydrateWithNodes(wf *wfv1.Workflow, nodes wfv1.Nodes) {}
24 |
25 | var Noop hydrator.Interface = &noop{}
26 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Tips:
2 |
3 | * Maybe add you organization to [USERS.md](https://github.com/argoproj/argo-workflows/blob/master/USERS.md).
4 | * Your PR needs to pass the required checks before it can be approved. If the check is not required (e.g. E2E tests) it does not need to pass
5 | * Sign-off your commits to pass the DCO check: `git commit --signoff`.
6 | * Run `make pre-commit -B` to fix codegen or lint problems.
7 | * Say how how you tested your changes. If you changed the UI, attach screenshots.
8 | * If changes were requested, and you've made them, then dismis the review to get it looked at again.
9 | * You can ask for help!
10 |
--------------------------------------------------------------------------------
/docs/workflow-creator.md:
--------------------------------------------------------------------------------
1 | # Workflow Creator
2 |
3 | 
4 |
5 | > v2.9 and after
6 |
7 | If you create your workflow via the CLI or UI, an attempt will be made to label it with the user who created it
8 |
9 | ```yaml
10 | apiVersion: argoproj.io/v1alpha1
11 | kind: Workflow
12 | metadata:
13 | name: my-wf
14 | labels:
15 | workflows.argoproj.io/creator: admin
16 | # labels must be DNS formatted, so the "@" is replaces by '.at.'
17 | workflows.argoproj.io/creator-email: admin.at.your.org
18 | ```
19 |
20 | !!! NOTE
21 | Labels only contain `[-_.0-9a-zA-Z]`, so any other characters will be turned into `-`.
22 |
--------------------------------------------------------------------------------
/examples/validation_test.go:
--------------------------------------------------------------------------------
1 | package validation
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 | "testing"
7 | )
8 |
9 | func TestValidateExamples(t *testing.T) {
10 | failures, err := ValidateArgoYamlRecursively(".", []string{"testvolume.yaml", "simple-parameters-configmap.yaml"})
11 | if err != nil {
12 | t.Errorf("There was an error: %s", err)
13 | }
14 | if len(failures) > 0 {
15 | fails := []string{}
16 | for path, fail := range failures {
17 | fails = append(fails, fmt.Sprintf("Validation failed - %s: %s", path, strings.Join(fail, "\n")))
18 | }
19 | t.Errorf("There were validation failures:\n%s", strings.Join(fails, "\n"))
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ui/src/app/event-sources/components/event-source-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {EventSourceDetails} from './event-source-details/event-source-details';
4 | import {EventSourceList} from './event-source-list/event-source-list';
5 |
6 | export const EventSourceContainer = (props: RouteComponentProps) => (
7 |
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/util/python/python.go:
--------------------------------------------------------------------------------
1 | package python
2 |
3 | import (
4 | "fmt"
5 |
6 | _ "github.com/go-python/gpython/builtin"
7 | "github.com/go-python/gpython/compile"
8 | "github.com/go-python/gpython/py"
9 | "github.com/go-python/gpython/vm"
10 | )
11 |
12 | func Run(s string, globals map[string]interface{}) error {
13 | x, err := compile.Compile(s, "", "exec", 0, true)
14 | if err != nil {
15 | return err
16 | }
17 | m := py.NewModule("__main__", "", nil, dict(globals))
18 | code, ok := x.(*py.Code)
19 | if !ok {
20 | return fmt.Errorf("obj cannot be cast to code")
21 | }
22 | _, err = vm.EvalCode(code, m.Globals, nil)
23 | return err
24 | }
25 |
--------------------------------------------------------------------------------
/workflow/executor/emissary/multi_reader_closer.go:
--------------------------------------------------------------------------------
1 | package emissary
2 |
3 | import (
4 | "io"
5 | )
6 |
7 | type multiReaderCloser struct {
8 | io.Reader
9 | closer []io.ReadCloser
10 | }
11 |
12 | func newMultiReaderCloser(x ...io.ReadCloser) io.ReadCloser {
13 | var readers []io.Reader
14 | for _, r := range x {
15 | readers = append(readers, r)
16 | }
17 | return &multiReaderCloser{
18 | Reader: io.MultiReader(readers...),
19 | closer: x,
20 | }
21 | }
22 |
23 | func (m *multiReaderCloser) Close() error {
24 | for _, c := range m.closer {
25 | if err := c.Close(); err != nil {
26 | return err
27 | }
28 | }
29 | return nil
30 | }
31 |
--------------------------------------------------------------------------------
/examples/parallelism-limit.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: argoproj.io/v1alpha1
2 | kind: Workflow
3 | metadata:
4 | generateName: parallelism-limit-
5 | spec:
6 | entrypoint: parallelism-limit
7 | parallelism: 2
8 | templates:
9 | - name: parallelism-limit
10 | steps:
11 | - - name: sleep
12 | template: sleep
13 | withItems:
14 | - this
15 | - workflow
16 | - should
17 | - take
18 | - at
19 | - least
20 | - 60
21 | - seconds
22 | - to
23 | - complete
24 |
25 | - name: sleep
26 | container:
27 | image: alpine:latest
28 | command: [sh, -c, sleep 10]
29 |
--------------------------------------------------------------------------------
/test/e2e/images/argosay/v2/argosay:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -eu
3 |
4 | case ${1:-} in
5 | '')
6 | echo "hello argo"
7 | ;;
8 | assert_contains)
9 | grep -F "$3" "$2"
10 | ;;
11 | cat)
12 | cat "$2"
13 | ;;
14 | echo)
15 | case $# in
16 | 1) echo "hello argo" ;;
17 | 2) echo "$2" ;;
18 | 3)
19 | mkdir -p "$(dirname $3)"
20 | echo "$2" > "$3"
21 | sleep 0.1 ;# sleep so the PNS executor has time to secure root file
22 | ;;
23 | default)
24 | exit 1
25 | esac
26 | ;;
27 | exit)
28 | exit "${2:-0}"
29 | ;;
30 | sleep)
31 | sleep "$2"
32 | ;;
33 | *)
34 | exit 1
35 | esac
--------------------------------------------------------------------------------
/examples/input-artifact-http.yaml:
--------------------------------------------------------------------------------
1 | # Example of using a hard-wired artifact location from a HTTP URL.
2 | apiVersion: argoproj.io/v1alpha1
3 | kind: Workflow
4 | metadata:
5 | generateName: input-artifact-http-
6 | spec:
7 | entrypoint: http-artifact-example
8 | templates:
9 | - name: http-artifact-example
10 | inputs:
11 | artifacts:
12 | - name: kubectl
13 | path: /bin/kubectl
14 | mode: 0755
15 | http:
16 | url: https://storage.googleapis.com/kubernetes-release/release/v1.8.0/bin/linux/amd64/kubectl
17 | container:
18 | image: debian:9.4
19 | command: [sh, -c]
20 | args: ["kubectl version"]
21 |
--------------------------------------------------------------------------------
/test/e2e/manifests/mixins/workflow-controller-configmap.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: workflow-controller-configmap
5 | data:
6 | resourceRateLimit: |
7 | limit: 10
8 | burst: 1
9 | workflowDefaults: |
10 | spec:
11 | activeDeadlineSeconds: 300
12 | ttlStrategy:
13 | secondsAfterCompletion: 600
14 | podSpecPatch: |
15 | terminationGracePeriodSeconds: 3
16 | executor: |
17 | imagePullPolicy: Never
18 | resources:
19 | requests:
20 | cpu: 0.1
21 | memory: 64Mi
22 | limits:
23 | cpu: 0.5
24 | memory: 128Mi
25 | kubeletInsecure: "true"
26 |
--------------------------------------------------------------------------------
/ui/src/app/cron-workflows/components/cron-workflow-container.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import {Route, RouteComponentProps, Switch} from 'react-router';
3 | import {CronWorkflowDetails} from './cron-workflow-details/cron-workflow-details';
4 | import {CronWorkflowList} from './cron-workflow-list/cron-workflow-list';
5 |
6 | export const CronWorkflowContainer = (props: RouteComponentProps) => (
7 |
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------