mirror of https://github.com/dapr/cli.git
Merge branch 'master' into feat/interact-with-kubernetes-dapr-apps
This commit is contained in:
commit
7bf3b40355
|
|
@ -12,16 +12,12 @@
|
|||
// the localhost bind-mount /var/run/docker-host.sock.
|
||||
// "BIND_LOCALHOST_DOCKER": "true"
|
||||
},
|
||||
"extensions": [
|
||||
"davidanson.vscode-markdownlint",
|
||||
"golang.go",
|
||||
"ms-azuretools.vscode-dapr",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"ms-kubernetes-tools.vscode-kubernetes-tools"
|
||||
],
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/sshd:1": {},
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {},
|
||||
"ghcr.io/devcontainers/features/node": {
|
||||
"version": "lts"
|
||||
}
|
||||
},
|
||||
"mounts": [
|
||||
// Mount docker-in-docker library volume
|
||||
|
|
@ -58,12 +54,27 @@
|
|||
// Run the entrypoint defined in container image.
|
||||
"--init"
|
||||
],
|
||||
"settings": {
|
||||
"go.toolsManagement.checkForUpdates": "local",
|
||||
"go.useLanguageServer": true,
|
||||
"go.gopath": "/go",
|
||||
"go.buildTags": "e2e,perf,conftests,unit,integration_test,certtests",
|
||||
"git.alwaysSignOff": true
|
||||
"postCreateCommand": "npm install -g @devcontainers/cli",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"davidanson.vscode-markdownlint",
|
||||
"golang.go",
|
||||
"ms-azuretools.vscode-dapr",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"ms-kubernetes-tools.vscode-kubernetes-tools"
|
||||
],
|
||||
"settings": {
|
||||
"go.toolsManagement.checkForUpdates": "local",
|
||||
"go.useLanguageServer": true,
|
||||
"go.gopath": "/go",
|
||||
"go.buildTags": "e2e,perf,conftests,unit,integration_test,certtests,allcomponents",
|
||||
"git.alwaysSignOff": true,
|
||||
"terminal.integrated.env.linux": {
|
||||
"GOLANG_PROTOBUF_REGISTRATION_CONFLICT": "ignore"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"workspaceFolder": "/workspaces/cli",
|
||||
"workspaceMount": "type=bind,source=${localWorkspaceFolder},target=/workspaces/cli"
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ jobs:
|
|||
name: Build ${{ matrix.target_os }}_${{ matrix.target_arch }} binaries
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
GOVER: 1.19.3
|
||||
GOLANG_CI_LINT_VER: v1.49.0
|
||||
GOLANG_CI_LINT_VER: v1.51.2
|
||||
GOOS: ${{ matrix.target_os }}
|
||||
GOARCH: ${{ matrix.target_arch }}
|
||||
GOPROXY: https://proxy.golang.org
|
||||
|
|
@ -57,12 +56,43 @@ jobs:
|
|||
- os: macOS-latest
|
||||
target_arch: arm
|
||||
steps:
|
||||
- name: Set up Go ${{ env.GOVER }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GOVER }}
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
id: setup-go
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
- name: Cache Go modules (Linux)
|
||||
if: matrix.target_os == 'linux'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
- name: Cache Go modules (Windows)
|
||||
if: matrix.target_os == 'windows'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~\AppData\Local\go-build
|
||||
~\go\pkg\mod
|
||||
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
- name: Cache Go modules (macOS)
|
||||
if: matrix.target_os == 'darwin'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
- name: Run golangci-lint
|
||||
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
|
||||
uses: golangci/golangci-lint-action@v3.2.0
|
||||
|
|
@ -72,11 +102,6 @@ jobs:
|
|||
- name: Run make modtidy check-diff
|
||||
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
|
||||
run: make modtidy check-diff
|
||||
- name: Run Go Vulnerability Check
|
||||
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
|
||||
run: |
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
govulncheck ./...
|
||||
- name: Parse release version and set REL_VERSION
|
||||
run: python ./.github/scripts/get_release_version.py
|
||||
- name: Setup test output
|
||||
|
|
@ -91,7 +116,7 @@ jobs:
|
|||
run: make test
|
||||
- name: Codecov
|
||||
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
|
||||
uses: codecov/codecov-action@v1
|
||||
uses: codecov/codecov-action@v3
|
||||
- name: Run make release to build and archive binaries
|
||||
run: |
|
||||
mkdir -p ${{ env.ARCHIVE_OUTDIR }}
|
||||
|
|
@ -144,41 +169,34 @@ jobs:
|
|||
- name: publish binaries to github
|
||||
if: startswith(github.ref, 'refs/tags/v')
|
||||
run: |
|
||||
echo "installing github-release-cli..."
|
||||
sudo npm install --silent --no-progress -g github-release-cli@1.3.1
|
||||
# Get the list of files
|
||||
RELEASE_ARTIFACT=(${ARTIFACT_DIR}/*)
|
||||
# Parse repository to get owner and repo names
|
||||
OWNER_NAME="${GITHUB_REPOSITORY%%/*}"
|
||||
REPO_NAME="${GITHUB_REPOSITORY#*/}"
|
||||
export GITHUB_TOKEN=${{ secrets.DAPR_BOT_TOKEN }}
|
||||
echo "Uploading Dapr CLI Binaries to GitHub Release"
|
||||
github-release upload \
|
||||
--owner $OWNER_NAME --repo $REPO_NAME \
|
||||
--tag "v${REL_VERSION}" \
|
||||
--name "Dapr CLI v${REL_VERSION}" \
|
||||
--prerelease true \
|
||||
gh release create \
|
||||
"v${REL_VERSION}" \
|
||||
--title "Dapr CLI v${REL_VERSION}" \
|
||||
--repo $GITHUB_REPOSITORY \
|
||||
--prerelease \
|
||||
${RELEASE_ARTIFACT[*]}
|
||||
publish-winget:
|
||||
name: Publish to winget-pkgs
|
||||
needs: publish
|
||||
if: startswith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
WINGETCREATE_VERSION: 1.1.2.0
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Parse release version and set REL_VERSION
|
||||
run: python ./.github/scripts/get_release_version.py
|
||||
- name: Update winget manifests
|
||||
shell: pwsh
|
||||
run: |
|
||||
$url = "https://github.com/dapr/cli/releases/download/v${{ env.REL_VERSION }}/dapr.msi"
|
||||
iwr https://github.com/microsoft/winget-create/releases/download/v${{ env.WINGETCREATE_VERSION }}/wingetcreate.exe -OutFile wingetcreate.exe
|
||||
iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
|
||||
if("${{ env.REL_VERSION }}".Contains("-rc.")){
|
||||
$PackageIdentifier="Dapr.CLI.Preview"
|
||||
} else{
|
||||
$PackageIdentifier="Dapr.CLI"
|
||||
}
|
||||
.\wingetcreate.exe update "$PackageIdentifier" --submit --urls "$url|x64" --version "${{ env.REL_VERSION }}" --token "${{ secrets.DAPR_BOT_TOKEN }}"
|
||||
.\wingetcreate.exe update "$PackageIdentifier" --submit --urls "$url|x64" --version "${{ env.REL_VERSION }}" --token "${{ secrets.DAPR_BOT_TOKEN }}"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
name: "Release dev container features & Generate Documentation"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: ${{ github.ref == 'refs/heads/master' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: "Publish Features"
|
||||
uses: devcontainers/action@v1
|
||||
with:
|
||||
publish-features: "true"
|
||||
base-path-to-features: "./dev-container-feature/src"
|
||||
generate-docs: "true"
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create PR for Documentation
|
||||
id: push_image_info
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -e
|
||||
echo "Start."
|
||||
# Configure git and Push updates
|
||||
git config --global user.email github-actions@github.com
|
||||
git config --global user.name github-actions
|
||||
git config pull.rebase false
|
||||
branch=automated-documentation-update-$GITHUB_RUN_ID
|
||||
git checkout -b $branch
|
||||
message='Automated documentation update'
|
||||
# Add / update and commit
|
||||
git add */**/README.md
|
||||
git commit -m 'Automated documentation update [skip ci]' || export NO_UPDATES=true
|
||||
# Push
|
||||
if [ "$NO_UPDATES" != "true" ] ; then
|
||||
git push origin "$branch"
|
||||
gh pr create --title "$message" --body "$message"
|
||||
fi
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
name: "CI - Test Features"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
- "dev-container-feature/**"
|
||||
- .github/workflows/dev_container_feature**
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
test-autogenerated:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
features:
|
||||
- dapr-cli
|
||||
baseImage:
|
||||
- debian:latest
|
||||
- ubuntu:latest
|
||||
- mcr.microsoft.com/devcontainers/base:ubuntu
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: "Install latest devcontainer CLI"
|
||||
run: npm install -g @devcontainers/cli
|
||||
|
||||
- name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'"
|
||||
run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} ./dev-container-feature
|
||||
|
||||
|
||||
test-scenarios:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
features:
|
||||
- dapr-cli
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: "Install latest devcontainer CLI"
|
||||
run: npm install -g @devcontainers/cli
|
||||
|
||||
- name: "Generating tests for '${{ matrix.features }}' scenarios"
|
||||
run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated ./dev-container-feature
|
||||
|
||||
|
||||
test-global:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: "Install latest devcontainer CLI"
|
||||
run: npm install -g @devcontainers/cli
|
||||
|
||||
- name: "Testing global scenarios"
|
||||
run: devcontainer features test --global-scenarios-only ./dev-container-feature
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
name: "Validate devcontainer-feature.json files"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- "dev-container-feature/**"
|
||||
- .github/workflows/dev_container_feature**
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: "Validate devcontainer-feature.json files"
|
||||
uses: devcontainers/action@v1
|
||||
with:
|
||||
validate-only: "true"
|
||||
base-path-to-features: "./dev-container-feature/src"
|
||||
|
|
@ -34,16 +34,16 @@ jobs:
|
|||
FOSSA_API_KEY: b88e1f4287c3108c8751bf106fb46db6 # This is a push-only token that is safe to be exposed.
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Run FOSSA Scan"
|
||||
uses: fossas/fossa-action@v1.1.0 # Use a specific version if locking is preferred
|
||||
uses: fossas/fossa-action@v1.3.1 # Use a specific version if locking is preferred
|
||||
with:
|
||||
api-key: ${{ env.FOSSA_API_KEY }}
|
||||
|
||||
# Disable fossa test due to a bug on fossa side.
|
||||
# - name: "Run FOSSA Test"
|
||||
# uses: fossas/fossa-action@v1.1.0 # Use a specific version if locking is preferred
|
||||
# uses: fossas/fossa-action@v1.3.1 # Use a specific version if locking is preferred
|
||||
# with:
|
||||
# api-key: ${{ env.FOSSA_API_KEY }}
|
||||
# run-tests: true
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Install Dapr
|
||||
- name: Install DAPR CLI
|
||||
|
|
|
|||
|
|
@ -50,12 +50,11 @@ jobs:
|
|||
name: E2E tests for K8s (KinD)
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOVER: 1.19.3
|
||||
DAPR_RUNTIME_PINNED_VERSION: 1.9.4
|
||||
DAPR_DASHBOARD_PINNED_VERSION: 0.11.0
|
||||
DAPR_RUNTIME_LATEST_VERSION:
|
||||
DAPR_DASHBOARD_LATEST_VERSION:
|
||||
DAPR_TGZ: dapr-1.9.4.tgz
|
||||
DAPR_RUNTIME_PINNED_VERSION: 1.11.0
|
||||
DAPR_DASHBOARD_PINNED_VERSION: 0.13.0
|
||||
DAPR_RUNTIME_LATEST_STABLE_VERSION:
|
||||
DAPR_DASHBOARD_LATEST_STABLE_VERSION:
|
||||
DAPR_TGZ: dapr-1.11.0.tgz
|
||||
strategy:
|
||||
fail-fast: false # Keep running if one leg fails.
|
||||
matrix:
|
||||
|
|
@ -80,14 +79,24 @@ jobs:
|
|||
kind-version: v0.16.0
|
||||
kind-image-sha: sha256:9be91e9e9cdf116809841fc77ebdb8845443c4c72fe5218f3ae9eb57fdb4bace
|
||||
steps:
|
||||
- name: Set up Go ${{ env.GOVER }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GOVER }}
|
||||
- name: Check out code onto GOPATH
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ./src/github.com/dapr/cli
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
id: setup-go
|
||||
with:
|
||||
go-version-file: './src/github.com/dapr/cli/go.mod'
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ matrix.k8s-version }}-${{ matrix.kind-version }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.k8s-version }}-${{ matrix.kind-version }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
|
||||
- name: Configure KinD
|
||||
# Generate a KinD configuration file that uses:
|
||||
|
|
@ -115,7 +124,7 @@ jobs:
|
|||
# Log the generated kind.yaml for easy reference.
|
||||
cat kind.yaml
|
||||
- name: Create KinD Cluster
|
||||
uses: helm/kind-action@v1.0.0
|
||||
uses: helm/kind-action@v1.3.0
|
||||
with:
|
||||
config: kind.yaml
|
||||
cluster_name: kind
|
||||
|
|
@ -131,37 +140,39 @@ jobs:
|
|||
- name: Free up some diskspace
|
||||
run: |
|
||||
docker image prune -a -f
|
||||
- name: Determine latest stable Dapr Runtime version
|
||||
- name: Determine latest Dapr Runtime version including Pre-releases
|
||||
if: github.base_ref == 'master'
|
||||
run: |
|
||||
export RUNTIME_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dapr/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
export RUNTIME_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dapr/releases | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
if [[ -z "$RUNTIME_VERSION" ]]; then
|
||||
echo "Could not fetch the latest Dapr Runtime version. Using default version $DAPR_RUNTIME_PINNED_VERSION"
|
||||
echo "DAPR_RUNTIME_LATEST_VERSION=$DAPR_RUNTIME_PINNED_VERSION" >> $GITHUB_ENV
|
||||
echo "Could not fetch the latest Dapr Runtime version. Using pinned version $DAPR_RUNTIME_PINNED_VERSION"
|
||||
else
|
||||
echo "Found $RUNTIME_VERSION"
|
||||
echo "DAPR_RUNTIME_LATEST_VERSION=$RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
base_ref=${{ github.base_ref }}
|
||||
echo "Branch $base_ref"
|
||||
if [[ $base_ref = 'master' ]]; then
|
||||
echo "DAPR_RUNTIME_PINNED_VERSION=$RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "DAPR_RUNTIME_PINNED_VERSION=$RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
- name: Determine latest Dapr Dashboard version including Pre-releases
|
||||
if: github.base_ref == 'master'
|
||||
run: |
|
||||
export DASHBOARD_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dashboard/releases | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
if [[ -z "$DASHBOARD_VERSION" ]]; then
|
||||
echo "Could not fetch the latest Dapr Dashboard version. Using pinned version $DAPR_DASHBOARD_PINNED_VERSION"
|
||||
else
|
||||
echo "Found $DASHBOARD_VERSION"
|
||||
echo "DAPR_DASHBOARD_PINNED_VERSION=$DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
- name: Determine latest stable Dapr Runtime version
|
||||
run: |
|
||||
export LATEST_STABLE_RUNTIME_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dapr/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
echo "Found $LATEST_STABLE_RUNTIME_VERSION"
|
||||
echo "DAPR_RUNTIME_LATEST_STABLE_VERSION=$LATEST_STABLE_RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- name: Determine latest stable Dapr Dashboard version
|
||||
run: |
|
||||
export DASHBOARD_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dashboard/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
if [[ -z "$DASHBOARD_VERSION" ]]; then
|
||||
echo "Could not fetch the latest Dapr Dashboard version. Using default version $DAPR_DASHBOARD_PINNED_VERSION"
|
||||
echo "DAPR_DASHBOARD_LATEST_VERSION=$DAPR_DASHBOARD_PINNED_VERSION" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Found $DASHBOARD_VERSION"
|
||||
echo "DAPR_DASHBOARD_LATEST_VERSION=$DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
base_ref=${{ github.base_ref }}
|
||||
echo "Branch $base_ref"
|
||||
if [[ $base_ref = 'master' ]]; then
|
||||
echo "DAPR_DASHBOARD_PINNED_VERSION=$DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
export LATEST_STABLE_DASHBOARD_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dashboard/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
echo "Found $LATEST_STABLE_DASHBOARD_VERSION"
|
||||
echo "DAPR_DASHBOARD_LATEST_STABLE_VERSION=$LATEST_STABLE_DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- name: Run tests with GHCR
|
||||
# runs every 6hrs
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# ------------------------------------------------------------
|
||||
|
||||
name: E2E - Self-hosted
|
||||
|
||||
on:
|
||||
|
|
@ -19,31 +18,31 @@ on:
|
|||
- master
|
||||
- release-*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- "**.md"
|
||||
schedule:
|
||||
- cron: '0 */3 * * *'
|
||||
- cron: '0 */6 * * *'
|
||||
- cron: "0 */3 * * *"
|
||||
- cron: "0 */6 * * *"
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- 'release-*'
|
||||
- "release-*"
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- "**.md"
|
||||
|
||||
jobs:
|
||||
self-hosted-e2e:
|
||||
name: Run Self-Hosted E2E tests in ${{ matrix.target_os }}_${{ matrix.target_arch }}_${{ matrix.dapr_install_mode }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
GOVER: 1.19.3
|
||||
GOOS: ${{ matrix.target_os }}
|
||||
GOARCH: ${{ matrix.target_arch }}
|
||||
GOPROXY: https://proxy.golang.org
|
||||
ARCHIVE_OUTDIR: dist/archives
|
||||
DAPR_RUNTIME_PINNED_VERSION: "1.9.4"
|
||||
DAPR_DASHBOARD_PINNED_VERSION: 0.11.0
|
||||
DAPR_RUNTIME_LATEST_VERSION:
|
||||
DAPR_DASHBOARD_LATEST_VERSION:
|
||||
DAPR_RUNTIME_PINNED_VERSION: "1.11.0"
|
||||
DAPR_DASHBOARD_PINNED_VERSION: 0.13.0
|
||||
DAPR_RUNTIME_LATEST_STABLE_VERSION:
|
||||
DAPR_DASHBOARD_LATEST_STABLE_VERSION:
|
||||
PODMAN_VERSION: 4.4.4
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
|
|
@ -60,59 +59,95 @@ jobs:
|
|||
- os: windows-latest
|
||||
dapr_install_mode: complete
|
||||
steps:
|
||||
- name: Set up Go ${{ env.GOVER }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GOVER }}
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
id: setup-go
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
- name: Cache Go modules (Linux)
|
||||
if: matrix.target_os == 'linux'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
- name: Cache Go modules (Windows)
|
||||
if: matrix.target_os == 'windows'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~\AppData\Local\go-build
|
||||
~\go\pkg\mod
|
||||
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
- name: Cache Go modules (macOS)
|
||||
if: matrix.target_os == 'darwin'
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.target_os }}-${{ matrix.target_arch }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
- name: Install podman - MacOS
|
||||
timeout-minutes: 15
|
||||
if: matrix.os == 'macos-latest' && matrix.dapr_install_mode == 'complete'
|
||||
run: |
|
||||
sudo rm -rf `brew --cache`
|
||||
brew upgrade
|
||||
brew install podman
|
||||
which podman-mac-helper
|
||||
podman_helper=$(which podman-mac-helper)
|
||||
sudo ${podman_helper} install
|
||||
# Install podman
|
||||
curl -sL -o podman.pkg https://github.com/containers/podman/releases/download/v${{ env.PODMAN_VERSION }}/podman-installer-macos-amd64.pkg
|
||||
sudo installer -pkg podman.pkg -target /
|
||||
export PATH=/opt/podman/bin:$PATH
|
||||
echo "/opt/podman/bin" >> $GITHUB_PATH
|
||||
|
||||
# Start podman machine
|
||||
sudo podman-mac-helper install
|
||||
podman machine init
|
||||
podman machine start
|
||||
podman machine start --log-level debug
|
||||
echo "CONTAINER_RUNTIME=podman" >> $GITHUB_ENV
|
||||
- name: Determine latest stable Dapr Runtime version
|
||||
- name: Determine latest Dapr Runtime version including Pre-releases
|
||||
if: github.base_ref == 'master'
|
||||
run: |
|
||||
export RUNTIME_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dapr/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
export RUNTIME_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dapr/releases | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
if [[ -z "$RUNTIME_VERSION" ]]; then
|
||||
echo "Could not fetch the latest Dapr Runtime version. Using default version $DAPR_RUNTIME_PINNED_VERSION"
|
||||
echo "DAPR_RUNTIME_LATEST_VERSION=$DAPR_RUNTIME_PINNED_VERSION" >> $GITHUB_ENV
|
||||
echo "Could not fetch the latest Dapr Runtime version. Using pinned version $DAPR_RUNTIME_PINNED_VERSION"
|
||||
else
|
||||
echo "Found $RUNTIME_VERSION"
|
||||
echo "DAPR_RUNTIME_LATEST_VERSION=$RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
base_ref=${{ github.base_ref }}
|
||||
echo "Branch $base_ref"
|
||||
if [[ $base_ref = 'master' ]]; then
|
||||
echo "DAPR_RUNTIME_PINNED_VERSION=$RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "DAPR_RUNTIME_PINNED_VERSION=$RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
- name: Determine latest Dapr Dashboard version including Pre-releases
|
||||
if: github.base_ref == 'master'
|
||||
run: |
|
||||
export DASHBOARD_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dashboard/releases | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
if [[ -z "$DASHBOARD_VERSION" ]]; then
|
||||
echo "Could not fetch the latest Dapr Dashboard version. Using pinned version $DAPR_DASHBOARD_PINNED_VERSION"
|
||||
else
|
||||
echo "Found $DASHBOARD_VERSION"
|
||||
echo "DAPR_DASHBOARD_PINNED_VERSION=$DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
- name: Determine latest stable Dapr Runtime version
|
||||
run: |
|
||||
export LATEST_STABLE_RUNTIME_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dapr/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
echo "Found $LATEST_STABLE_RUNTIME_VERSION"
|
||||
echo "DAPR_RUNTIME_LATEST_STABLE_VERSION=$LATEST_STABLE_RUNTIME_VERSION" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- name: Determine latest stable Dapr Dashboard version
|
||||
run: |
|
||||
export DASHBOARD_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dashboard/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
if [[ -z "$DASHBOARD_VERSION" ]]; then
|
||||
echo "Could not fetch the latest Dapr Dashboard version. Using default version $DAPR_DASHBOARD_PINNED_VERSION"
|
||||
echo "DAPR_DASHBOARD_LATEST_VERSION=$DAPR_DASHBOARD_PINNED_VERSION" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Found $DASHBOARD_VERSION"
|
||||
echo "DAPR_DASHBOARD_LATEST_VERSION=$DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
base_ref=${{ github.base_ref }}
|
||||
echo "Branch $base_ref"
|
||||
if [[ $base_ref = 'master' ]]; then
|
||||
echo "DAPR_DASHBOARD_PINNED_VERSION=$DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
export LATEST_STABLE_DASHBOARD_VERSION=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" https://api.github.com/repos/dapr/dashboard/releases/latest | grep tag_name | awk -F':' '{print $2}' | tr -d '", ' | sed '/-/! s/$/_/' | sort -V | sed 's/_$//' | tr -d 'v' | tail -1)
|
||||
echo "Found $LATEST_STABLE_DASHBOARD_VERSION"
|
||||
echo "DAPR_DASHBOARD_LATEST_STABLE_VERSION=$LATEST_STABLE_DASHBOARD_VERSION" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
- name: Set the test timeout - MacOS
|
||||
if: matrix.os == 'macos-latest'
|
||||
run: echo "E2E_SH_TEST_TIMEOUT=20m" >> $GITHUB_ENV
|
||||
run: echo "E2E_SH_TEST_TIMEOUT=30m" >> $GITHUB_ENV
|
||||
- name: Run E2E tests with GHCR
|
||||
# runs every 6hrs
|
||||
if: github.event.schedule == '0 */6 * * *'
|
||||
|
|
|
|||
|
|
@ -49,8 +49,6 @@ jobs:
|
|||
kubernetes-e2e:
|
||||
name: Upgrade path tests (KinD)
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
GOVER: 1.19.3
|
||||
strategy:
|
||||
fail-fast: false # Keep running if one leg fails.
|
||||
matrix:
|
||||
|
|
@ -75,14 +73,25 @@ jobs:
|
|||
kind-version: v0.16.0
|
||||
kind-image-sha: sha256:9be91e9e9cdf116809841fc77ebdb8845443c4c72fe5218f3ae9eb57fdb4bace
|
||||
steps:
|
||||
- name: Set up Go ${{ env.GOVER }}
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.GOVER }}
|
||||
- name: Check out code onto GOPATH
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: ./src/github.com/dapr/cli
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
id: setup-go
|
||||
with:
|
||||
go-version-file: './src/github.com/dapr/cli/go.mod'
|
||||
- name: Cache Go modules
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ matrix.k8s-version }}-${{ matrix.kind-version }}-go-${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ matrix.k8s-version }}-${{ matrix.kind-version }}-go-${{ steps.setup-go.outputs.go-version }}-
|
||||
|
||||
|
||||
- name: Configure KinD
|
||||
# Generate a KinD configuration file that uses:
|
||||
|
|
@ -112,7 +121,7 @@ jobs:
|
|||
cat kind.yaml
|
||||
|
||||
- name: Create KinD Cluster
|
||||
uses: helm/kind-action@v1.0.0
|
||||
uses: helm/kind-action@v1.3.0
|
||||
with:
|
||||
config: kind.yaml
|
||||
cluster_name: kind
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ run:
|
|||
skip-dirs:
|
||||
- ^pkg.*client.*clientset.*versioned.*
|
||||
- ^pkg.*client.*informers.*externalversions.*
|
||||
- pkg.*mod.*k8s.io.*
|
||||
|
||||
# which files to skip: they will be analyzed, but issues from them
|
||||
# won't be reported. Default value is empty list, but there is
|
||||
|
|
@ -244,7 +245,7 @@ linters:
|
|||
- goerr113
|
||||
- nlreturn
|
||||
- exhaustive
|
||||
- gci
|
||||
- gci
|
||||
- noctx
|
||||
- exhaustivestruct
|
||||
- exhaustruct
|
||||
|
|
|
|||
11
Makefile
11
Makefile
|
|
@ -200,7 +200,7 @@ e2e-build-run-sh: build test-e2e-sh
|
|||
################################################################################
|
||||
.PHONY: modtidy
|
||||
modtidy:
|
||||
go mod tidy -compat=1.19
|
||||
go mod tidy -compat=1.20
|
||||
|
||||
################################################################################
|
||||
# Target: check-diff #
|
||||
|
|
@ -208,3 +208,12 @@ modtidy:
|
|||
.PHONY: check-diff
|
||||
check-diff:
|
||||
git diff --exit-code ./go.mod # check no changes
|
||||
|
||||
################################################################################
|
||||
# Target: vuln-check #
|
||||
################################################################################
|
||||
.PHONY: vuln-check
|
||||
vuln-check:
|
||||
@echo "Checking for vulnerabilities..."
|
||||
go install golang.org/x/vuln/cmd/govulncheck@latest
|
||||
govulncheck ./...
|
||||
|
|
|
|||
16
README.md
16
README.md
|
|
@ -212,6 +212,20 @@ $ dapr init --container-runtime podman
|
|||
|
||||
> Note: The default container runtime is Docker.
|
||||
|
||||
#### In a dev container or GitHub Codespace
|
||||
|
||||
To install the Dapr CLI in a dev container or GitHub Codespace, add the following to your `devcontainer.json` file:
|
||||
|
||||
```jsonc
|
||||
"features": {
|
||||
"ghcr.io/dapr/cli/dapr-cli:0": {}
|
||||
}
|
||||
```
|
||||
|
||||
Restart your dev container or GitHub Codespace and run `dapr init` to initialize Dapr.
|
||||
|
||||
For more details, see the docs for dev containers with [Visual Studio Code](https://code.visualstudio.com/docs/devcontainers/containers#_dev-container-features) and [GitHub Codespaces](https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/configuring-dev-containers/adding-features-to-a-devcontainer-file).
|
||||
|
||||
### Uninstall Dapr in a standalone mode
|
||||
|
||||
Uninstalling will remove daprd binary and the placement container (if installed with Docker or the placement binary if not).
|
||||
|
|
@ -736,7 +750,9 @@ See the [Reference Guide](https://docs.dapr.io/reference/cli/) for more informat
|
|||
## Contributing to Dapr CLI
|
||||
|
||||
See the [Development Guide](https://github.com/dapr/cli/blob/master/docs/development/development.md) to get started with building and developing.
|
||||
## Release process for Dapr CLI
|
||||
|
||||
See the [Release Guide](https://github.com/dapr/cli/blob/master/docs/development/release.md) for complete release process for Dapr CLI.
|
||||
## Code of Conduct
|
||||
|
||||
Please refer to our [Dapr Community Code of Conduct](https://github.com/dapr/community/blob/master/CODE-OF-CONDUCT.md)
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ func init() {
|
|||
AnnotateCmd.Flags().StringVarP(&annotateAppID, "app-id", "a", "", "The app id to annotate")
|
||||
AnnotateCmd.Flags().IntVarP(&annotateAppPort, "app-port", "p", -1, "The port to expose the app on")
|
||||
AnnotateCmd.Flags().StringVarP(&annotateConfig, "config", "c", "", "The config file to annotate")
|
||||
AnnotateCmd.Flags().StringVar(&annotateAppProtocol, "app-protocol", "", "The protocol to use for the app")
|
||||
AnnotateCmd.Flags().StringVar(&annotateAppProtocol, "app-protocol", "", "The protocol to use for the app. Allowed values http, https, h2c, grpc, grpcs")
|
||||
AnnotateCmd.Flags().BoolVar(&annotateEnableProfile, "enable-profile", false, "Enable profiling")
|
||||
AnnotateCmd.Flags().StringVar(&annotateLogLevel, "log-level", "", "The log level to use")
|
||||
AnnotateCmd.Flags().StringVar(&annotateAPITokenSecret, "api-token-secret", "", "The secret to use for the API token")
|
||||
|
|
@ -385,6 +385,7 @@ func init() {
|
|||
AnnotateCmd.Flags().IntVar(&annotateReadinessProbeThreshold, "readiness-probe-threshold", -1, "The threshold to use for the readiness probe")
|
||||
AnnotateCmd.Flags().StringVar(&annotateDaprImage, "dapr-image", "", "The image to use for the dapr sidecar container")
|
||||
AnnotateCmd.Flags().BoolVar(&annotateAppSSL, "app-ssl", false, "Enable SSL for the app")
|
||||
AnnotateCmd.Flags().MarkDeprecated("app-ssl", "This flag is deprecated and will be removed in a future release. Use \"app-protocol\" flag with https or grpcs instead")
|
||||
AnnotateCmd.Flags().IntVar(&annotateMaxRequestBodySize, "max-request-body-size", -1, "The maximum request body size to use")
|
||||
AnnotateCmd.Flags().IntVar(&annotateReadBufferSize, "http-read-buffer-size", -1, "The maximum size of HTTP header read buffer in kilobytes")
|
||||
AnnotateCmd.Flags().BoolVar(&annotateHTTPStreamRequestBody, "http-stream-request-body", false, "Enable streaming request body for HTTP")
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ var BuildInfoCmd = &cobra.Command{
|
|||
dapr build-info
|
||||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
out, err := standalone.GetBuildInfo(daprPath, RootCmd.Version)
|
||||
out, err := standalone.GetBuildInfo(daprRuntimePath, cliVersion)
|
||||
if err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, "Error getting build info: %s", err.Error())
|
||||
os.Exit(1)
|
||||
|
|
|
|||
55
cmd/dapr.go
55
cmd/dapr.go
|
|
@ -30,15 +30,22 @@ var RootCmd = &cobra.Command{
|
|||
Use: "dapr",
|
||||
Short: "Dapr CLI",
|
||||
Long: `
|
||||
__
|
||||
__
|
||||
____/ /___ _____ _____
|
||||
/ __ / __ '/ __ \/ ___/
|
||||
/ /_/ / /_/ / /_/ / /
|
||||
\__,_/\__,_/ .___/_/
|
||||
/_/
|
||||
|
||||
/ /_/ / /_/ / /_/ / /
|
||||
\__,_/\__,_/ .___/_/
|
||||
/_/
|
||||
|
||||
===============================
|
||||
Distributed Application Runtime`,
|
||||
Run: func(cmd *cobra.Command, _ []string) {
|
||||
if versionFlag {
|
||||
printVersion()
|
||||
} else {
|
||||
cmd.Help()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
type daprVersion struct {
|
||||
|
|
@ -53,43 +60,44 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
daprVer daprVersion
|
||||
logAsJSON bool
|
||||
daprPath string
|
||||
cliVersion string
|
||||
versionFlag bool
|
||||
daprVer daprVersion
|
||||
logAsJSON bool
|
||||
daprRuntimePath string
|
||||
)
|
||||
|
||||
// Execute adds all child commands to the root command.
|
||||
func Execute(version, apiVersion string) {
|
||||
RootCmd.Version = version
|
||||
// Need to be set here as it is accessed in initConfig.
|
||||
cliVersion = version
|
||||
api.RuntimeAPIVersion = apiVersion
|
||||
|
||||
// err intentionally ignored since daprd may not yet be installed.
|
||||
runtimeVer, _ := standalone.GetRuntimeVersion(daprPath)
|
||||
|
||||
daprVer = daprVersion{
|
||||
CliVersion: version,
|
||||
RuntimeVersion: strings.ReplaceAll(runtimeVer, "\n", ""),
|
||||
}
|
||||
|
||||
cobra.OnInitialize(initConfig)
|
||||
|
||||
setVersion()
|
||||
|
||||
if err := RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
func setVersion() {
|
||||
template := fmt.Sprintf(cliVersionTemplateString, daprVer.CliVersion, daprVer.RuntimeVersion)
|
||||
RootCmd.SetVersionTemplate(template)
|
||||
func printVersion() {
|
||||
fmt.Printf(cliVersionTemplateString, daprVer.CliVersion, daprVer.RuntimeVersion)
|
||||
}
|
||||
|
||||
// Function is called as a preRun initializer for each command executed.
|
||||
func initConfig() {
|
||||
if logAsJSON {
|
||||
print.EnableJSONFormat()
|
||||
}
|
||||
// err intentionally ignored since daprd may not yet be installed.
|
||||
runtimeVer, _ := standalone.GetRuntimeVersion(daprRuntimePath)
|
||||
|
||||
daprVer = daprVersion{
|
||||
// Set in Execute() method in this file before initConfig() is called by cmd.Execute().
|
||||
CliVersion: cliVersion,
|
||||
RuntimeVersion: strings.ReplaceAll(runtimeVer, "\n", ""),
|
||||
}
|
||||
|
||||
viper.SetEnvPrefix("dapr")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
|
|
@ -97,6 +105,7 @@ func initConfig() {
|
|||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.PersistentFlags().StringVarP(&daprPath, "dapr-path", "", "", "The path to the dapr installation directory")
|
||||
RootCmd.Flags().BoolVarP(&versionFlag, "version", "v", false, "version for dapr")
|
||||
RootCmd.PersistentFlags().StringVarP(&daprRuntimePath, "runtime-path", "", "", "The path to the dapr runtime installation directory")
|
||||
RootCmd.PersistentFlags().BoolVarP(&logAsJSON, "log-as-json", "", false, "Log output in JSON format")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,14 +62,14 @@ var DashboardCmd = &cobra.Command{
|
|||
# Start dashboard locally
|
||||
dapr dashboard
|
||||
|
||||
# Start dashboard locally in a specified port
|
||||
# Start dashboard locally in a specified port
|
||||
dapr dashboard -p 9999
|
||||
|
||||
# Start dashboard locally on a random port which is free.
|
||||
dapr dashboard -p 0
|
||||
|
||||
# Port forward to dashboard in Kubernetes
|
||||
dapr dashboard -k
|
||||
# Port forward to dashboard in Kubernetes
|
||||
dapr dashboard -k
|
||||
|
||||
# Port forward to dashboard in Kubernetes on all addresses in a specified port
|
||||
dapr dashboard -k -p 9999 -a 0.0.0.0
|
||||
|
|
@ -82,7 +82,7 @@ dapr dashboard -k -p 0
|
|||
`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if dashboardVersionCmd {
|
||||
dashboardVer, err := standalone.GetDashboardVersion(daprPath)
|
||||
dashboardVer, err := standalone.GetDashboardVersion(daprRuntimePath)
|
||||
if err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, "Failed to get Dapr install directory: %v", err)
|
||||
os.Exit(1)
|
||||
|
|
@ -194,7 +194,7 @@ dapr dashboard -k -p 0
|
|||
<-portForward.GetStop()
|
||||
} else {
|
||||
// Standalone mode.
|
||||
dashboardCmd, err := standalone.NewDashboardCmd(daprPath, dashboardLocalPort)
|
||||
dashboardCmd, err := standalone.NewDashboardCmd(daprRuntimePath, dashboardLocalPort)
|
||||
if err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, "Failed to get Dapr install directory: %v", err)
|
||||
} else {
|
||||
|
|
|
|||
93
cmd/init.go
93
cmd/init.go
|
|
@ -14,6 +14,7 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
|
@ -51,13 +52,17 @@ var InitCmd = &cobra.Command{
|
|||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlag("network", cmd.Flags().Lookup("network"))
|
||||
viper.BindPFlag("image-registry", cmd.Flags().Lookup("image-registry"))
|
||||
|
||||
runtimeVersion = getConfigurationValue("runtime-version", cmd)
|
||||
dashboardVersion = getConfigurationValue("dashboard-version", cmd)
|
||||
containerRuntime = getConfigurationValue("container-runtime", cmd)
|
||||
},
|
||||
Example: `
|
||||
# Initialize Dapr in self-hosted mode
|
||||
dapr init
|
||||
|
||||
# Initialize Dapr in self-hosted mode with a provided docker image registry. Image looked up as <registry-url>/<image>.
|
||||
# Check docs or README for more information on the format of the image path that is required.
|
||||
# Check docs or README for more information on the format of the image path that is required.
|
||||
dapr init --image-registry <registry-url>
|
||||
|
||||
# Initialize Dapr in Kubernetes
|
||||
|
|
@ -81,8 +86,9 @@ dapr init --from-dir <path-to-directory>
|
|||
# Initialize dapr with a particular image variant. Allowed values: "mariner"
|
||||
dapr init --image-variant <variant>
|
||||
|
||||
# Initialize Dapr to non-default install directory (default is $HOME/.dapr)
|
||||
dapr init --dapr-path <path-to-install-directory>
|
||||
# Initialize Dapr inside a ".dapr" directory present in a non-default location
|
||||
# Folder .dapr will be created in folder pointed to by <path-to-install-directory>
|
||||
dapr init --runtime-path <path-to-install-directory>
|
||||
|
||||
# See more at: https://docs.dapr.io/getting-started/
|
||||
`,
|
||||
|
|
@ -95,8 +101,8 @@ dapr init --dapr-path <path-to-install-directory>
|
|||
imageRegistryURI := ""
|
||||
var err error
|
||||
|
||||
if len(strings.TrimSpace(daprPath)) != 0 {
|
||||
print.FailureStatusEvent(os.Stderr, "--dapr-path is only valid for self-hosted mode")
|
||||
if len(strings.TrimSpace(daprRuntimePath)) != 0 {
|
||||
print.FailureStatusEvent(os.Stderr, "--runtime-path is only valid for self-hosted mode")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -110,16 +116,25 @@ dapr init --dapr-path <path-to-install-directory>
|
|||
print.FailureStatusEvent(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = verifyCustomCertFlags(cmd); err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
config := kubernetes.InitConfiguration{
|
||||
Namespace: initNamespace,
|
||||
Version: runtimeVersion,
|
||||
EnableMTLS: enableMTLS,
|
||||
EnableHA: enableHA,
|
||||
Args: values,
|
||||
Wait: wait,
|
||||
Timeout: timeout,
|
||||
ImageRegistryURI: imageRegistryURI,
|
||||
ImageVariant: imageVariant,
|
||||
Namespace: initNamespace,
|
||||
Version: runtimeVersion,
|
||||
DashboardVersion: dashboardVersion,
|
||||
EnableMTLS: enableMTLS,
|
||||
EnableHA: enableHA,
|
||||
Args: values,
|
||||
Wait: wait,
|
||||
Timeout: timeout,
|
||||
ImageRegistryURI: imageRegistryURI,
|
||||
ImageVariant: imageVariant,
|
||||
RootCertificateFilePath: strings.TrimSpace(caRootCertificateFile),
|
||||
IssuerCertificateFilePath: strings.TrimSpace(issuerPublicCertificateFile),
|
||||
IssuerPrivateKeyFilePath: strings.TrimSpace(issuerPrivateKeyFile),
|
||||
}
|
||||
err = kubernetes.Init(config)
|
||||
if err != nil {
|
||||
|
|
@ -150,7 +165,7 @@ dapr init --dapr-path <path-to-install-directory>
|
|||
print.FailureStatusEvent(os.Stdout, "Invalid container runtime. Supported values are docker and podman.")
|
||||
os.Exit(1)
|
||||
}
|
||||
err := standalone.Init(runtimeVersion, dashboardVersion, dockerNetwork, slimMode, imageRegistryURI, fromDir, containerRuntime, imageVariant, daprPath)
|
||||
err := standalone.Init(runtimeVersion, dashboardVersion, dockerNetwork, slimMode, imageRegistryURI, fromDir, containerRuntime, imageVariant, daprRuntimePath)
|
||||
if err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
|
|
@ -160,30 +175,38 @@ dapr init --dapr-path <path-to-install-directory>
|
|||
},
|
||||
}
|
||||
|
||||
func verifyCustomCertFlags(cmd *cobra.Command) error {
|
||||
ca := cmd.Flags().Lookup("ca-root-certificate")
|
||||
issuerKey := cmd.Flags().Lookup("issuer-private-key")
|
||||
issuerCert := cmd.Flags().Lookup("issuer-public-certificate")
|
||||
|
||||
if ca.Changed && len(strings.TrimSpace(ca.Value.String())) == 0 {
|
||||
return errors.New("non empty value of --ca-root-certificate must be provided")
|
||||
}
|
||||
if issuerKey.Changed && len(strings.TrimSpace(issuerKey.Value.String())) == 0 {
|
||||
return errors.New("non empty value of --issuer-private-key must be provided")
|
||||
}
|
||||
if issuerCert.Changed && len(strings.TrimSpace(issuerCert.Value.String())) == 0 {
|
||||
return errors.New("non empty value of --issuer-public-certificate must be provided")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func warnForPrivateRegFeat() {
|
||||
print.WarningStatusEvent(os.Stdout, "Flag --image-registry is a preview feature and is subject to change.")
|
||||
}
|
||||
|
||||
func init() {
|
||||
defaultRuntimeVersion := "latest"
|
||||
viper.BindEnv("runtime_version_override", "DAPR_RUNTIME_VERSION")
|
||||
runtimeVersionEnv := viper.GetString("runtime_version_override")
|
||||
if runtimeVersionEnv != "" {
|
||||
defaultRuntimeVersion = runtimeVersionEnv
|
||||
}
|
||||
defaultDashboardVersion := "latest"
|
||||
viper.BindEnv("dashboard_version_override", "DAPR_DASHBOARD_VERSION")
|
||||
dashboardVersionEnv := viper.GetString("dashboard_version_override")
|
||||
if dashboardVersionEnv != "" {
|
||||
defaultDashboardVersion = dashboardVersionEnv
|
||||
}
|
||||
defaultContainerRuntime := string(utils.DOCKER)
|
||||
|
||||
InitCmd.Flags().BoolVarP(&kubernetesMode, "kubernetes", "k", false, "Deploy Dapr to a Kubernetes cluster")
|
||||
InitCmd.Flags().BoolVarP(&wait, "wait", "", false, "Wait for Kubernetes initialization to complete")
|
||||
InitCmd.Flags().UintVarP(&timeout, "timeout", "", 300, "The wait timeout for the Kubernetes installation")
|
||||
InitCmd.Flags().BoolVarP(&slimMode, "slim", "s", false, "Exclude placement service, Redis and Zipkin containers from self-hosted installation")
|
||||
InitCmd.Flags().StringVarP(&runtimeVersion, "runtime-version", "", defaultRuntimeVersion, "The version of the Dapr runtime to install, for example: 1.0.0")
|
||||
InitCmd.Flags().StringVarP(&dashboardVersion, "dashboard-version", "", defaultDashboardVersion, "The version of the Dapr dashboard to install, for example: 1.0.0")
|
||||
InitCmd.Flags().StringVarP(&dashboardVersion, "dashboard-version", "", defaultDashboardVersion, "The version of the Dapr dashboard to install, for example: 0.13.0")
|
||||
InitCmd.Flags().StringVarP(&initNamespace, "namespace", "n", "dapr-system", "The Kubernetes namespace to install Dapr in")
|
||||
InitCmd.Flags().BoolVarP(&enableMTLS, "enable-mtls", "", true, "Enable mTLS in your cluster")
|
||||
InitCmd.Flags().BoolVarP(&enableHA, "enable-ha", "", false, "Enable high availability (HA) mode")
|
||||
|
|
@ -193,7 +216,23 @@ func init() {
|
|||
InitCmd.Flags().BoolP("help", "h", false, "Print this help message")
|
||||
InitCmd.Flags().StringArrayVar(&values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
|
||||
InitCmd.Flags().String("image-registry", "", "Custom/private docker image repository URL")
|
||||
InitCmd.Flags().StringVarP(&containerRuntime, "container-runtime", "", "docker", "The container runtime to use. Supported values are docker (default) and podman")
|
||||
InitCmd.Flags().StringVarP(&containerRuntime, "container-runtime", "", defaultContainerRuntime, "The container runtime to use. Supported values are docker (default) and podman")
|
||||
InitCmd.Flags().StringVarP(&caRootCertificateFile, "ca-root-certificate", "", "", "The root certificate file")
|
||||
InitCmd.Flags().StringVarP(&issuerPrivateKeyFile, "issuer-private-key", "", "", "The issuer certificate private key")
|
||||
InitCmd.Flags().StringVarP(&issuerPublicCertificateFile, "issuer-public-certificate", "", "", "The issuer certificate")
|
||||
InitCmd.MarkFlagsRequiredTogether("ca-root-certificate", "issuer-private-key", "issuer-public-certificate")
|
||||
|
||||
RootCmd.AddCommand(InitCmd)
|
||||
}
|
||||
|
||||
// getConfigurationValue returns the value for a given configuration key.
|
||||
// The value is retrieved from the following sources, in order:
|
||||
// Default value
|
||||
// Environment variable (respecting registered prefixes)
|
||||
// Command line flag
|
||||
// Value is returned as a string.
|
||||
func getConfigurationValue(n string, cmd *cobra.Command) string {
|
||||
viper.BindEnv(n)
|
||||
viper.BindPFlag(n, cmd.Flags().Lookup(n))
|
||||
return viper.GetString(n)
|
||||
}
|
||||
|
|
|
|||
195
cmd/run.go
195
cmd/run.go
|
|
@ -49,7 +49,7 @@ var (
|
|||
logLevel string
|
||||
protocol string
|
||||
componentsPath string
|
||||
resourcesPath string
|
||||
resourcesPaths []string
|
||||
appSSL bool
|
||||
metricsPort int
|
||||
maxRequestBodySize int
|
||||
|
|
@ -63,6 +63,7 @@ var (
|
|||
enableAPILogging bool
|
||||
apiListenAddresses string
|
||||
runFilePath string
|
||||
appChannelAddress string
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -92,8 +93,12 @@ dapr run --app-id myapp
|
|||
# Run a gRPC application written in Go (listening on port 3000)
|
||||
dapr run --app-id myapp --app-port 3000 --app-protocol grpc -- go run main.go
|
||||
|
||||
# Run a gRPC application written in Go (listening on port 3000) with a different app channel address
|
||||
dapr run --app-id myapp --app-port 3000 --app-channel-address localhost --app-protocol grpc -- go run main.go
|
||||
|
||||
|
||||
# Run sidecar only specifying dapr runtime installation directory
|
||||
dapr run --app-id myapp --dapr-path /usr/local/dapr
|
||||
dapr run --app-id myapp --runtime-path /usr/local/dapr
|
||||
|
||||
# Run multiple apps by providing path of a run config file
|
||||
dapr run --run-file dapr.yaml
|
||||
|
|
@ -123,7 +128,7 @@ dapr run --run-file /path/to/directory
|
|||
fmt.Println(print.WhiteBold("WARNING: no application command found."))
|
||||
}
|
||||
|
||||
daprDirPath, err := standalone.GetDaprPath(daprPath)
|
||||
daprDirPath, err := standalone.GetDaprRuntimePath(daprRuntimePath)
|
||||
if err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, "Failed to get Dapr install directory: %v", err)
|
||||
os.Exit(1)
|
||||
|
|
@ -160,7 +165,7 @@ dapr run --run-file /path/to/directory
|
|||
AppProtocol: protocol,
|
||||
PlacementHostAddr: viper.GetString("placement-host-address"),
|
||||
ComponentsPath: componentsPath,
|
||||
ResourcesPath: resourcesPath,
|
||||
ResourcesPaths: resourcesPaths,
|
||||
AppSSL: appSSL,
|
||||
MaxRequestBodySize: maxRequestBodySize,
|
||||
HTTPReadBufferSize: readBufferSize,
|
||||
|
|
@ -171,19 +176,20 @@ dapr run --run-file /path/to/directory
|
|||
AppHealthThreshold: appHealthThreshold,
|
||||
EnableAPILogging: enableAPILogging,
|
||||
APIListenAddresses: apiListenAddresses,
|
||||
DaprdInstallPath: daprPath,
|
||||
DaprdInstallPath: daprRuntimePath,
|
||||
}
|
||||
output, err := runExec.NewOutput(&standalone.RunConfig{
|
||||
AppID: appID,
|
||||
AppPort: appPort,
|
||||
HTTPPort: port,
|
||||
GRPCPort: grpcPort,
|
||||
ProfilePort: profilePort,
|
||||
Command: args,
|
||||
MetricsPort: metricsPort,
|
||||
UnixDomainSocket: unixDomainSocket,
|
||||
InternalGRPCPort: internalGRPCPort,
|
||||
SharedRunConfig: *sharedRunConfig,
|
||||
AppID: appID,
|
||||
AppChannelAddress: appChannelAddress,
|
||||
AppPort: appPort,
|
||||
HTTPPort: port,
|
||||
GRPCPort: grpcPort,
|
||||
ProfilePort: profilePort,
|
||||
Command: args,
|
||||
MetricsPort: metricsPort,
|
||||
UnixDomainSocket: unixDomainSocket,
|
||||
InternalGRPCPort: internalGRPCPort,
|
||||
SharedRunConfig: *sharedRunConfig,
|
||||
})
|
||||
if err != nil {
|
||||
print.FailureStatusEvent(os.Stderr, err.Error())
|
||||
|
|
@ -354,15 +360,23 @@ dapr run --run-file /path/to/directory
|
|||
}
|
||||
|
||||
// Metadata API is only available if app has started listening to port, so wait for app to start before calling metadata API.
|
||||
err = metadata.Put(output.DaprHTTPPort, "cliPID", strconv.Itoa(os.Getpid()), appID, unixDomainSocket)
|
||||
err = metadata.Put(output.DaprHTTPPort, "cliPID", strconv.Itoa(os.Getpid()), output.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.WarningStatusEvent(os.Stdout, "Could not update sidecar metadata for cliPID: %s", err.Error())
|
||||
}
|
||||
|
||||
if output.AppCMD != nil {
|
||||
if output.AppCMD.Process != nil {
|
||||
print.InfoStatusEvent(os.Stdout, fmt.Sprintf("Updating metadata for appPID: %d", output.AppCMD.Process.Pid))
|
||||
err = metadata.Put(output.DaprHTTPPort, "appPID", strconv.Itoa(output.AppCMD.Process.Pid), output.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.WarningStatusEvent(os.Stdout, "Could not update sidecar metadata for appPID: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
appCommand := strings.Join(args, " ")
|
||||
print.InfoStatusEvent(os.Stdout, fmt.Sprintf("Updating metadata for app command: %s", appCommand))
|
||||
err = metadata.Put(output.DaprHTTPPort, "appCommand", appCommand, appID, unixDomainSocket)
|
||||
err = metadata.Put(output.DaprHTTPPort, "appCommand", appCommand, output.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.WarningStatusEvent(os.Stdout, "Could not update sidecar metadata for appCommand: %s", err.Error())
|
||||
} else {
|
||||
|
|
@ -426,14 +440,16 @@ func init() {
|
|||
RunCmd.Flags().IntVarP(&profilePort, "profile-port", "", -1, "The port for the profile server to listen on")
|
||||
RunCmd.Flags().StringVarP(&logLevel, "log-level", "", "info", "The log verbosity. Valid values are: debug, info, warn, error, fatal, or panic")
|
||||
RunCmd.Flags().IntVarP(&maxConcurrency, "app-max-concurrency", "", -1, "The concurrency level of the application, otherwise is unlimited")
|
||||
RunCmd.Flags().StringVarP(&protocol, "app-protocol", "P", "http", "The protocol (gRPC or HTTP) Dapr uses to talk to the application")
|
||||
RunCmd.Flags().StringVarP(&componentsPath, "components-path", "d", "", "The path for components directory")
|
||||
RunCmd.Flags().StringVarP(&resourcesPath, "resources-path", "", "", "The path for resources directory")
|
||||
RunCmd.Flags().StringVarP(&protocol, "app-protocol", "P", "http", "The protocol (grpc, grpcs, http, https, h2c) Dapr uses to talk to the application")
|
||||
RunCmd.Flags().StringVarP(&componentsPath, "components-path", "d", "", "The path for components directory. Default is $HOME/.dapr/components or %USERPROFILE%\\.dapr\\components")
|
||||
RunCmd.Flags().StringSliceVarP(&resourcesPaths, "resources-path", "", []string{}, "The path for resources directory")
|
||||
// TODO: Remove below line once the flag is removed in the future releases.
|
||||
// By marking this as deprecated, the flag will be hidden from the help menu, but will continue to work. It will show a warning message when used.
|
||||
RunCmd.Flags().MarkDeprecated("components-path", "This flag is deprecated and will be removed in the future releases. Use \"resources-path\" flag instead")
|
||||
RunCmd.Flags().String("placement-host-address", "localhost", "The address of the placement service. Format is either <hostname> for default port or <hostname>:<port> for custom port")
|
||||
// TODO: Remove below flag once the flag is removed in runtime in future release.
|
||||
RunCmd.Flags().BoolVar(&appSSL, "app-ssl", false, "Enable https when Dapr invokes the application")
|
||||
RunCmd.Flags().MarkDeprecated("app-ssl", "This flag is deprecated and will be removed in the future releases. Use \"app-protocol\" flag with https or grpcs values instead")
|
||||
RunCmd.Flags().IntVarP(&metricsPort, "metrics-port", "M", -1, "The port of metrics on dapr")
|
||||
RunCmd.Flags().BoolP("help", "h", false, "Print this help message")
|
||||
RunCmd.Flags().IntVarP(&maxRequestBodySize, "dapr-http-max-request-size", "", -1, "Max size of request body in MB")
|
||||
|
|
@ -447,10 +463,11 @@ func init() {
|
|||
RunCmd.Flags().BoolVar(&enableAPILogging, "enable-api-logging", false, "Log API calls at INFO verbosity. Valid values are: true or false")
|
||||
RunCmd.Flags().StringVar(&apiListenAddresses, "dapr-listen-addresses", "", "Comma separated list of IP addresses that sidecar will listen to")
|
||||
RunCmd.Flags().StringVarP(&runFilePath, "run-file", "f", "", "Path to the run template file for the list of apps to run")
|
||||
RunCmd.Flags().StringVarP(&appChannelAddress, "app-channel-address", "", utils.DefaultAppChannelAddress, "The network address the application listens on")
|
||||
RootCmd.AddCommand(RunCmd)
|
||||
}
|
||||
|
||||
func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
|
||||
func executeRun(runTemplateName, runFilePath string, apps []runfileconfig.App) (bool, error) {
|
||||
var exitWithError bool
|
||||
|
||||
// setup shutdown notify channel.
|
||||
|
|
@ -464,6 +481,8 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
|
|||
// This is done to provide a better grouping, which can be used to control all the proceses started by "dapr run -f".
|
||||
daprsyscall.CreateProcessGroupID()
|
||||
|
||||
print.WarningStatusEvent(os.Stdout, "This is a preview feature and subject to change in future releases.")
|
||||
|
||||
for _, app := range apps {
|
||||
print.StatusEvent(os.Stdout, print.LogInfo, "Validating config and starting app %q", app.RunConfig.AppID)
|
||||
// Set defaults if zero value provided in config yaml.
|
||||
|
|
@ -487,13 +506,17 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
|
|||
}
|
||||
// Combined multiwriter for logs.
|
||||
var appDaprdWriter io.Writer
|
||||
// appLogWriterCloser is used when app command is present.
|
||||
var appLogWriterCloser io.WriteCloser
|
||||
daprdLogWriterCloser := app.DaprdLogWriteCloser
|
||||
// appLogWriter is used when app command is present.
|
||||
var appLogWriter io.Writer
|
||||
// A custom writer used for trimming ASCII color codes from logs when writing to files.
|
||||
var customAppLogWriter io.Writer
|
||||
|
||||
daprdLogWriterCloser := getLogWriter(app.DaprdLogWriteCloser, app.DaprdLogDestination)
|
||||
|
||||
if len(runConfig.Command) == 0 {
|
||||
print.StatusEvent(os.Stdout, print.LogWarning, "No application command found for app %q present in %s", runConfig.AppID, runFilePath)
|
||||
appDaprdWriter = app.DaprdLogWriteCloser
|
||||
appLogWriterCloser = app.DaprdLogWriteCloser
|
||||
appDaprdWriter = getAppDaprdWriter(app, true)
|
||||
appLogWriter = app.DaprdLogWriteCloser
|
||||
} else {
|
||||
err = app.CreateAppLogFile()
|
||||
if err != nil {
|
||||
|
|
@ -501,14 +524,13 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
|
|||
exitWithError = true
|
||||
break
|
||||
}
|
||||
appDaprdWriter = io.MultiWriter(app.AppLogWriteCloser, app.DaprdLogWriteCloser)
|
||||
appLogWriterCloser = app.AppLogWriteCloser
|
||||
appDaprdWriter = getAppDaprdWriter(app, false)
|
||||
appLogWriter = getLogWriter(app.AppLogWriteCloser, app.AppLogDestination)
|
||||
}
|
||||
|
||||
customAppLogWriter = print.CustomLogWriter{W: appLogWriter}
|
||||
runState, err := startDaprdAndAppProcesses(&runConfig, app.AppDirPath, sigCh,
|
||||
daprdLogWriterCloser, daprdLogWriterCloser, appLogWriterCloser, appLogWriterCloser)
|
||||
daprdLogWriterCloser, daprdLogWriterCloser, customAppLogWriter, customAppLogWriter)
|
||||
if err != nil {
|
||||
print.StatusEvent(os.Stdout, print.LogFailure, "Error starting Dapr and app (%q): %s", app.AppID, err.Error())
|
||||
print.StatusEvent(appDaprdWriter, print.LogFailure, "Error starting Dapr and app (%q): %s", app.AppID, err.Error())
|
||||
exitWithError = true
|
||||
break
|
||||
|
|
@ -522,9 +544,27 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
|
|||
// Update extended metadata with run file path.
|
||||
putRunFilePathInMeta(runState, runFilePath)
|
||||
|
||||
// Update extended metadata with run file path.
|
||||
putRunTemplateNameInMeta(runState, runTemplateName)
|
||||
|
||||
// Update extended metadata with app log file path.
|
||||
if app.AppLogDestination != standalone.Console {
|
||||
putAppLogFilePathInMeta(runState, app.AppLogFileName)
|
||||
}
|
||||
|
||||
// Update extended metadata with daprd log file path.
|
||||
if app.DaprdLogDestination != standalone.Console {
|
||||
putDaprLogFilePathInMeta(runState, app.DaprdLogFileName)
|
||||
}
|
||||
|
||||
if runState.AppCMD.Command != nil {
|
||||
putAppCommandInMeta(runConfig, runState)
|
||||
|
||||
if runState.AppCMD.Command.Process != nil {
|
||||
putAppProcessIDInMeta(runState)
|
||||
}
|
||||
}
|
||||
|
||||
print.StatusEvent(runState.DaprCMD.OutputWriter, print.LogSuccess, "You're up and running! Dapr logs will appear here.\n")
|
||||
logInformationalStatusToStdout(app)
|
||||
}
|
||||
|
|
@ -552,6 +592,43 @@ func executeRun(runFilePath string, apps []runfileconfig.App) (bool, error) {
|
|||
return exitWithError, closeError
|
||||
}
|
||||
|
||||
// getAppDaprdWriter returns the writer for writing logs common to both daprd, app and stdout.
|
||||
func getAppDaprdWriter(app runfileconfig.App, isAppCommandEmpty bool) io.Writer {
|
||||
var appDaprdWriter io.Writer
|
||||
if isAppCommandEmpty {
|
||||
if app.DaprdLogDestination != standalone.Console {
|
||||
appDaprdWriter = io.MultiWriter(os.Stdout, app.DaprdLogWriteCloser)
|
||||
} else {
|
||||
appDaprdWriter = os.Stdout
|
||||
}
|
||||
} else {
|
||||
if app.AppLogDestination != standalone.Console && app.DaprdLogDestination != standalone.Console {
|
||||
appDaprdWriter = io.MultiWriter(app.AppLogWriteCloser, app.DaprdLogWriteCloser, os.Stdout)
|
||||
} else if app.AppLogDestination != standalone.Console {
|
||||
appDaprdWriter = io.MultiWriter(app.AppLogWriteCloser, os.Stdout)
|
||||
} else if app.DaprdLogDestination != standalone.Console {
|
||||
appDaprdWriter = io.MultiWriter(app.DaprdLogWriteCloser, os.Stdout)
|
||||
} else {
|
||||
appDaprdWriter = os.Stdout
|
||||
}
|
||||
}
|
||||
return appDaprdWriter
|
||||
}
|
||||
|
||||
// getLogWriter returns the log writer based on the log destination.
|
||||
func getLogWriter(fileLogWriterCloser io.WriteCloser, logDestination standalone.LogDestType) io.Writer {
|
||||
var logWriter io.Writer
|
||||
switch logDestination {
|
||||
case standalone.Console:
|
||||
logWriter = os.Stdout
|
||||
case standalone.File:
|
||||
logWriter = fileLogWriterCloser
|
||||
case standalone.FileAndConsole:
|
||||
logWriter = io.MultiWriter(os.Stdout, fileLogWriterCloser)
|
||||
}
|
||||
return logWriter
|
||||
}
|
||||
|
||||
func logInformationalStatusToStdout(app runfileconfig.App) {
|
||||
print.InfoStatusEvent(os.Stdout, "Started Dapr with app id %q. HTTP Port: %d. gRPC Port: %d",
|
||||
app.AppID, app.RunConfig.HTTPPort, app.RunConfig.GRPCPort)
|
||||
|
|
@ -588,7 +665,7 @@ func executeRunWithAppsConfigFile(runFilePath string) {
|
|||
print.StatusEvent(os.Stdout, print.LogFailure, "No apps to run")
|
||||
os.Exit(1)
|
||||
}
|
||||
exitWithError, closeErr := executeRun(runFilePath, apps)
|
||||
exitWithError, closeErr := executeRun(config.Name, runFilePath, apps)
|
||||
if exitWithError {
|
||||
if closeErr != nil {
|
||||
print.StatusEvent(os.Stdout, print.LogFailure, "Error closing resources: %s", closeErr)
|
||||
|
|
@ -742,25 +819,14 @@ func startAppProcess(runConfig *standalone.RunConfig, runE *runExec.RunExec,
|
|||
outScanner := bufio.NewScanner(stdOutPipe)
|
||||
go func() {
|
||||
for errScanner.Scan() {
|
||||
if runE.AppCMD.ErrorWriter == os.Stderr {
|
||||
// Add color and prefix to log and output to Stderr.
|
||||
fmt.Fprintln(runE.AppCMD.ErrorWriter, print.Blue(fmt.Sprintf("== APP == %s", errScanner.Text())))
|
||||
} else {
|
||||
// Directly output app logs to the error writer.
|
||||
fmt.Fprintln(runE.AppCMD.ErrorWriter, errScanner.Text())
|
||||
}
|
||||
fmt.Fprintln(runE.AppCMD.ErrorWriter, print.Blue(fmt.Sprintf("== APP - %s == %s", runE.AppID,
|
||||
errScanner.Text())))
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for outScanner.Scan() {
|
||||
if runE.AppCMD.OutputWriter == os.Stdout {
|
||||
// Add color and prefix to log and output to Stdout.
|
||||
fmt.Fprintln(runE.AppCMD.OutputWriter, print.Blue(fmt.Sprintf("== APP == %s", outScanner.Text())))
|
||||
} else {
|
||||
// Directly output app logs to the output writer.
|
||||
fmt.Fprintln(runE.AppCMD.OutputWriter, outScanner.Text())
|
||||
}
|
||||
fmt.Fprintln(runE.AppCMD.OutputWriter, print.Blue(fmt.Sprintf("== APP - %s == %s", runE.AppID, outScanner.Text())))
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
@ -813,10 +879,8 @@ func startDaprdProcess(runConfig *standalone.RunConfig, runE *runExec.RunExec,
|
|||
daprRunning <- false
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
daprdErr := runE.DaprCMD.Command.Wait()
|
||||
|
||||
if daprdErr != nil {
|
||||
runE.DaprCMD.CommandErr = daprdErr
|
||||
print.StatusEvent(runE.DaprCMD.ErrorWriter, print.LogFailure, "The daprd process exited with error code: %s", daprdErr.Error())
|
||||
|
|
@ -905,6 +969,14 @@ func putCLIProcessIDInMeta(runE *runExec.RunExec, pid int) {
|
|||
}
|
||||
}
|
||||
|
||||
func putAppProcessIDInMeta(runE *runExec.RunExec) {
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogInfo, "Updating metadata for appPID: %d", runE.AppCMD.Command.Process.Pid)
|
||||
err := metadata.Put(runE.DaprHTTPPort, "appPID", strconv.Itoa(runE.AppCMD.Command.Process.Pid), runE.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for appPID: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// putAppCommandInMeta puts the app command in metadata so that it can be used by the CLI to stop the app.
|
||||
func putAppCommandInMeta(runConfig standalone.RunConfig, runE *runExec.RunExec) {
|
||||
appCommand := strings.Join(runConfig.Command, " ")
|
||||
|
|
@ -914,7 +986,6 @@ func putAppCommandInMeta(runConfig standalone.RunConfig, runE *runExec.RunExec)
|
|||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for appCommand: %s", err.Error())
|
||||
return
|
||||
}
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogSuccess, "You're up and running! Dapr logs will appear here.\n")
|
||||
}
|
||||
|
||||
// putRunFilePathInMeta puts the absolute path of run file in metadata so that it can be used by the CLI to stop all apps started by this run file.
|
||||
|
|
@ -926,7 +997,31 @@ func putRunFilePathInMeta(runE *runExec.RunExec, runFilePath string) {
|
|||
}
|
||||
err = metadata.Put(runE.DaprHTTPPort, "runTemplatePath", runFilePath, runE.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for runFile: %s", err.Error())
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for run file path: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// putRunTemplateNameInMeta puts the name of the run file in metadata so that it can be used by the CLI to stop all apps started by this run file.
|
||||
func putRunTemplateNameInMeta(runE *runExec.RunExec, runTemplateName string) {
|
||||
err := metadata.Put(runE.DaprHTTPPort, "runTemplateName", runTemplateName, runE.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for run template name: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// putAppLogFilePathInMeta puts the absolute path of app log file in metadata so that it can be used by the CLI to stop the app.
|
||||
func putAppLogFilePathInMeta(runE *runExec.RunExec, appLogFilePath string) {
|
||||
err := metadata.Put(runE.DaprHTTPPort, "appLogPath", appLogFilePath, runE.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for app log file path: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// putDaprLogFilePathInMeta puts the absolute path of Dapr log file in metadata so that it can be used by the CLI to stop the app.
|
||||
func putDaprLogFilePathInMeta(runE *runExec.RunExec, daprLogFilePath string) {
|
||||
err := metadata.Put(runE.DaprHTTPPort, "daprdLogPath", daprLogFilePath, runE.AppID, unixDomainSocket)
|
||||
if err != nil {
|
||||
print.StatusEvent(runE.DaprCMD.OutputWriter, print.LogWarning, "Could not update sidecar metadata for dapr log file path: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ dapr uninstall --all
|
|||
# Uninstall from Kubernetes
|
||||
dapr uninstall -k
|
||||
|
||||
# Uninstall Dapr from non-default install directory (default is $HOME/.dapr)
|
||||
dapr uninstall --dapr-path <path-to-install-directory>
|
||||
# Uninstall Dapr from non-default install directory
|
||||
# This will remove the .dapr directory present in the path <path-to-install-directory>
|
||||
dapr uninstall --runtime-path <path-to-install-directory>
|
||||
`,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlag("network", cmd.Flags().Lookup("network"))
|
||||
|
|
@ -59,8 +60,8 @@ dapr uninstall --dapr-path <path-to-install-directory>
|
|||
var err error
|
||||
|
||||
if uninstallKubernetes {
|
||||
if len(strings.TrimSpace(daprPath)) != 0 {
|
||||
print.FailureStatusEvent(os.Stderr, "--dapr-path is only valid for self-hosted mode")
|
||||
if len(strings.TrimSpace(daprRuntimePath)) != 0 {
|
||||
print.FailureStatusEvent(os.Stderr, "--runtime-path is only valid for self-hosted mode")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ dapr uninstall --dapr-path <path-to-install-directory>
|
|||
}
|
||||
print.InfoStatusEvent(os.Stdout, "Removing Dapr from your machine...")
|
||||
dockerNetwork := viper.GetString("network")
|
||||
err = standalone.Uninstall(uninstallAll, dockerNetwork, uninstallContainerRuntime, daprPath)
|
||||
err = standalone.Uninstall(uninstallAll, dockerNetwork, uninstallContainerRuntime, daprRuntimePath)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -25,8 +25,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
upgradeRuntimeVersion string
|
||||
upgradeImageVariant string
|
||||
upgradeRuntimeVersion string
|
||||
upgradeImageVariant string
|
||||
upgradeDashboardVersion string
|
||||
)
|
||||
|
||||
var UpgradeCmd = &cobra.Command{
|
||||
|
|
@ -58,6 +59,7 @@ dapr upgrade -k
|
|||
}
|
||||
err = kubernetes.Upgrade(kubernetes.UpgradeConfig{
|
||||
RuntimeVersion: upgradeRuntimeVersion,
|
||||
DashboardVersion: upgradeDashboardVersion,
|
||||
Args: values,
|
||||
Timeout: timeout,
|
||||
ImageRegistryURI: imageRegistryURI,
|
||||
|
|
@ -78,6 +80,7 @@ func init() {
|
|||
UpgradeCmd.Flags().BoolVarP(&kubernetesMode, "kubernetes", "k", false, "Upgrade or downgrade Dapr in a Kubernetes cluster")
|
||||
UpgradeCmd.Flags().UintVarP(&timeout, "timeout", "", 300, "The timeout for the Kubernetes upgrade")
|
||||
UpgradeCmd.Flags().StringVarP(&upgradeRuntimeVersion, "runtime-version", "", "", "The version of the Dapr runtime to upgrade or downgrade to, for example: 1.0.0")
|
||||
UpgradeCmd.Flags().StringVarP(&upgradeDashboardVersion, "dashboard-version", "", "", "The version of the Dapr dashboard to upgrade or downgrade to, for example: 0.13.0")
|
||||
UpgradeCmd.Flags().BoolP("help", "h", false, "Print this help message")
|
||||
UpgradeCmd.Flags().StringArrayVar(&values, "set", []string{}, "set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
|
||||
UpgradeCmd.Flags().String("image-registry", "", "Custom/Private docker image repository URL")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
## Using with `docker-in-docker` feature
|
||||
|
||||
Since the Dapr CLI requires Docker, an easy way to get started is to use the `docker-in-docker` feature. This will install a separate Docker daemon inside the container for `dapr` to use:
|
||||
|
||||
```jsonc
|
||||
"features": {
|
||||
// Install the Dapr CLI
|
||||
"ghcr.io/dapr/cli/dapr-cli:0": {},
|
||||
// Enable Docker (via Docker-in-Docker)
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
||||
// Alternatively, use Docker-outside-of-Docker (uses Docker in the host)
|
||||
//"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
|
||||
}
|
||||
```
|
||||
|
||||
For more details on setting up a Dev Container with Dapr, see the [Developing Dapr applications with Dev Containers docs](https://docs.dapr.io/developing-applications/local-development/ides/vscode/vscode-remote-dev-containers/).
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
# dapr-cli (dapr-cli)
|
||||
|
||||
Install the Dapr CLI
|
||||
|
||||
## Example Usage
|
||||
|
||||
```json
|
||||
"features": {
|
||||
"ghcr.io/dapr/cli/dapr-cli:0": {}
|
||||
}
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
| Options Id | Description | Type | Default Value |
|
||||
|-----|-----|-----|-----|
|
||||
| version | Version of the Dapr CLI to install (or "latest") | string | latest |
|
||||
|
||||
## Using with `docker-in-docker` feature
|
||||
|
||||
Since the Dapr CLI requires Docker, an easy way to get started is to use the `docker-in-docker` feature. This will install a separate Docker daemon inside the container for `dapr` to use:
|
||||
|
||||
```jsonc
|
||||
"features": {
|
||||
// Install the Dapr CLI
|
||||
"ghcr.io/dapr/cli/dapr-cli:0": {},
|
||||
// Enable Docker (via Docker-in-Docker)
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
|
||||
// Alternatively, use Docker-outside-of-Docker (uses Docker in the host)
|
||||
//"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
|
||||
}
|
||||
```
|
||||
|
||||
For more details on setting up a Dev Container with Dapr, see the [Developing Dapr applications with Dev Containers docs](https://docs.dapr.io/developing-applications/local-development/ides/vscode/vscode-remote-dev-containers/).
|
||||
|
||||
---
|
||||
|
||||
_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/dapr/cli/blob/master/dev-container-feature/src/dapr-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "dapr-cli",
|
||||
"id": "dapr-cli",
|
||||
"version": "0.1.0",
|
||||
"description": "Install the Dapr CLI",
|
||||
"options": {
|
||||
"version": {
|
||||
"type": "string",
|
||||
"proposals": [
|
||||
"latest"
|
||||
],
|
||||
"default": "latest",
|
||||
"description": "Version of the Dapr CLI to install (or \"latest\")"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
|
||||
###################
|
||||
# Helper Functions
|
||||
###################
|
||||
|
||||
# Re-used from https://github.com/devcontainers/features/blob/4a9929f96485061e3778b35848e21d7c3c193480/src/dotnet/install.sh#L74
|
||||
|
||||
apt_get_update()
|
||||
{
|
||||
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
||||
echo "Running apt-get update..."
|
||||
apt-get update -y
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if packages are installed and installs them if not.
|
||||
check_packages() {
|
||||
if ! dpkg -s "$@" > /dev/null 2>&1; then
|
||||
apt_get_update
|
||||
apt-get -y install --no-install-recommends "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
get_latest_release() {
|
||||
curl --silent "https://api.github.com/repos/dapr/cli/releases/latest" |
|
||||
grep '"tag_name":' | sed -E "s/.*\"v([^\"]+)\".*/\1/"
|
||||
}
|
||||
|
||||
###################
|
||||
# Install Dapr CLI
|
||||
###################
|
||||
echo "Activating feature 'dapr-cli'"
|
||||
|
||||
check_packages curl ca-certificates
|
||||
|
||||
VERSION=${VERSION:-"latest"}
|
||||
|
||||
if [ "${VERSION}" = "latest" ]; then
|
||||
VERSION=$(get_latest_release)
|
||||
fi
|
||||
|
||||
ARCH=$(uname -m)
|
||||
case $ARCH in
|
||||
armv7*) ARCH="arm";;
|
||||
aarch64) ARCH="arm64";;
|
||||
x86_64) ARCH="amd64";;
|
||||
esac
|
||||
|
||||
curl -SsL "https://github.com/dapr/cli/releases/download/v${VERSION}/dapr_linux_${ARCH}.tar.gz" | \
|
||||
tar -zx -C /usr/local/bin dapr
|
||||
|
||||
dapr --version
|
||||
|
||||
## Write bash completion code to a file and source it from .bash_profile
|
||||
mkdir -p $_REMOTE_USER_HOME/.dapr
|
||||
dapr completion bash > $_REMOTE_USER_HOME/.dapr/completion.bash.inc
|
||||
printf "
|
||||
## dapr shell completion
|
||||
source '$_REMOTE_USER_HOME/.dapr/completion.bash.inc'
|
||||
" >> $_REMOTE_USER_HOME/.bashrc
|
||||
chown -R $_REMOTE_USER:$_REMOTE_USER $_REMOTE_USER_HOME/.dapr
|
||||
chown $_REMOTE_USER:$_REMOTE_USER $_REMOTE_USER_HOME/.bashrc
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#!/bin/bash
|
||||
|
||||
# This test file will be executed against an auto-generated devcontainer.json that
|
||||
# includes the 'dapr-cli' Feature with no options.
|
||||
#
|
||||
# For more information, see: https://github.com/devcontainers/cli/blob/main/docs/features/test.md
|
||||
#
|
||||
# Eg:
|
||||
# {
|
||||
# "image": "<..some-base-image...>",
|
||||
# "features": {
|
||||
# "dapr-cli": {}
|
||||
# },
|
||||
# "remoteUser": "root"
|
||||
# }
|
||||
#
|
||||
# Thus, the value of all options will fall back to the default value in
|
||||
# the Feature's 'devcontainer-feature.json'.
|
||||
#
|
||||
# These scripts are run as 'root' by default. Although that can be changed
|
||||
# with the '--remote-user' flag.
|
||||
#
|
||||
# This test can be run with the following command (from the repo root folder):
|
||||
#
|
||||
# devcontainer features test \
|
||||
# --features dapr-cli \
|
||||
# --remote-user root \
|
||||
# --skip-scenarios \
|
||||
# --base-image mcr.microsoft.com/devcontainers/base:ubuntu \
|
||||
# --project-folder dev-container-feature
|
||||
|
||||
set -e
|
||||
|
||||
# Optional: Import test library bundled with the devcontainer CLI
|
||||
# Provides the 'check' and 'reportResults' commands.
|
||||
source dev-container-features-test-lib
|
||||
|
||||
# Feature-specific tests
|
||||
# The 'check' command comes from the dev-container-features-test-lib.
|
||||
check "execute command" bash -c "dapr --help | grep 'Distributed Application Runtime'"
|
||||
|
||||
# Report results
|
||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
||||
reportResults
|
||||
|
|
@ -7,7 +7,7 @@ This document helps you get started developing Dapr CLI. If you find any problem
|
|||
|
||||
### Linux and MacOS
|
||||
|
||||
1. The Go language environment `1.19` [(instructions)](https://golang.org/doc/install#tarball).
|
||||
1. The Go language environment `1.20` [(instructions)](https://golang.org/doc/install#tarball).
|
||||
* Make sure that your GOPATH and PATH are configured correctly
|
||||
```bash
|
||||
export GOPATH=~/go
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
# Release Guide
|
||||
|
||||
This document describes how to release Dapr CLI along with associated artifacts.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Only the repository maintainers and release team are allowed to execute the below steps.
|
||||
|
||||
## Pre-release build
|
||||
|
||||
Pre-release build will be built from `release-<major>.<minor>` branch and versioned by git version tag suffix e.g. `-rc.0`, `-rc.1`, etc. This build is not released to users who use the latest stable version.
|
||||
**Pre-release process**
|
||||
1. Create a PR to update the `Dapr runtime` and `Dapr dashboard` pre-release versions in workflow and tests files wherever applicable, and merge the PR to master branch. For example, please take a look at this PR - https://github.com/dapr/cli/pull/1019. Please note that this PR is just for reference and only reflects the absolute minimum number of file changes. These versions update could lead to some other changes also.
|
||||
|
||||
2. Create branch `release-<major>.<minor>` from master and push the branch. e.g. `release-1.11`. You can use the github web UI to create the branch or use the following command.
|
||||
|
||||
```sh
|
||||
$ git checkout master && git reset --hard upstream/master && git pull upstream master
|
||||
$ git checkout -b release-1.11
|
||||
$ git push upstream release-1.11
|
||||
```
|
||||
3. Add pre-release version tag (with suffix -rc.0 e.g. v1.11.0-rc.0) and push the tag.
|
||||
|
||||
```sh
|
||||
$ git tag "v1.11.0-rc.0" -m "v1.11.0-rc.0"
|
||||
$ git push upstream v1.11.0-rc.0
|
||||
|
||||
```
|
||||
4. CI creates the new build artifacts.
|
||||
5. Test and validate the functionalities with the specific version.
|
||||
6. If there are regressions and bugs, fix them in release-* branch. e.g `release-1.11` branch.
|
||||
7. Create new pre-release version tag (with suffix -rc.1, -rc.2, etc).
|
||||
8. Repeat from 5 to 7 until all bugs are fixed.
|
||||
|
||||
|
||||
## Release the stable version to users
|
||||
|
||||
> **Note**: Make sure stable versions of `dapr runtime` and `dapr dashboard` are released before releasing the CLI and update their references in workflow and tests files wherever applicable.
|
||||
|
||||
Once all bugs are fixed, stable version can be released. Create a new git version tag (without the suffix -rc.x e.g. v1.11.0) and push the tag. CI will create the new build artifacts and release them.
|
||||
|
||||
## Release Patch version
|
||||
|
||||
Work on the existing `release-<major>.<minor>` branch to release a patch version. Once all bugs are fixed, create a new patch version tag, such as `v1.11.1-rc.0`. After verifying the fixes on this pre-release, create a new git version tag such as `v1.11.1` and push the tag. CI will create the new build artifacts and release them.
|
||||
245
go.mod
245
go.mod
|
|
@ -1,16 +1,16 @@
|
|||
module github.com/dapr/cli
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect
|
||||
github.com/Pallinder/sillyname-go v0.0.0-20130730142914-97aeae9e6ba1
|
||||
github.com/briandowns/spinner v1.19.0
|
||||
github.com/dapr/dapr v1.9.0
|
||||
github.com/dapr/dapr v1.11.0
|
||||
github.com/dapr/go-sdk v1.6.0
|
||||
github.com/docker/docker v20.10.20+incompatible
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/docker/docker v20.10.21+incompatible
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/gocarina/gocsv v0.0.0-20220927221512-ad3251f9fa25
|
||||
github.com/hashicorp/go-retryablehttp v0.7.1
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
|
|
@ -18,119 +18,136 @@ require (
|
|||
github.com/nightlyone/lockfile v1.0.0
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
||||
github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/spf13/cobra v1.6.0
|
||||
github.com/spf13/cobra v1.6.1
|
||||
github.com/spf13/viper v1.13.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
|
||||
github.com/stretchr/testify v1.8.3
|
||||
golang.org/x/sys v0.8.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
helm.sh/helm/v3 v3.10.3
|
||||
k8s.io/api v0.25.2
|
||||
k8s.io/apiextensions-apiserver v0.25.2
|
||||
k8s.io/apimachinery v0.25.2
|
||||
k8s.io/cli-runtime v0.25.2
|
||||
k8s.io/client-go v0.25.2
|
||||
helm.sh/helm/v3 v3.11.1
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/apiextensions-apiserver v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
k8s.io/cli-runtime v0.26.3
|
||||
k8s.io/client-go v0.26.3
|
||||
k8s.io/helm v2.16.10+incompatible
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||
require github.com/evanphx/json-patch v5.6.0+incompatible
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.2.0
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.6.1 // indirect
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.1 // indirect
|
||||
cloud.google.com/go/compute v1.19.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect
|
||||
github.com/AdhityaRamadhanus/fasthttpcors v0.0.0-20170121111917-d4c07198763a // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/BurntSushi/toml v1.1.0 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.5.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.3 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20220418222510-f25a4f6275ed // indirect
|
||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.6 // indirect
|
||||
github.com/PuerkitoBio/purell v1.2.0 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/bufbuild/protocompile v0.4.0 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/containerd/containerd v1.6.6 // indirect
|
||||
github.com/containerd/continuity v0.2.2 // indirect
|
||||
github.com/chebyrash/promise v0.0.0-20220530143319-1123826567d6 // indirect
|
||||
github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.13.0 // indirect
|
||||
github.com/cloudevents/sdk-go/v2 v2.13.0 // indirect
|
||||
github.com/containerd/containerd v1.6.18 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
||||
github.com/dapr/components-contrib v1.9.0-rc.5 // indirect
|
||||
github.com/dapr/kit v0.0.3-0.20220930182601-272e358ba6a7 // indirect
|
||||
github.com/dapr/components-contrib v1.11.0-rc.11 // indirect
|
||||
github.com/dapr/kit v0.11.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/docker/cli v20.10.17+incompatible // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/docker/cli v20.10.21+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.1+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.6.4 // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.2 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/fasthttp/router v1.4.12 // indirect
|
||||
github.com/fsnotify/fsnotify v1.5.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-errors/errors v1.4.0 // indirect
|
||||
github.com/fasthttp/router v1.4.18 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.0.2 // indirect
|
||||
github.com/go-kit/log v0.2.0 // indirect
|
||||
github.com/go-kit/log v0.2.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.5 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/cel-go v0.12.5 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/cel-go v0.13.0 // indirect
|
||||
github.com/google/gnostic v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gosuri/uitable v0.0.4 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/huandu/xstrings v1.3.3 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jhump/protoreflect v1.13.0 // indirect
|
||||
github.com/jhump/protoreflect v1.15.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.15.11 // indirect
|
||||
github.com/klauspost/compress v1.16.3 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/lib/pq v1.10.6 // indirect
|
||||
github.com/lestrrat-go/blackmagic v1.0.1 // indirect
|
||||
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
||||
github.com/lestrrat-go/httprc v1.0.4 // indirect
|
||||
github.com/lestrrat-go/iter v1.0.2 // indirect
|
||||
github.com/lestrrat-go/jwx/v2 v2.0.9 // indirect
|
||||
github.com/lestrrat-go/option v1.0.1 // indirect
|
||||
github.com/lib/pq v1.10.7 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/magiconair/properties v1.8.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/marusama/semaphore/v2 v2.5.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/microsoft/durabletask-go v0.2.4 // indirect
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
||||
|
|
@ -138,84 +155,84 @@ require (
|
|||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
|
||||
github.com/opencontainers/runc v1.1.2 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.4.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
|
||||
github.com/opencontainers/runc v1.1.5 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.4.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.35.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/prometheus/statsd_exporter v0.22.3 // indirect
|
||||
github.com/rubenv/sql-migrate v1.1.2 // indirect
|
||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect
|
||||
github.com/prometheus/client_golang v1.14.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
github.com/prometheus/statsd_exporter v0.22.7 // indirect
|
||||
github.com/rubenv/sql-migrate v1.2.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect
|
||||
github.com/sirupsen/logrus v1.9.2 // indirect
|
||||
github.com/sony/gobreaker v0.5.0 // indirect
|
||||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
github.com/stretchr/objx v0.4.0 // indirect
|
||||
github.com/stretchr/objx v0.5.0 // indirect
|
||||
github.com/subosito/gotenv v1.4.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
||||
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||
github.com/tidwall/transform v0.0.0-20201103190739-32f242e2dbde // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.40.0 // indirect
|
||||
github.com/valyala/fasthttp v1.47.0 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xlab/treeprint v1.1.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.4 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.opentelemetry.io/otel v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.7.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.16.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/otel v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.14.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v0.19.0 // indirect
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect
|
||||
golang.org/x/net v0.0.0-20220927171203-f486391704dc // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/oauth2 v0.8.0 // indirect
|
||||
golang.org/x/sync v0.2.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220622171453-ea41d75dfa0f // indirect
|
||||
google.golang.org/grpc v1.48.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.54.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiserver v0.25.2 // indirect
|
||||
k8s.io/component-base v0.25.2 // indirect
|
||||
k8s.io/klog/v2 v2.70.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
|
||||
k8s.io/kubectl v0.25.2 // indirect
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
|
||||
oras.land/oras-go v1.2.0 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.11.0 // indirect
|
||||
k8s.io/apiserver v0.26.3 // indirect
|
||||
k8s.io/component-base v0.26.3 // indirect
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
k8s.io/kubectl v0.26.0 // indirect
|
||||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
|
||||
oras.land/oras-go v1.2.2 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.14.6 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.12.1 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect
|
||||
|
|
@ -224,9 +241,9 @@ require (
|
|||
|
||||
replace (
|
||||
github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0+incompatible
|
||||
|
||||
github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d
|
||||
github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
|
||||
github.com/russross/blackfriday => github.com/russross/blackfriday v1.5.2
|
||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.25.2
|
||||
k8s.io/client => github.com/kubernetes-client/go v0.0.0-20190928040339-c757968c4c36
|
||||
k8s.io/client-go => k8s.io/client-go v0.25.2
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import (
|
|||
yamlDecoder "k8s.io/apimachinery/pkg/util/yaml"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/dapr/dapr/pkg/injector/sidecar"
|
||||
"github.com/dapr/dapr/pkg/injector/patcher"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -341,8 +341,8 @@ func (p *K8sAnnotator) annotateYAML(input []byte, config AnnotateOptions) ([]byt
|
|||
}
|
||||
|
||||
// Create a patch operation for the annotations.
|
||||
patchOps := []sidecar.PatchOperation{}
|
||||
patchOps = append(patchOps, sidecar.PatchOperation{
|
||||
patchOps := []patcher.PatchOperation{}
|
||||
patchOps = append(patchOps, patcher.PatchOperation{
|
||||
Op: "add",
|
||||
Path: path,
|
||||
Value: annotations,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ func GetDaprHelmChartName(helmConf *helm.Configuration) (string, error) {
|
|||
}
|
||||
var chart string
|
||||
for _, r := range releases {
|
||||
if r.Chart != nil && strings.Contains(r.Chart.Name(), "dapr") {
|
||||
if r.Chart != nil &&
|
||||
strings.Contains(r.Chart.Name(), daprReleaseName) &&
|
||||
!strings.Contains(r.Chart.Name(), dashboardReleaseName) {
|
||||
chart = r.Name
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ func TestConfigurations(t *testing.T) {
|
|||
name: "Yaml one config",
|
||||
configName: "",
|
||||
outputFormat: "yaml",
|
||||
expectedOutput: "- name: appConfig\n namespace: default\n spec:\n apphttppipelinespec:\n handlers: []\n httppipelinespec:\n handlers: []\n tracingspec:\n samplingrate: \"\"\n stdout: false\n zipkin:\n endpointaddresss: \"\"\n otel:\n protocol: \"\"\n endpointAddress: \"\"\n isSecure: false\n metricspec:\n enabled: false\n mtlsspec:\n enabled: false\n workloadcertttl: \"\"\n allowedclockskew: \"\"\n secrets:\n scopes: []\n accesscontrolspec:\n defaultAction: \"\"\n trustDomain: \"\"\n policies: []\n nameresolutionspec:\n component: \"\"\n version: \"\"\n configuration:\n json:\n raw: []\n features: []\n apispec:\n allowed: []\n componentsspec: {}\n",
|
||||
expectedOutput: "- name: appConfig\n namespace: default\n spec:\n apphttppipelinespec:\n handlers: []\n httppipelinespec:\n handlers: []\n tracingspec:\n samplingrate: \"\"\n stdout: false\n zipkin:\n endpointaddresss: \"\"\n otel:\n protocol: \"\"\n endpointAddress: \"\"\n isSecure: false\n metricspec:\n enabled: false\n rules: []\n metricsspec:\n enabled: false\n rules: []\n mtlsspec:\n enabled: false\n workloadcertttl: \"\"\n allowedclockskew: \"\"\n secrets:\n scopes: []\n accesscontrolspec:\n defaultAction: \"\"\n trustDomain: \"\"\n policies: []\n nameresolutionspec:\n component: \"\"\n version: \"\"\n configuration:\n json:\n raw: []\n features: []\n apispec:\n allowed: []\n denied: []\n componentsspec: {}\n loggingspec:\n apiLogging:\n enabled: false\n obfuscateURLs: false\n omitHealthChecks: false\n",
|
||||
errString: "",
|
||||
errorExpected: false,
|
||||
k8sConfig: []v1alpha1.Configuration{
|
||||
|
|
@ -148,7 +148,7 @@ func TestConfigurations(t *testing.T) {
|
|||
name: "Yaml two configs",
|
||||
configName: "",
|
||||
outputFormat: "yaml",
|
||||
expectedOutput: "- name: appConfig1\n namespace: default\n spec:\n apphttppipelinespec:\n handlers: []\n httppipelinespec:\n handlers: []\n tracingspec:\n samplingrate: \"\"\n stdout: false\n zipkin:\n endpointaddresss: \"\"\n otel:\n protocol: \"\"\n endpointAddress: \"\"\n isSecure: false\n metricspec:\n enabled: false\n mtlsspec:\n enabled: false\n workloadcertttl: \"\"\n allowedclockskew: \"\"\n secrets:\n scopes: []\n accesscontrolspec:\n defaultAction: \"\"\n trustDomain: \"\"\n policies: []\n nameresolutionspec:\n component: \"\"\n version: \"\"\n configuration:\n json:\n raw: []\n features: []\n apispec:\n allowed: []\n componentsspec: {}\n- name: appConfig2\n namespace: default\n spec:\n apphttppipelinespec:\n handlers: []\n httppipelinespec:\n handlers: []\n tracingspec:\n samplingrate: \"\"\n stdout: false\n zipkin:\n endpointaddresss: \"\"\n otel:\n protocol: \"\"\n endpointAddress: \"\"\n isSecure: false\n metricspec:\n enabled: false\n mtlsspec:\n enabled: false\n workloadcertttl: \"\"\n allowedclockskew: \"\"\n secrets:\n scopes: []\n accesscontrolspec:\n defaultAction: \"\"\n trustDomain: \"\"\n policies: []\n nameresolutionspec:\n component: \"\"\n version: \"\"\n configuration:\n json:\n raw: []\n features: []\n apispec:\n allowed: []\n componentsspec: {}\n",
|
||||
expectedOutput: "- name: appConfig1\n namespace: default\n spec:\n apphttppipelinespec:\n handlers: []\n httppipelinespec:\n handlers: []\n tracingspec:\n samplingrate: \"\"\n stdout: false\n zipkin:\n endpointaddresss: \"\"\n otel:\n protocol: \"\"\n endpointAddress: \"\"\n isSecure: false\n metricspec:\n enabled: false\n rules: []\n metricsspec:\n enabled: false\n rules: []\n mtlsspec:\n enabled: false\n workloadcertttl: \"\"\n allowedclockskew: \"\"\n secrets:\n scopes: []\n accesscontrolspec:\n defaultAction: \"\"\n trustDomain: \"\"\n policies: []\n nameresolutionspec:\n component: \"\"\n version: \"\"\n configuration:\n json:\n raw: []\n features: []\n apispec:\n allowed: []\n denied: []\n componentsspec: {}\n loggingspec:\n apiLogging:\n enabled: false\n obfuscateURLs: false\n omitHealthChecks: false\n- name: appConfig2\n namespace: default\n spec:\n apphttppipelinespec:\n handlers: []\n httppipelinespec:\n handlers: []\n tracingspec:\n samplingrate: \"\"\n stdout: false\n zipkin:\n endpointaddresss: \"\"\n otel:\n protocol: \"\"\n endpointAddress: \"\"\n isSecure: false\n metricspec:\n enabled: false\n rules: []\n metricsspec:\n enabled: false\n rules: []\n mtlsspec:\n enabled: false\n workloadcertttl: \"\"\n allowedclockskew: \"\"\n secrets:\n scopes: []\n accesscontrolspec:\n defaultAction: \"\"\n trustDomain: \"\"\n policies: []\n nameresolutionspec:\n component: \"\"\n version: \"\"\n configuration:\n json:\n raw: []\n features: []\n apispec:\n allowed: []\n denied: []\n componentsspec: {}\n loggingspec:\n apiLogging:\n enabled: false\n obfuscateURLs: false\n omitHealthChecks: false\n",
|
||||
errString: "",
|
||||
errorExpected: false,
|
||||
k8sConfig: []v1alpha1.Configuration{
|
||||
|
|
@ -174,7 +174,7 @@ func TestConfigurations(t *testing.T) {
|
|||
name: "Json one config",
|
||||
configName: "",
|
||||
outputFormat: "json",
|
||||
expectedOutput: "[\n {\n \"name\": \"appConfig\",\n \"namespace\": \"default\",\n \"spec\": {\n \"appHttpPipeline\": {\n \"handlers\": null\n },\n \"httpPipeline\": {\n \"handlers\": null\n },\n \"tracing\": {\n \"samplingRate\": \"\",\n \"stdout\": false,\n \"zipkin\": {\n \"endpointAddress\": \"\"\n },\n \"otel\": {\n \"protocol\": \"\",\n \"endpointAddress\": \"\",\n \"isSecure\": false\n }\n },\n \"metric\": {\n \"enabled\": false\n },\n \"mtls\": {\n \"enabled\": false,\n \"workloadCertTTL\": \"\",\n \"allowedClockSkew\": \"\"\n },\n \"secrets\": {\n \"scopes\": null\n },\n \"accessControl\": {\n \"defaultAction\": \"\",\n \"trustDomain\": \"\",\n \"policies\": null\n },\n \"nameResolution\": {\n \"component\": \"\",\n \"version\": \"\",\n \"configuration\": null\n },\n \"api\": {},\n \"components\": {}\n }\n }\n]",
|
||||
expectedOutput: "[\n {\n \"name\": \"appConfig\",\n \"namespace\": \"default\",\n \"spec\": {\n \"appHttpPipeline\": {\n \"handlers\": null\n },\n \"httpPipeline\": {\n \"handlers\": null\n },\n \"tracing\": {\n \"samplingRate\": \"\",\n \"stdout\": false,\n \"zipkin\": {\n \"endpointAddress\": \"\"\n },\n \"otel\": {\n \"protocol\": \"\",\n \"endpointAddress\": \"\",\n \"isSecure\": false\n }\n },\n \"metric\": {\n \"enabled\": false,\n \"rules\": null\n },\n \"metrics\": {\n \"enabled\": false,\n \"rules\": null\n },\n \"mtls\": {\n \"enabled\": false,\n \"workloadCertTTL\": \"\",\n \"allowedClockSkew\": \"\"\n },\n \"secrets\": {\n \"scopes\": null\n },\n \"accessControl\": {\n \"defaultAction\": \"\",\n \"trustDomain\": \"\",\n \"policies\": null\n },\n \"nameResolution\": {\n \"component\": \"\",\n \"version\": \"\",\n \"configuration\": null\n },\n \"api\": {},\n \"components\": {},\n \"logging\": {\n \"apiLogging\": {\n \"enabled\": false,\n \"obfuscateURLs\": false,\n \"omitHealthChecks\": false\n }\n }\n }\n }\n]",
|
||||
errString: "",
|
||||
errorExpected: false,
|
||||
k8sConfig: []v1alpha1.Configuration{
|
||||
|
|
@ -192,7 +192,7 @@ func TestConfigurations(t *testing.T) {
|
|||
name: "Json two configs",
|
||||
configName: "",
|
||||
outputFormat: "json",
|
||||
expectedOutput: "[\n {\n \"name\": \"appConfig1\",\n \"namespace\": \"default\",\n \"spec\": {\n \"appHttpPipeline\": {\n \"handlers\": null\n },\n \"httpPipeline\": {\n \"handlers\": null\n },\n \"tracing\": {\n \"samplingRate\": \"\",\n \"stdout\": false,\n \"zipkin\": {\n \"endpointAddress\": \"\"\n },\n \"otel\": {\n \"protocol\": \"\",\n \"endpointAddress\": \"\",\n \"isSecure\": false\n }\n },\n \"metric\": {\n \"enabled\": false\n },\n \"mtls\": {\n \"enabled\": false,\n \"workloadCertTTL\": \"\",\n \"allowedClockSkew\": \"\"\n },\n \"secrets\": {\n \"scopes\": null\n },\n \"accessControl\": {\n \"defaultAction\": \"\",\n \"trustDomain\": \"\",\n \"policies\": null\n },\n \"nameResolution\": {\n \"component\": \"\",\n \"version\": \"\",\n \"configuration\": null\n },\n \"api\": {},\n \"components\": {}\n }\n },\n {\n \"name\": \"appConfig2\",\n \"namespace\": \"default\",\n \"spec\": {\n \"appHttpPipeline\": {\n \"handlers\": null\n },\n \"httpPipeline\": {\n \"handlers\": null\n },\n \"tracing\": {\n \"samplingRate\": \"\",\n \"stdout\": false,\n \"zipkin\": {\n \"endpointAddress\": \"\"\n },\n \"otel\": {\n \"protocol\": \"\",\n \"endpointAddress\": \"\",\n \"isSecure\": false\n }\n },\n \"metric\": {\n \"enabled\": false\n },\n \"mtls\": {\n \"enabled\": false,\n \"workloadCertTTL\": \"\",\n \"allowedClockSkew\": \"\"\n },\n \"secrets\": {\n \"scopes\": null\n },\n \"accessControl\": {\n \"defaultAction\": \"\",\n \"trustDomain\": \"\",\n \"policies\": null\n },\n \"nameResolution\": {\n \"component\": \"\",\n \"version\": \"\",\n \"configuration\": null\n },\n \"api\": {},\n \"components\": {}\n }\n }\n]",
|
||||
expectedOutput: "[\n {\n \"name\": \"appConfig1\",\n \"namespace\": \"default\",\n \"spec\": {\n \"appHttpPipeline\": {\n \"handlers\": null\n },\n \"httpPipeline\": {\n \"handlers\": null\n },\n \"tracing\": {\n \"samplingRate\": \"\",\n \"stdout\": false,\n \"zipkin\": {\n \"endpointAddress\": \"\"\n },\n \"otel\": {\n \"protocol\": \"\",\n \"endpointAddress\": \"\",\n \"isSecure\": false\n }\n },\n \"metric\": {\n \"enabled\": false,\n \"rules\": null\n },\n \"metrics\": {\n \"enabled\": false,\n \"rules\": null\n },\n \"mtls\": {\n \"enabled\": false,\n \"workloadCertTTL\": \"\",\n \"allowedClockSkew\": \"\"\n },\n \"secrets\": {\n \"scopes\": null\n },\n \"accessControl\": {\n \"defaultAction\": \"\",\n \"trustDomain\": \"\",\n \"policies\": null\n },\n \"nameResolution\": {\n \"component\": \"\",\n \"version\": \"\",\n \"configuration\": null\n },\n \"api\": {},\n \"components\": {},\n \"logging\": {\n \"apiLogging\": {\n \"enabled\": false,\n \"obfuscateURLs\": false,\n \"omitHealthChecks\": false\n }\n }\n }\n },\n {\n \"name\": \"appConfig2\",\n \"namespace\": \"default\",\n \"spec\": {\n \"appHttpPipeline\": {\n \"handlers\": null\n },\n \"httpPipeline\": {\n \"handlers\": null\n },\n \"tracing\": {\n \"samplingRate\": \"\",\n \"stdout\": false,\n \"zipkin\": {\n \"endpointAddress\": \"\"\n },\n \"otel\": {\n \"protocol\": \"\",\n \"endpointAddress\": \"\",\n \"isSecure\": false\n }\n },\n \"metric\": {\n \"enabled\": false,\n \"rules\": null\n },\n \"metrics\": {\n \"enabled\": false,\n \"rules\": null\n },\n \"mtls\": {\n \"enabled\": false,\n \"workloadCertTTL\": \"\",\n \"allowedClockSkew\": \"\"\n },\n \"secrets\": {\n \"scopes\": null\n },\n \"accessControl\": {\n \"defaultAction\": \"\",\n \"trustDomain\": \"\",\n \"policies\": null\n },\n \"nameResolution\": {\n \"component\": \"\",\n \"version\": \"\",\n \"configuration\": null\n },\n \"api\": {},\n \"components\": {},\n \"logging\": {\n \"apiLogging\": {\n \"enabled\": false,\n \"obfuscateURLs\": false,\n \"omitHealthChecks\": false\n }\n }\n }\n }\n]",
|
||||
errString: "",
|
||||
errorExpected: false,
|
||||
k8sConfig: []v1alpha1.Configuration{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Copyright 2023 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubernetes
|
||||
|
||||
import "github.com/Masterminds/semver/v3"
|
||||
|
||||
const daprHelmChartWithDashboard = "<= 1.10.x"
|
||||
|
||||
// IsDashboardIncluded returns true if dashboard is included in Helm chart version for Dapr.
|
||||
func IsDashboardIncluded(runtimeVersion string) (bool, error) {
|
||||
c, err := semver.NewConstraint(daprHelmChartWithDashboard)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
v, err := semver.NewVersion(runtimeVersion)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return c.Check(v), nil
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2023 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDashboardChart(t *testing.T) {
|
||||
testCases := []struct {
|
||||
runtimeVersion string
|
||||
expectDashboard bool
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
runtimeVersion: "1.9.6",
|
||||
expectDashboard: true,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
runtimeVersion: "1.10.7",
|
||||
expectDashboard: true,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
runtimeVersion: "1.10.99",
|
||||
expectDashboard: true,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
runtimeVersion: "1.11.0",
|
||||
expectDashboard: false,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
runtimeVersion: "1.11.0",
|
||||
expectDashboard: false,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
runtimeVersion: "1.12.7",
|
||||
expectDashboard: false,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
runtimeVersion: "Bad Version",
|
||||
expectDashboard: false,
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run("Validating version "+tc.runtimeVersion, func(t *testing.T) {
|
||||
hasDashboard, err := IsDashboardIncluded(tc.runtimeVersion)
|
||||
if tc.expectError {
|
||||
assert.Error(t, err, "expected an error")
|
||||
} else {
|
||||
assert.NoError(t, err, "expected an error")
|
||||
}
|
||||
|
||||
assert.Equal(t, tc.expectDashboard, hasDashboard, "dashboard expectation")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -36,34 +36,62 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
daprReleaseName = "dapr"
|
||||
daprHelmRepo = "https://dapr.github.io/helm-charts"
|
||||
latestVersion = "latest"
|
||||
daprReleaseName = "dapr"
|
||||
dashboardReleaseName = "dapr-dashboard"
|
||||
daprHelmRepo = "https://dapr.github.io/helm-charts"
|
||||
latestVersion = "latest"
|
||||
)
|
||||
|
||||
type InitConfiguration struct {
|
||||
Version string
|
||||
Namespace string
|
||||
EnableMTLS bool
|
||||
EnableHA bool
|
||||
Args []string
|
||||
Wait bool
|
||||
Timeout uint
|
||||
ImageRegistryURI string
|
||||
ImageVariant string
|
||||
Version string
|
||||
DashboardVersion string
|
||||
Namespace string
|
||||
EnableMTLS bool
|
||||
EnableHA bool
|
||||
Args []string
|
||||
Wait bool
|
||||
Timeout uint
|
||||
ImageRegistryURI string
|
||||
ImageVariant string
|
||||
RootCertificateFilePath string
|
||||
IssuerCertificateFilePath string
|
||||
IssuerPrivateKeyFilePath string
|
||||
}
|
||||
|
||||
// Init deploys the Dapr operator using the supplied runtime version.
|
||||
func Init(config InitConfiguration) error {
|
||||
msg := "Deploying the Dapr control plane to your cluster..."
|
||||
|
||||
stopSpinning := print.Spinner(os.Stdout, msg)
|
||||
defer stopSpinning(print.Failure)
|
||||
if err := install(config); err != nil {
|
||||
err := installWithConsole(daprReleaseName, config.Version, "Dapr control plane", config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stopSpinning(print.Success)
|
||||
for _, dashboardClusterRole := range []string{"dashboard-reader", "dapr-dashboard"} {
|
||||
// Detect Dapr Dashboard using a cluster-level resource (not dependent on namespace).
|
||||
_, err = utils.RunCmdAndWait("kubectl", "describe", "clusterrole", dashboardClusterRole)
|
||||
if err == nil {
|
||||
// No need to install Dashboard since it is already present.
|
||||
// Charts for versions < 1.11 contain Dashboard already.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
err = installWithConsole(dashboardReleaseName, config.DashboardVersion, "Dapr dashboard", config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func installWithConsole(releaseName string, releaseVersion string, prettyName string, config InitConfiguration) error {
|
||||
installSpinning := print.Spinner(os.Stdout, "Deploying the "+prettyName+" with "+releaseVersion+" version to your cluster...")
|
||||
defer installSpinning(print.Failure)
|
||||
|
||||
err := install(releaseName, releaseVersion, config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
installSpinning(print.Success)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -93,16 +121,23 @@ func helmConfig(namespace string) (*helm.Configuration, error) {
|
|||
return &ac, err
|
||||
}
|
||||
|
||||
func getVersion(version string) (string, error) {
|
||||
func getVersion(releaseName string, version string) (string, error) {
|
||||
actualVersion := version
|
||||
if version == latestVersion {
|
||||
var err error
|
||||
version, err = cli_ver.GetDaprVersion()
|
||||
if releaseName == daprReleaseName {
|
||||
actualVersion, err = cli_ver.GetDaprVersion()
|
||||
} else if releaseName == dashboardReleaseName {
|
||||
actualVersion, err = cli_ver.GetDashboardVersion()
|
||||
} else {
|
||||
return "", fmt.Errorf("cannot get latest version for unknown chart: %s", releaseName)
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot get the latest release version: %w", err)
|
||||
}
|
||||
version = strings.TrimPrefix(version, "v")
|
||||
actualVersion = strings.TrimPrefix(actualVersion, "v")
|
||||
}
|
||||
return version, nil
|
||||
return actualVersion, nil
|
||||
}
|
||||
|
||||
func createTempDir() (string, error) {
|
||||
|
|
@ -121,7 +156,7 @@ func locateChartFile(dirPath string) (string, error) {
|
|||
return filepath.Join(dirPath, files[0].Name()), nil
|
||||
}
|
||||
|
||||
func daprChart(version string, config *helm.Configuration) (*chart.Chart, error) {
|
||||
func daprChart(version string, releaseName string, config *helm.Configuration) (*chart.Chart, error) {
|
||||
pull := helm.NewPullWithOpts(helm.WithConfig(config))
|
||||
pull.RepoURL = utils.GetEnv("DAPR_HELM_REPO_URL", daprHelmRepo)
|
||||
pull.Username = utils.GetEnv("DAPR_HELM_REPO_USERNAME", "")
|
||||
|
|
@ -129,7 +164,7 @@ func daprChart(version string, config *helm.Configuration) (*chart.Chart, error)
|
|||
|
||||
pull.Settings = &cli.EnvSettings{}
|
||||
|
||||
if version != latestVersion {
|
||||
if version != latestVersion && (releaseName == daprReleaseName || releaseName == dashboardReleaseName) {
|
||||
pull.Version = chartVersion(version)
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +176,7 @@ func daprChart(version string, config *helm.Configuration) (*chart.Chart, error)
|
|||
|
||||
pull.DestDir = dir
|
||||
|
||||
_, err = pull.Run(daprReleaseName)
|
||||
_, err = pull.Run(releaseName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -159,17 +194,32 @@ func chartValues(config InitConfiguration, version string) (map[string]interface
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
globalVals := []string{
|
||||
helmVals := []string{
|
||||
fmt.Sprintf("global.ha.enabled=%t", config.EnableHA),
|
||||
fmt.Sprintf("global.mtls.enabled=%t", config.EnableMTLS),
|
||||
fmt.Sprintf("global.tag=%s", utils.GetVariantVersion(version, config.ImageVariant)),
|
||||
}
|
||||
if len(config.ImageRegistryURI) != 0 {
|
||||
globalVals = append(globalVals, fmt.Sprintf("global.registry=%s", config.ImageRegistryURI))
|
||||
helmVals = append(helmVals, fmt.Sprintf("global.registry=%s", config.ImageRegistryURI))
|
||||
}
|
||||
globalVals = append(globalVals, config.Args...)
|
||||
helmVals = append(helmVals, config.Args...)
|
||||
|
||||
for _, v := range globalVals {
|
||||
if config.RootCertificateFilePath != "" && config.IssuerCertificateFilePath != "" && config.IssuerPrivateKeyFilePath != "" {
|
||||
rootCertBytes, issuerCertBytes, issuerKeyBytes, err := parseCertificateFiles(
|
||||
config.RootCertificateFilePath,
|
||||
config.IssuerCertificateFilePath,
|
||||
config.IssuerPrivateKeyFilePath,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
helmVals = append(helmVals, fmt.Sprintf("dapr_sentry.tls.root.certPEM=%s", string(rootCertBytes)),
|
||||
fmt.Sprintf("dapr_sentry.tls.issuer.certPEM=%s", string(issuerCertBytes)),
|
||||
fmt.Sprintf("dapr_sentry.tls.issuer.keyPEM=%s", string(issuerKeyBytes)),
|
||||
)
|
||||
}
|
||||
|
||||
for _, v := range helmVals {
|
||||
if err := strvals.ParseInto(v, chartVals); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -177,7 +227,7 @@ func chartValues(config InitConfiguration, version string) (map[string]interface
|
|||
return chartVals, nil
|
||||
}
|
||||
|
||||
func install(config InitConfiguration) error {
|
||||
func install(releaseName string, releaseVersion string, config InitConfiguration) error {
|
||||
err := createNamespace(config.Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -188,23 +238,25 @@ func install(config InitConfiguration) error {
|
|||
return err
|
||||
}
|
||||
|
||||
daprChart, err := daprChart(config.Version, helmConf)
|
||||
daprChart, err := daprChart(releaseVersion, releaseName, helmConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
version, err := getVersion(config.Version)
|
||||
version, err := getVersion(releaseName, releaseVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = applyCRDs(fmt.Sprintf("v%s", version))
|
||||
if err != nil {
|
||||
return err
|
||||
if releaseName == daprReleaseName {
|
||||
err = applyCRDs(fmt.Sprintf("v%s", version))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
installClient := helm.NewInstall(helmConf)
|
||||
installClient.ReleaseName = daprReleaseName
|
||||
installClient.ReleaseName = releaseName
|
||||
installClient.Namespace = config.Namespace
|
||||
installClient.Wait = config.Wait
|
||||
installClient.Timeout = time.Duration(config.Timeout) * time.Second
|
||||
|
|
@ -217,15 +269,16 @@ func install(config InitConfiguration) error {
|
|||
if _, err = installClient.Run(daprChart, values); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func debugLogf(format string, v ...interface{}) {
|
||||
}
|
||||
|
||||
func confirmExist(cfg *helm.Configuration) (bool, error) {
|
||||
func confirmExist(cfg *helm.Configuration, releaseName string) (bool, error) {
|
||||
client := helm.NewGet(cfg)
|
||||
release, err := client.Run(daprReleaseName)
|
||||
release, err := client.Run(releaseName)
|
||||
|
||||
if release == nil {
|
||||
return false, nil
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ func renewCertificate(rootCert, issuerCert, issuerKey []byte, timeout uint, imag
|
|||
return err
|
||||
}
|
||||
|
||||
daprChart, err := daprChart(daprVersion, helmConf)
|
||||
daprChart, err := daprChart(daprVersion, "dapr", helmConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func Uninstall(namespace string, uninstallAll bool, timeout uint) error {
|
|||
return err
|
||||
}
|
||||
|
||||
exists, err := confirmExist(config)
|
||||
exists, err := confirmExist(config, daprReleaseName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -42,6 +42,12 @@ func Uninstall(namespace string, uninstallAll bool, timeout uint) error {
|
|||
|
||||
uninstallClient := helm.NewUninstall(config)
|
||||
uninstallClient.Timeout = time.Duration(timeout) * time.Second
|
||||
|
||||
// Uninstall Dashboard as a best effort.
|
||||
// Chart versions < 1.11 for Dapr will delete dashboard as part of the main chart.
|
||||
// Deleting Dashboard here is for versions >= 1.11.
|
||||
uninstallClient.Run(dashboardReleaseName)
|
||||
|
||||
_, err = uninstallClient.Run(daprReleaseName)
|
||||
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"time"
|
||||
|
||||
helm "helm.sh/helm/v3/pkg/action"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
"k8s.io/helm/pkg/strvals"
|
||||
|
||||
"github.com/hashicorp/go-version"
|
||||
|
|
@ -35,6 +36,7 @@ var crds = []string{
|
|||
"configuration",
|
||||
"subscription",
|
||||
"resiliency",
|
||||
"httpendpoints",
|
||||
}
|
||||
|
||||
var crdsFullResources = []string{
|
||||
|
|
@ -42,10 +44,12 @@ var crdsFullResources = []string{
|
|||
"configurations.dapr.io",
|
||||
"subscriptions.dapr.io",
|
||||
"resiliencies.dapr.io",
|
||||
"httpendpoints.dapr.io",
|
||||
}
|
||||
|
||||
type UpgradeConfig struct {
|
||||
RuntimeVersion string
|
||||
DashboardVersion string
|
||||
Args []string
|
||||
Timeout uint
|
||||
ImageRegistryURI string
|
||||
|
|
@ -61,16 +65,56 @@ func Upgrade(conf UpgradeConfig) error {
|
|||
daprVersion := GetDaprVersion(status)
|
||||
print.InfoStatusEvent(os.Stdout, "Dapr control plane version %s detected in namespace %s", daprVersion, status[0].Namespace)
|
||||
|
||||
hasDashboardInDaprChart, err := IsDashboardIncluded(daprVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
helmConf, err := helmConfig(status[0].Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
daprChart, err := daprChart(conf.RuntimeVersion, helmConf)
|
||||
controlPlaneChart, err := daprChart(conf.RuntimeVersion, "dapr", helmConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
willHaveDashboardInDaprChart, err := IsDashboardIncluded(conf.RuntimeVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Before we do anything, checks if installing dashboard is allowed.
|
||||
if willHaveDashboardInDaprChart && conf.DashboardVersion != "" {
|
||||
// We cannot install Dashboard separately if Dapr's chart has it already.
|
||||
return fmt.Errorf("cannot install Dashboard because Dapr version %s already contains it - installation aborted", conf.RuntimeVersion)
|
||||
}
|
||||
|
||||
dashboardExists, err := confirmExist(helmConf, dashboardReleaseName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !hasDashboardInDaprChart && willHaveDashboardInDaprChart && dashboardExists {
|
||||
print.InfoStatusEvent(os.Stdout, "Dashboard being uninstalled prior to Dapr control plane upgrade...")
|
||||
uninstallClient := helm.NewUninstall(helmConf)
|
||||
uninstallClient.Timeout = time.Duration(conf.Timeout) * time.Second
|
||||
|
||||
_, err = uninstallClient.Run(dashboardReleaseName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var dashboardChart *chart.Chart
|
||||
if conf.DashboardVersion != "" {
|
||||
dashboardChart, err = daprChart(conf.DashboardVersion, dashboardReleaseName, helmConf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
upgradeClient := helm.NewUpgrade(helmConf)
|
||||
upgradeClient.ResetValues = true
|
||||
upgradeClient.Namespace = status[0].Namespace
|
||||
|
|
@ -121,9 +165,29 @@ func Upgrade(conf UpgradeConfig) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if _, err = upgradeClient.Run(chart, daprChart, vals); err != nil {
|
||||
if _, err = upgradeClient.Run(chart, controlPlaneChart, vals); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if dashboardChart != nil {
|
||||
if dashboardExists {
|
||||
if _, err = upgradeClient.Run(dashboardReleaseName, dashboardChart, vals); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// We need to install Dashboard since it does not exist yet.
|
||||
err = install(dashboardReleaseName, conf.DashboardVersion, InitConfiguration{
|
||||
DashboardVersion: conf.DashboardVersion,
|
||||
Namespace: upgradeClient.Namespace,
|
||||
Wait: upgradeClient.Wait,
|
||||
Timeout: conf.Timeout,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
|
@ -204,3 +206,37 @@ func logJSON(w io.Writer, status, message string) {
|
|||
|
||||
fmt.Fprintf(w, "%s\n", string(jsonBytes))
|
||||
}
|
||||
|
||||
type CustomLogWriter struct {
|
||||
W io.Writer
|
||||
}
|
||||
|
||||
func (c CustomLogWriter) Write(p []byte) (int, error) {
|
||||
write := func(w io.Writer, isStdIO bool) (int, error) {
|
||||
b := p
|
||||
if !isStdIO {
|
||||
// below regex is used to replace the color codes from the logs collected in the log file.
|
||||
reg := regexp.MustCompile("\x1b\\[[\\d;]+m")
|
||||
b = reg.ReplaceAll(b, []byte(""))
|
||||
}
|
||||
n, err := w.Write(b)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
if n != len(b) {
|
||||
return n, io.ErrShortWrite
|
||||
}
|
||||
return len(b), nil
|
||||
}
|
||||
wIface := reflect.ValueOf(c.W).Interface()
|
||||
switch wType := wIface.(type) {
|
||||
case *os.File:
|
||||
if wType == os.Stderr || wType == os.Stdout {
|
||||
return write(c.W, true)
|
||||
} else {
|
||||
return write(c.W, false)
|
||||
}
|
||||
default:
|
||||
return write(c.W, false)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ func assertArgumentContains(t *testing.T, key string, expectedValue string, args
|
|||
}
|
||||
|
||||
func setupRun(t *testing.T) {
|
||||
myDaprPath, err := standalone.GetDaprPath("")
|
||||
myDaprPath, err := standalone.GetDaprRuntimePath("")
|
||||
assert.NoError(t, err)
|
||||
|
||||
componentsDir := standalone.GetDaprComponentsPath(myDaprPath)
|
||||
|
|
@ -87,7 +87,7 @@ func setupRun(t *testing.T) {
|
|||
}
|
||||
|
||||
func tearDownRun(t *testing.T) {
|
||||
myDaprPath, err := standalone.GetDaprPath("")
|
||||
myDaprPath, err := standalone.GetDaprRuntimePath("")
|
||||
assert.NoError(t, err)
|
||||
|
||||
componentsDir := standalone.GetDaprComponentsPath(myDaprPath)
|
||||
|
|
@ -106,7 +106,7 @@ func assertCommonArgs(t *testing.T, basicConfig *standalone.RunConfig, output *R
|
|||
assert.Equal(t, 8000, output.DaprHTTPPort)
|
||||
assert.Equal(t, 50001, output.DaprGRPCPort)
|
||||
|
||||
daprPath, err := standalone.GetDaprPath("")
|
||||
daprPath, err := standalone.GetDaprRuntimePath("")
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Contains(t, output.DaprCMD.Args[0], "daprd")
|
||||
|
|
@ -168,7 +168,7 @@ func TestRun(t *testing.T) {
|
|||
// Setup the tearDown routine to run in the end.
|
||||
defer tearDownRun(t)
|
||||
|
||||
myDaprPath, err := standalone.GetDaprPath("")
|
||||
myDaprPath, err := standalone.GetDaprRuntimePath("")
|
||||
assert.NoError(t, err)
|
||||
|
||||
componentsDir := standalone.GetDaprComponentsPath(myDaprPath)
|
||||
|
|
@ -186,15 +186,16 @@ func TestRun(t *testing.T) {
|
|||
APIListenAddresses: "127.0.0.1",
|
||||
}
|
||||
basicConfig := &standalone.RunConfig{
|
||||
AppID: "MyID",
|
||||
AppPort: 3000,
|
||||
HTTPPort: 8000,
|
||||
GRPCPort: 50001,
|
||||
Command: []string{"MyCommand", "--my-arg"},
|
||||
ProfilePort: 9090,
|
||||
MetricsPort: 9001,
|
||||
InternalGRPCPort: 5050,
|
||||
SharedRunConfig: *sharedRunConfig,
|
||||
AppID: "MyID",
|
||||
AppPort: 3000,
|
||||
HTTPPort: 8000,
|
||||
GRPCPort: 50001,
|
||||
Command: []string{"MyCommand", "--my-arg"},
|
||||
ProfilePort: 9090,
|
||||
MetricsPort: 9001,
|
||||
InternalGRPCPort: 5050,
|
||||
AppChannelAddress: "localhost",
|
||||
SharedRunConfig: *sharedRunConfig,
|
||||
}
|
||||
|
||||
t.Run("run happy http", func(t *testing.T) {
|
||||
|
|
@ -204,6 +205,7 @@ func TestRun(t *testing.T) {
|
|||
assertCommonArgs(t, basicConfig, output)
|
||||
assert.Equal(t, "MyCommand", output.AppCMD.Args[0])
|
||||
assert.Equal(t, "--my-arg", output.AppCMD.Args[1])
|
||||
assertArgumentEqual(t, "app-channel-address", "localhost", output.DaprCMD.Args)
|
||||
assertAppEnv(t, basicConfig, output)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"os"
|
||||
path_filepath "path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -28,19 +29,21 @@ const (
|
|||
defaultComponentsDirName = "components"
|
||||
)
|
||||
|
||||
// GetDaprPath returns the dapr installation path.
|
||||
// GetDaprRuntimePath returns the dapr runtime installation path.
|
||||
// daprRuntimePath is based on the --runtime-path command line flag.
|
||||
// The order of precedence is:
|
||||
// 1. From --dapr-path command line flag
|
||||
// 2. From DAPR_PATH environment variable
|
||||
// 3. $HOME/.dapr
|
||||
func GetDaprPath(inputInstallPath string) (string, error) {
|
||||
if inputInstallPath != "" {
|
||||
return inputInstallPath, nil
|
||||
// 1. From --runtime-path command line flag appended with `.dapr`
|
||||
// 2. From DAPR_RUNTIME_PATH environment variable appended with `.dapr`
|
||||
// 3. default $HOME/.dapr
|
||||
func GetDaprRuntimePath(daprRuntimePath string) (string, error) {
|
||||
runtimePath := strings.TrimSpace(daprRuntimePath)
|
||||
if runtimePath != "" {
|
||||
return path_filepath.Join(runtimePath, DefaultDaprDirName), nil
|
||||
}
|
||||
|
||||
envDaprDir := os.Getenv("DAPR_PATH")
|
||||
if envDaprDir != "" {
|
||||
return envDaprDir, nil
|
||||
envRuntimePath := strings.TrimSpace(os.Getenv("DAPR_RUNTIME_PATH"))
|
||||
if envRuntimePath != "" {
|
||||
return path_filepath.Join(envRuntimePath, DefaultDaprDirName), nil
|
||||
}
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
|
|
@ -64,7 +67,7 @@ func binaryFilePathWithDir(binaryDir string, binaryFilePrefix string) string {
|
|||
}
|
||||
|
||||
func lookupBinaryFilePath(inputInstallPath string, binaryFilePrefix string) (string, error) {
|
||||
daprPath, err := GetDaprPath(inputInstallPath)
|
||||
daprPath, err := GetDaprRuntimePath(inputInstallPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright 2023 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package standalone
|
||||
|
||||
import (
|
||||
"os"
|
||||
path_filepath "path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestGetDaprPath(t *testing.T) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "error getting home dir")
|
||||
|
||||
t.Run("without flag value or env var", func(t *testing.T) {
|
||||
p, err := GetDaprRuntimePath("")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, p, path_filepath.Join(homeDir, DefaultDaprDirName), "path should be $HOME/.dapr")
|
||||
})
|
||||
|
||||
t.Run("check trim spaces", func(t *testing.T) {
|
||||
p, err := GetDaprRuntimePath(" ")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, path_filepath.Join(homeDir, DefaultDaprDirName), p, "path should be $HOME/.dapr")
|
||||
|
||||
t.Setenv("DAPR_RUNTIME_PATH", " ")
|
||||
p, err = GetDaprRuntimePath("")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, path_filepath.Join(homeDir, DefaultDaprDirName), p, "path should be $HOME/.dapr")
|
||||
})
|
||||
|
||||
t.Run("with flag value", func(t *testing.T) {
|
||||
input := path_filepath.Join("path", "to", "dapr")
|
||||
p, err := GetDaprRuntimePath(input)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, path_filepath.Join(input, ".dapr"), p, "path should be /path/to/dapr/.dapr")
|
||||
})
|
||||
|
||||
t.Run("with env var", func(t *testing.T) {
|
||||
input := path_filepath.Join("path", "to", "dapr")
|
||||
t.Setenv("DAPR_RUNTIME_PATH", input)
|
||||
p, err := GetDaprRuntimePath("")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, path_filepath.Join(input, ".dapr"), p, "path should be /path/to/dapr/.dapr")
|
||||
})
|
||||
|
||||
t.Run("with flag value and env var", func(t *testing.T) {
|
||||
input := path_filepath.Join("path", "to", "dapr")
|
||||
input2 := path_filepath.Join("path", "to", "dapr2")
|
||||
t.Setenv("DAPR_RUNTIME_PATH", input2)
|
||||
p, err := GetDaprRuntimePath(input)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, path_filepath.Join(input, ".dapr"), p, "path should be /path/to/dapr/.dapr")
|
||||
})
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import (
|
|||
)
|
||||
|
||||
func TestDashboardRun(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("build Cmd", func(t *testing.T) {
|
||||
cmd, err := NewDashboardCmd("", 9090)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,11 @@ import (
|
|||
ps "github.com/mitchellh/go-ps"
|
||||
process "github.com/shirou/gopsutil/process"
|
||||
|
||||
"github.com/dapr/dapr/pkg/runtime"
|
||||
|
||||
"github.com/dapr/cli/pkg/age"
|
||||
"github.com/dapr/cli/pkg/metadata"
|
||||
"github.com/dapr/cli/utils"
|
||||
"github.com/dapr/dapr/pkg/runtime"
|
||||
)
|
||||
|
||||
// ListOutput represents the application ID, application port and creation time.
|
||||
|
|
@ -39,9 +40,13 @@ type ListOutput struct {
|
|||
Created string `csv:"CREATED" json:"created" yaml:"created"`
|
||||
DaprdPID int `csv:"DAPRD PID" json:"daprdPid" yaml:"daprdPid"`
|
||||
CliPID int `csv:"CLI PID" json:"cliPid" yaml:"cliPid"`
|
||||
AppPID int `csv:"APP PID" json:"appPid" yaml:"appPid"`
|
||||
MaxRequestBodySize int `csv:"-" json:"maxRequestBodySize" yaml:"maxRequestBodySize"` // Additional field, not displayed in table.
|
||||
HTTPReadBufferSize int `csv:"-" json:"httpReadBufferSize" yaml:"httpReadBufferSize"` // Additional field, not displayed in table.
|
||||
RunTemplatePath string `csv:"RUN_TEMPLATE_PATH" json:"runTemplatePath" yaml:"runTemplatePath"`
|
||||
AppLogPath string `csv:"APP_LOG_PATH" json:"appLogPath" yaml:"appLogPath"`
|
||||
DaprDLogPath string `csv:"DAPRD_LOG_PATH" json:"daprdLogPath" yaml:"daprdLogPath"`
|
||||
RunTemplateName string `json:"runTemplateName" yaml:"runTemplateName"` // specifically omitted in csv output.
|
||||
}
|
||||
|
||||
func (d *daprProcess) List() ([]ListOutput, error) {
|
||||
|
|
@ -76,9 +81,16 @@ func List() ([]ListOutput, error) {
|
|||
continue
|
||||
}
|
||||
|
||||
// Parse command line arguments, example format for cmdLine `daprd --flag1 value1 --enable-flag2 --flag3 value3`.
|
||||
argumentsMap := make(map[string]string)
|
||||
for i := 1; i < len(cmdLineItems)-1; i += 2 {
|
||||
argumentsMap[cmdLineItems[i]] = cmdLineItems[i+1]
|
||||
for i := 1; i < len(cmdLineItems)-1; {
|
||||
if !strings.HasPrefix(cmdLineItems[i+1], "--") {
|
||||
argumentsMap[cmdLineItems[i]] = cmdLineItems[i+1]
|
||||
i += 2
|
||||
} else {
|
||||
argumentsMap[cmdLineItems[i]] = ""
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
httpPort := getIntArg(argumentsMap, "--dapr-http-port", runtime.DefaultDaprHTTPPort)
|
||||
|
|
@ -99,14 +111,27 @@ func List() ([]ListOutput, error) {
|
|||
|
||||
appID := argumentsMap["--app-id"]
|
||||
appCmd := ""
|
||||
appPIDString := ""
|
||||
cliPIDString := ""
|
||||
runTemplatePath := ""
|
||||
appLogPath := ""
|
||||
daprdLogPath := ""
|
||||
runTemplateName := ""
|
||||
socket := argumentsMap["--unix-domain-socket"]
|
||||
appMetadata, err := metadata.Get(httpPort, appID, socket)
|
||||
if err == nil {
|
||||
appCmd = appMetadata.Extended["appCommand"]
|
||||
appPIDString = appMetadata.Extended["appPID"]
|
||||
cliPIDString = appMetadata.Extended["cliPID"]
|
||||
runTemplatePath = appMetadata.Extended["runTemplatePath"]
|
||||
runTemplateName = appMetadata.Extended["runTemplateName"]
|
||||
appLogPath = appMetadata.Extended["appLogPath"]
|
||||
daprdLogPath = appMetadata.Extended["daprdLogPath"]
|
||||
}
|
||||
|
||||
appPID, err := strconv.Atoi(appPIDString)
|
||||
if err != nil {
|
||||
appPID = 0
|
||||
}
|
||||
|
||||
// Parse functions return an error on bad input.
|
||||
|
|
@ -130,6 +155,7 @@ func List() ([]ListOutput, error) {
|
|||
DaprdPID: daprPID,
|
||||
CliPID: cliPID,
|
||||
AppID: appID,
|
||||
AppPID: appPID,
|
||||
HTTPPort: httpPort,
|
||||
GRPCPort: grpcPort,
|
||||
AppPort: appPort,
|
||||
|
|
@ -138,6 +164,9 @@ func List() ([]ListOutput, error) {
|
|||
MaxRequestBodySize: maxRequestBodySize,
|
||||
HTTPReadBufferSize: httpReadBufferSize,
|
||||
RunTemplatePath: runTemplatePath,
|
||||
RunTemplateName: runTemplateName,
|
||||
AppLogPath: appLogPath,
|
||||
DaprDLogPath: daprdLogPath,
|
||||
}
|
||||
|
||||
// filter only dashboard instance.
|
||||
|
|
|
|||
|
|
@ -29,50 +29,61 @@ import (
|
|||
|
||||
"github.com/dapr/cli/pkg/print"
|
||||
"github.com/dapr/dapr/pkg/components"
|
||||
modes "github.com/dapr/dapr/pkg/config/modes"
|
||||
)
|
||||
|
||||
type LogDestType string
|
||||
|
||||
const (
|
||||
Console LogDestType = "console"
|
||||
File LogDestType = "file"
|
||||
FileAndConsole LogDestType = "fileAndConsole"
|
||||
DefaultDaprdLogDest = File
|
||||
DefaultAppLogDest = FileAndConsole
|
||||
|
||||
sentryDefaultAddress = "localhost:50001"
|
||||
defaultStructTagKey = "default"
|
||||
)
|
||||
|
||||
// RunConfig represents the application configuration parameters.
|
||||
type RunConfig struct {
|
||||
SharedRunConfig `yaml:",inline"`
|
||||
AppID string `env:"APP_ID" arg:"app-id" yaml:"appID"`
|
||||
AppPort int `env:"APP_PORT" arg:"app-port" yaml:"appPort" default:"-1"`
|
||||
HTTPPort int `env:"DAPR_HTTP_PORT" arg:"dapr-http-port" yaml:"daprHTTPPort" default:"-1"`
|
||||
GRPCPort int `env:"DAPR_GRPC_PORT" arg:"dapr-grpc-port" yaml:"daprGRPCPort" default:"-1"`
|
||||
ProfilePort int `arg:"profile-port" yaml:"profilePort" default:"-1"`
|
||||
Command []string `yaml:"command"`
|
||||
MetricsPort int `env:"DAPR_METRICS_PORT" arg:"metrics-port" yaml:"metricsPort" default:"-1"`
|
||||
UnixDomainSocket string `arg:"unix-domain-socket" yaml:"unixDomainSocket"`
|
||||
InternalGRPCPort int `arg:"dapr-internal-grpc-port" yaml:"daprInternalGRPCPort" default:"-1"`
|
||||
SharedRunConfig `yaml:",inline"`
|
||||
AppID string `env:"APP_ID" arg:"app-id" yaml:"appID"`
|
||||
AppChannelAddress string `env:"APP_CHANNEL_ADDRESS" arg:"app-channel-address" ifneq:"127.0.0.1" yaml:"appChannelAddress"`
|
||||
AppPort int `env:"APP_PORT" arg:"app-port" yaml:"appPort" default:"-1"`
|
||||
HTTPPort int `env:"DAPR_HTTP_PORT" arg:"dapr-http-port" yaml:"daprHTTPPort" default:"-1"`
|
||||
GRPCPort int `env:"DAPR_GRPC_PORT" arg:"dapr-grpc-port" yaml:"daprGRPCPort" default:"-1"`
|
||||
ProfilePort int `arg:"profile-port" yaml:"profilePort" default:"-1"`
|
||||
Command []string `yaml:"command"`
|
||||
MetricsPort int `env:"DAPR_METRICS_PORT" arg:"metrics-port" yaml:"metricsPort" default:"-1"`
|
||||
UnixDomainSocket string `arg:"unix-domain-socket" yaml:"unixDomainSocket"`
|
||||
InternalGRPCPort int `arg:"dapr-internal-grpc-port" yaml:"daprInternalGRPCPort" default:"-1"`
|
||||
}
|
||||
|
||||
// SharedRunConfig represents the application configuration parameters, which can be shared across many apps.
|
||||
type SharedRunConfig struct {
|
||||
ConfigFile string `arg:"config" yaml:"configFilePath"`
|
||||
AppProtocol string `arg:"app-protocol" yaml:"appProtocol" default:"http"`
|
||||
APIListenAddresses string `arg:"dapr-listen-addresses" yaml:"apiListenAddresses"`
|
||||
EnableProfiling bool `arg:"enable-profiling" yaml:"enableProfiling"`
|
||||
LogLevel string `arg:"log-level" yaml:"logLevel"`
|
||||
MaxConcurrency int `arg:"app-max-concurrency" yaml:"appMaxConcurrency" default:"-1"`
|
||||
PlacementHostAddr string `arg:"placement-host-address" yaml:"placementHostAddress"`
|
||||
ComponentsPath string `arg:"components-path"`
|
||||
ResourcesPath string `arg:"resources-path" yaml:"resourcesPath"`
|
||||
AppSSL bool `arg:"app-ssl" yaml:"appSSL"`
|
||||
MaxRequestBodySize int `arg:"dapr-http-max-request-size" yaml:"daprHTTPMaxRequestSize" default:"-1"`
|
||||
HTTPReadBufferSize int `arg:"dapr-http-read-buffer-size" yaml:"daprHTTPReadBufferSize" default:"-1"`
|
||||
EnableAppHealth bool `arg:"enable-app-health-check" yaml:"enableAppHealthCheck"`
|
||||
AppHealthPath string `arg:"app-health-check-path" yaml:"appHealthCheckPath"`
|
||||
AppHealthInterval int `arg:"app-health-probe-interval" ifneq:"0" yaml:"appHealthProbeInterval"`
|
||||
AppHealthTimeout int `arg:"app-health-probe-timeout" ifneq:"0" yaml:"appHealthProbeTimeout"`
|
||||
AppHealthThreshold int `arg:"app-health-threshold" ifneq:"0" yaml:"appHealthThreshold"`
|
||||
EnableAPILogging bool `arg:"enable-api-logging" yaml:"enableApiLogging"`
|
||||
DaprdInstallPath string `yaml:"daprPath"`
|
||||
Env map[string]string `yaml:"env"`
|
||||
ConfigFile string `arg:"config" yaml:"configFilePath"`
|
||||
AppProtocol string `arg:"app-protocol" yaml:"appProtocol" default:"http"`
|
||||
APIListenAddresses string `arg:"dapr-listen-addresses" yaml:"apiListenAddresses"`
|
||||
EnableProfiling bool `arg:"enable-profiling" yaml:"enableProfiling"`
|
||||
LogLevel string `arg:"log-level" yaml:"logLevel"`
|
||||
MaxConcurrency int `arg:"app-max-concurrency" yaml:"appMaxConcurrency" default:"-1"`
|
||||
PlacementHostAddr string `arg:"placement-host-address" yaml:"placementHostAddress"`
|
||||
ComponentsPath string `arg:"components-path"` // Deprecated in run template file: use ResourcesPaths instead.
|
||||
ResourcesPath string `yaml:"resourcesPath"` // Deprecated in run template file: use ResourcesPaths instead.
|
||||
ResourcesPaths []string `arg:"resources-path" yaml:"resourcesPaths"`
|
||||
AppSSL bool `arg:"app-ssl" yaml:"appSSL"`
|
||||
MaxRequestBodySize int `arg:"dapr-http-max-request-size" yaml:"daprHTTPMaxRequestSize" default:"-1"`
|
||||
HTTPReadBufferSize int `arg:"dapr-http-read-buffer-size" yaml:"daprHTTPReadBufferSize" default:"-1"`
|
||||
EnableAppHealth bool `arg:"enable-app-health-check" yaml:"enableAppHealthCheck"`
|
||||
AppHealthPath string `arg:"app-health-check-path" yaml:"appHealthCheckPath"`
|
||||
AppHealthInterval int `arg:"app-health-probe-interval" ifneq:"0" yaml:"appHealthProbeInterval"`
|
||||
AppHealthTimeout int `arg:"app-health-probe-timeout" ifneq:"0" yaml:"appHealthProbeTimeout"`
|
||||
AppHealthThreshold int `arg:"app-health-threshold" ifneq:"0" yaml:"appHealthThreshold"`
|
||||
EnableAPILogging bool `arg:"enable-api-logging" yaml:"enableApiLogging"`
|
||||
DaprdInstallPath string `yaml:"runtimePath"`
|
||||
Env map[string]string `yaml:"env"`
|
||||
DaprdLogDestination LogDestType `yaml:"daprdLogDestination"`
|
||||
AppLogDestination LogDestType `yaml:"appLogDestination"`
|
||||
}
|
||||
|
||||
func (meta *DaprMeta) newAppID() string {
|
||||
|
|
@ -84,17 +95,18 @@ func (meta *DaprMeta) newAppID() string {
|
|||
}
|
||||
}
|
||||
|
||||
func (config *RunConfig) validateResourcesPath() error {
|
||||
dirPath := config.ResourcesPath
|
||||
if dirPath == "" {
|
||||
dirPath = config.ComponentsPath
|
||||
func (config *RunConfig) validateResourcesPaths() error {
|
||||
dirPath := config.ResourcesPaths
|
||||
if len(dirPath) == 0 {
|
||||
dirPath = []string{config.ComponentsPath}
|
||||
}
|
||||
_, err := os.Stat(dirPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error validating resources path %q : %w", dirPath, err)
|
||||
for _, path := range dirPath {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
return fmt.Errorf("error validating resources path %q : %w", dirPath, err)
|
||||
}
|
||||
}
|
||||
componentsLoader := components.NewStandaloneComponents(modes.StandaloneConfig{ComponentsPath: dirPath})
|
||||
_, err = componentsLoader.LoadComponents()
|
||||
componentsLoader := components.NewLocalComponents(dirPath...)
|
||||
_, err := componentsLoader.LoadComponents()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error validating components in resources path %q : %w", dirPath, err)
|
||||
}
|
||||
|
|
@ -143,12 +155,12 @@ func (config *RunConfig) Validate() error {
|
|||
config.AppID = meta.newAppID()
|
||||
}
|
||||
|
||||
err = config.validateResourcesPath()
|
||||
err = config.validateResourcesPaths()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if config.ResourcesPath != "" {
|
||||
if len(config.ResourcesPaths) > 0 {
|
||||
config.ComponentsPath = ""
|
||||
}
|
||||
|
||||
|
|
@ -287,11 +299,17 @@ func getArgsFromSchema(schema reflect.Value, args []string) []string {
|
|||
|
||||
ifneq, hasIfneq := typeField.Tag.Lookup("ifneq")
|
||||
|
||||
switch valueField.(type) {
|
||||
switch vType := valueField.(type) {
|
||||
case bool:
|
||||
if valueField == true {
|
||||
args = append(args, key)
|
||||
}
|
||||
case []string:
|
||||
if len(vType) > 0 {
|
||||
for _, val := range vType {
|
||||
args = append(args, key, val)
|
||||
}
|
||||
}
|
||||
default:
|
||||
value := fmt.Sprintf("%v", reflect.ValueOf(valueField))
|
||||
if len(value) != 0 && (!hasIfneq || value != ifneq) {
|
||||
|
|
@ -331,6 +349,8 @@ func (config *RunConfig) setDefaultFromSchemaRecursive(schema reflect.Value) {
|
|||
|
||||
func (config *RunConfig) getEnv() []string {
|
||||
env := []string{}
|
||||
|
||||
// Handle values from config that have an "env" tag.
|
||||
schema := reflect.ValueOf(*config)
|
||||
for i := 0; i < schema.NumField(); i++ {
|
||||
valueField := schema.Field(i).Interface()
|
||||
|
|
@ -347,12 +367,48 @@ func (config *RunConfig) getEnv() []string {
|
|||
value := fmt.Sprintf("%v", reflect.ValueOf(valueField))
|
||||
env = append(env, fmt.Sprintf("%s=%v", key, value))
|
||||
}
|
||||
|
||||
// Handle APP_PROTOCOL separately since that requires some additional processing.
|
||||
appProtocol := config.getAppProtocol()
|
||||
if appProtocol != "" {
|
||||
env = append(env, "APP_PROTOCOL="+appProtocol)
|
||||
}
|
||||
|
||||
// Add user-defined env vars.
|
||||
for k, v := range config.Env {
|
||||
env = append(env, fmt.Sprintf("%s=%v", k, v))
|
||||
}
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
func (config *RunConfig) getAppProtocol() string {
|
||||
appProtocol := strings.ToLower(config.AppProtocol)
|
||||
|
||||
switch appProtocol {
|
||||
case string("grpcs"), string("https"), string("h2c"):
|
||||
return appProtocol
|
||||
case string("http"):
|
||||
// For backwards compatibility, when protocol is HTTP and --app-ssl is set, use "https".
|
||||
if config.AppSSL {
|
||||
return "https"
|
||||
} else {
|
||||
return "http"
|
||||
}
|
||||
case string("grpc"):
|
||||
// For backwards compatibility, when protocol is GRPC and --app-ssl is set, use "grpcs".
|
||||
if config.AppSSL {
|
||||
return string("grpcs")
|
||||
} else {
|
||||
return string("grpc")
|
||||
}
|
||||
case "":
|
||||
return string("http")
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func GetDaprCommand(config *RunConfig) (*exec.Cmd, error) {
|
||||
daprCMD, err := lookupBinaryFilePath(config.DaprdInstallPath, "daprd")
|
||||
if err != nil {
|
||||
|
|
@ -405,3 +461,15 @@ func GetAppCommand(config *RunConfig) *exec.Cmd {
|
|||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (l LogDestType) String() string {
|
||||
return string(l)
|
||||
}
|
||||
|
||||
func (l LogDestType) IsValid() error {
|
||||
switch l {
|
||||
case Console, File, FileAndConsole:
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid log destination type: %s", l)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
Copyright 2021 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package standalone
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetEnv(t *testing.T) {
|
||||
config := &RunConfig{
|
||||
SharedRunConfig: SharedRunConfig{},
|
||||
AppID: "testapp",
|
||||
AppChannelAddress: "localhost",
|
||||
AppPort: 1234,
|
||||
HTTPPort: 2345,
|
||||
GRPCPort: 3456,
|
||||
ProfilePort: 4567, // This is not included in env.
|
||||
MetricsPort: 5678,
|
||||
}
|
||||
|
||||
t.Run("no explicit app-protocol", func(t *testing.T) {
|
||||
expect := []string{
|
||||
"APP_ID=testapp",
|
||||
"APP_CHANNEL_ADDRESS=localhost",
|
||||
"APP_PORT=1234",
|
||||
"APP_PROTOCOL=http",
|
||||
"DAPR_HTTP_PORT=2345",
|
||||
"DAPR_GRPC_PORT=3456",
|
||||
"DAPR_METRICS_PORT=5678",
|
||||
}
|
||||
|
||||
got := config.getEnv()
|
||||
|
||||
sort.Strings(expect)
|
||||
sort.Strings(got)
|
||||
|
||||
assert.Equal(t, expect, got)
|
||||
})
|
||||
|
||||
t.Run("app-protocol grpcs", func(t *testing.T) {
|
||||
config.AppProtocol = "grpcs"
|
||||
config.AppSSL = false
|
||||
|
||||
expect := []string{
|
||||
"APP_ID=testapp",
|
||||
"APP_CHANNEL_ADDRESS=localhost",
|
||||
"APP_PORT=1234",
|
||||
"APP_PROTOCOL=grpcs",
|
||||
"DAPR_HTTP_PORT=2345",
|
||||
"DAPR_GRPC_PORT=3456",
|
||||
"DAPR_METRICS_PORT=5678",
|
||||
}
|
||||
|
||||
got := config.getEnv()
|
||||
|
||||
sort.Strings(expect)
|
||||
sort.Strings(got)
|
||||
|
||||
assert.Equal(t, expect, got)
|
||||
})
|
||||
|
||||
t.Run("app-protocol http", func(t *testing.T) {
|
||||
config.AppProtocol = "http"
|
||||
config.AppSSL = false
|
||||
|
||||
expect := []string{
|
||||
"APP_ID=testapp",
|
||||
"APP_CHANNEL_ADDRESS=localhost",
|
||||
"APP_PORT=1234",
|
||||
"APP_PROTOCOL=http",
|
||||
"DAPR_HTTP_PORT=2345",
|
||||
"DAPR_GRPC_PORT=3456",
|
||||
"DAPR_METRICS_PORT=5678",
|
||||
}
|
||||
|
||||
got := config.getEnv()
|
||||
|
||||
sort.Strings(expect)
|
||||
sort.Strings(got)
|
||||
|
||||
assert.Equal(t, expect, got)
|
||||
})
|
||||
|
||||
t.Run("app-protocol http with app-ssl", func(t *testing.T) {
|
||||
config.AppProtocol = "http"
|
||||
config.AppSSL = true
|
||||
|
||||
expect := []string{
|
||||
"APP_ID=testapp",
|
||||
"APP_CHANNEL_ADDRESS=localhost",
|
||||
"APP_PORT=1234",
|
||||
"APP_PROTOCOL=https",
|
||||
"DAPR_HTTP_PORT=2345",
|
||||
"DAPR_GRPC_PORT=3456",
|
||||
"DAPR_METRICS_PORT=5678",
|
||||
}
|
||||
|
||||
got := config.getEnv()
|
||||
|
||||
sort.Strings(expect)
|
||||
sort.Strings(got)
|
||||
|
||||
assert.Equal(t, expect, got)
|
||||
})
|
||||
|
||||
t.Run("app-protocol grpc with app-ssl", func(t *testing.T) {
|
||||
config.AppProtocol = "grpc"
|
||||
config.AppSSL = true
|
||||
|
||||
expect := []string{
|
||||
"APP_ID=testapp",
|
||||
"APP_CHANNEL_ADDRESS=localhost",
|
||||
"APP_PORT=1234",
|
||||
"APP_PROTOCOL=grpcs",
|
||||
"DAPR_HTTP_PORT=2345",
|
||||
"DAPR_GRPC_PORT=3456",
|
||||
"DAPR_METRICS_PORT=5678",
|
||||
}
|
||||
|
||||
got := config.getEnv()
|
||||
|
||||
sort.Strings(expect)
|
||||
sort.Strings(got)
|
||||
|
||||
assert.Equal(t, expect, got)
|
||||
})
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/dapr/cli/pkg/standalone"
|
||||
)
|
||||
|
|
@ -34,6 +35,7 @@ type RunFileConfig struct {
|
|||
Common Common `yaml:"common"`
|
||||
Apps []App `yaml:"apps"`
|
||||
Version int `yaml:"version"`
|
||||
Name string `yaml:"name,omitempty"`
|
||||
}
|
||||
|
||||
// App represents the configuration options for the apps in the run file.
|
||||
|
|
@ -60,8 +62,13 @@ func (a *App) GetLogsDir() string {
|
|||
// CreateAppLogFile creates the log file, sets internal file handle
|
||||
// and returns error if any.
|
||||
func (a *App) CreateAppLogFile() error {
|
||||
logsPath := a.GetLogsDir()
|
||||
f, err := os.Create(filepath.Join(logsPath, getAppLogFileName()))
|
||||
var err error
|
||||
var f *os.File
|
||||
if a.AppLogDestination == standalone.Console {
|
||||
f = os.Stdout
|
||||
} else {
|
||||
f, err = a.createLogFile(appLogFileNamePrefix)
|
||||
}
|
||||
if err == nil {
|
||||
a.AppLogWriteCloser = f
|
||||
a.AppLogFileName = f.Name()
|
||||
|
|
@ -72,8 +79,13 @@ func (a *App) CreateAppLogFile() error {
|
|||
// CreateDaprdLogFile creates the log file, sets internal file handle
|
||||
// and returns error if any.
|
||||
func (a *App) CreateDaprdLogFile() error {
|
||||
logsPath := a.GetLogsDir()
|
||||
f, err := os.Create(filepath.Join(logsPath, getDaprdLogFileName()))
|
||||
var err error
|
||||
var f *os.File
|
||||
if a.DaprdLogDestination == standalone.Console {
|
||||
f = os.Stdout
|
||||
} else {
|
||||
f, err = a.createLogFile(daprdLogFileNamePrefix)
|
||||
}
|
||||
if err == nil {
|
||||
a.DaprdLogWriteCloser = f
|
||||
a.DaprdLogFileName = f.Name()
|
||||
|
|
@ -81,12 +93,13 @@ func (a *App) CreateDaprdLogFile() error {
|
|||
return err
|
||||
}
|
||||
|
||||
func getAppLogFileName() string {
|
||||
return appLogFileNamePrefix + logFileExtension
|
||||
}
|
||||
|
||||
func getDaprdLogFileName() string {
|
||||
return daprdLogFileNamePrefix + logFileExtension
|
||||
// createLogFile creates the log file and returns the file handle and error if any.
|
||||
// It also adds the app ID as a prefix and the current timestamp to the file name as a suffix.
|
||||
func (a *App) createLogFile(logType string) (*os.File, error) {
|
||||
logsPath := a.GetLogsDir()
|
||||
fpath := filepath.Join(logsPath, a.AppID+"_"+logType+"_"+time.Now().Format("20060102150405")+logFileExtension)
|
||||
f, err := os.Create(fpath)
|
||||
return f, err
|
||||
}
|
||||
|
||||
func (a *App) CloseAppLogFile() error {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,20 @@ func (a *RunFileConfig) validateRunConfig(runFilePath string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Resolves common's section ResourcesPaths to absolute paths and validates them.
|
||||
for i := range a.Common.ResourcesPaths {
|
||||
err := a.resolvePathToAbsAndValidate(baseDir, &a.Common.ResourcesPaths[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Merge common's section ResourcesPaths and ResourcePath. ResourcesPaths will be single source of truth for resources to be loaded.
|
||||
if len(strings.TrimSpace(a.Common.ResourcesPath)) > 0 {
|
||||
a.Common.ResourcesPaths = append(a.Common.ResourcesPaths, a.Common.ResourcesPath)
|
||||
}
|
||||
|
||||
for i := 0; i < len(a.Apps); i++ {
|
||||
if a.Apps[i].AppDirPath == "" {
|
||||
return errors.New("required field 'appDirPath' not found in the provided app config file")
|
||||
|
|
@ -70,6 +84,19 @@ func (a *RunFileConfig) validateRunConfig(runFilePath string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Resolves ResourcesPaths to absolute paths and validates them.
|
||||
for j := range a.Apps[i].ResourcesPaths {
|
||||
err := a.resolvePathToAbsAndValidate(a.Apps[i].AppDirPath, &a.Apps[i].ResourcesPaths[j])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Merge app's section ResourcesPaths and ResourcePath. ResourcesPaths will be single source of truth for resources to be loaded.
|
||||
if len(strings.TrimSpace(a.Apps[i].ResourcesPath)) > 0 {
|
||||
a.Apps[i].ResourcesPaths = append(a.Apps[i].ResourcesPaths, a.Apps[i].ResourcesPath)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -91,11 +118,13 @@ func (a *RunFileConfig) GetApps(runFilePath string) ([]App, error) {
|
|||
}
|
||||
a.mergeCommonAndAppsSharedRunConfig()
|
||||
a.mergeCommonAndAppsEnv()
|
||||
// Resolve app ids if not provided in the run file.
|
||||
err = a.setAppIDIfEmpty()
|
||||
|
||||
// Set and validates default fields in the run file.
|
||||
err = a.setDefaultFields()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a.Apps, nil
|
||||
}
|
||||
|
||||
|
|
@ -121,17 +150,44 @@ func (a *RunFileConfig) mergeCommonAndAppsSharedRunConfig() {
|
|||
}
|
||||
}
|
||||
|
||||
// setDefaultFields sets the default values for the fields that are not provided in the run file.
|
||||
func (a *RunFileConfig) setDefaultFields() error {
|
||||
for i := range a.Apps {
|
||||
if err := a.setAppIDIfEmpty(&a.Apps[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := a.setAndValidateLogDestination(&a.Apps[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set AppID to the directory name of appDirPath.
|
||||
// appDirPath is a mandatory field in the run file and at this point it is already validated and resolved to its absolute path.
|
||||
func (a *RunFileConfig) setAppIDIfEmpty() error {
|
||||
for i := range a.Apps {
|
||||
if a.Apps[i].AppID == "" {
|
||||
basePath, err := a.getBasePathFromAbsPath(a.Apps[i].AppDirPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Apps[i].AppID = basePath
|
||||
func (a *RunFileConfig) setAppIDIfEmpty(app *App) error {
|
||||
if app.AppID == "" {
|
||||
basePath, err := a.getBasePathFromAbsPath(app.AppDirPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error in setting the app id: %w", err)
|
||||
}
|
||||
app.AppID = basePath
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setAndValidateLogDestination sets the default log destination if not provided in the run file.
|
||||
// It also validates the log destination if provided.
|
||||
func (a *RunFileConfig) setAndValidateLogDestination(app *App) error {
|
||||
if app.DaprdLogDestination == "" {
|
||||
app.DaprdLogDestination = standalone.DefaultDaprdLogDest
|
||||
} else if err := app.DaprdLogDestination.IsValid(); err != nil {
|
||||
return err
|
||||
}
|
||||
if app.AppLogDestination == "" {
|
||||
app.AppLogDestination = standalone.DefaultAppLogDest
|
||||
} else if err := app.AppLogDestination.IsValid(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -151,6 +207,10 @@ func (a *RunFileConfig) resolvePathToAbsAndValidate(baseDir string, paths ...*st
|
|||
if *path == "" {
|
||||
continue
|
||||
}
|
||||
*path, err = utils.ResolveHomeDir(*path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
absPath := utils.GetAbsPath(baseDir, *path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -198,22 +258,22 @@ func (a *RunFileConfig) mergeCommonAndAppsEnv() {
|
|||
}
|
||||
|
||||
// resolveResourcesFilePath resolves the resources path for the app.
|
||||
// Precedence order for resourcesPath -> apps[i].resourcesPath > apps[i].appDirPath/.dapr/resources > common.resourcesPath > dapr default resources path.
|
||||
// Precedence order for resourcesPaths -> apps[i].resourcesPaths > apps[i].appDirPath/.dapr/resources > common.resourcesPaths > dapr default resources path.
|
||||
func (a *RunFileConfig) resolveResourcesFilePath(app *App) error {
|
||||
if app.ResourcesPath != "" {
|
||||
if len(app.ResourcesPaths) > 0 {
|
||||
return nil
|
||||
}
|
||||
localResourcesDir := filepath.Join(app.AppDirPath, standalone.DefaultDaprDirName, standalone.DefaultResourcesDirName)
|
||||
if err := utils.ValidateFilePath(localResourcesDir); err == nil {
|
||||
app.ResourcesPath = localResourcesDir
|
||||
} else if len(strings.TrimSpace(a.Common.ResourcesPath)) > 0 {
|
||||
app.ResourcesPath = a.Common.ResourcesPath
|
||||
app.ResourcesPaths = []string{localResourcesDir}
|
||||
} else if len(a.Common.ResourcesPaths) > 0 {
|
||||
app.ResourcesPaths = append(app.ResourcesPaths, a.Common.ResourcesPaths...)
|
||||
} else {
|
||||
daprDirPath, err := standalone.GetDaprPath(app.DaprdInstallPath)
|
||||
daprDirPath, err := standalone.GetDaprRuntimePath(app.DaprdInstallPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting dapr install path: %w", err)
|
||||
}
|
||||
app.ResourcesPath = standalone.GetDaprComponentsPath(daprDirPath)
|
||||
app.ResourcesPaths = []string{standalone.GetDaprComponentsPath(daprDirPath)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -230,7 +290,7 @@ func (a *RunFileConfig) resolveConfigFilePath(app *App) error {
|
|||
} else if len(strings.TrimSpace(a.Common.ConfigFile)) > 0 {
|
||||
app.ConfigFile = a.Common.ConfigFile
|
||||
} else {
|
||||
daprDirPath, err := standalone.GetDaprPath(app.DaprdInstallPath)
|
||||
daprDirPath, err := standalone.GetDaprRuntimePath(app.DaprdInstallPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting dapr install path: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ package runfileconfig
|
|||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/cli/pkg/standalone"
|
||||
|
|
@ -29,9 +30,12 @@ var (
|
|||
invalidRunFilePath2 = filepath.Join("..", "testdata", "runfileconfig", "test_run_config_empty_app_dir.yaml")
|
||||
runFileForPrecedenceRule = filepath.Join("..", "testdata", "runfileconfig", "test_run_config_precedence_rule.yaml")
|
||||
runFileForPrecedenceRuleDaprDir = filepath.Join("..", "testdata", "runfileconfig", "test_run_config_precedence_rule_dapr_dir.yaml")
|
||||
runFileForLogDestination = filepath.Join("..", "testdata", "runfileconfig", "test_run_config_log_destination.yaml")
|
||||
runFileForMultiResourcePaths = filepath.Join("..", "testdata", "runfileconfig", "test_run_config_multiple_resources_paths.yaml")
|
||||
)
|
||||
|
||||
func TestRunConfigFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("test parse valid run template", func(t *testing.T) {
|
||||
appsRunConfig := RunFileConfig{}
|
||||
err := appsRunConfig.parseAppsConfig(validRunFilePath)
|
||||
|
|
@ -69,17 +73,17 @@ func TestRunConfigFile(t *testing.T) {
|
|||
assert.Equal(t, "/tmp/test-socket", apps[1].UnixDomainSocket)
|
||||
|
||||
// test resourcesPath and configPath after precedence order logic.
|
||||
assert.Equal(t, filepath.Join(apps[0].AppDirPath, "resources"), apps[0].ResourcesPath)
|
||||
assert.Equal(t, filepath.Join(apps[1].AppDirPath, ".dapr", "resources"), apps[1].ResourcesPath)
|
||||
assert.Equal(t, filepath.Join(apps[0].AppDirPath, "resources"), apps[0].ResourcesPaths[0])
|
||||
assert.Equal(t, filepath.Join(apps[1].AppDirPath, ".dapr", "resources"), apps[1].ResourcesPaths[0])
|
||||
|
||||
assert.Equal(t, filepath.Join(apps[0].AppDirPath, "config.yaml"), apps[0].ConfigFile)
|
||||
assert.Equal(t, filepath.Join(apps[1].AppDirPath, ".dapr", "config.yaml"), apps[1].ConfigFile)
|
||||
|
||||
// temporarily set apps[0].ResourcesPath to empty string to test it is getting picked from common section.
|
||||
apps[0].ResourcesPath = ""
|
||||
apps[0].ResourcesPaths = []string{}
|
||||
config.resolveResourcesAndConfigFilePaths()
|
||||
assert.Equal(t, config.Common.ResourcesPath, apps[0].ResourcesPath)
|
||||
assert.Equal(t, filepath.Join(apps[1].AppDirPath, ".dapr", "resources"), apps[1].ResourcesPath)
|
||||
assert.Equal(t, config.Common.ResourcesPaths[0], apps[0].ResourcesPaths[0])
|
||||
assert.Equal(t, filepath.Join(apps[1].AppDirPath, ".dapr", "resources"), apps[1].ResourcesPaths[0])
|
||||
|
||||
// test merged envs from common and app sections.
|
||||
assert.Equal(t, 2, len(apps[0].Env))
|
||||
|
|
@ -102,45 +106,39 @@ func TestRunConfigFile(t *testing.T) {
|
|||
err = config.validateRunConfig(runFileForPrecedenceRule)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// test precedence logic for resourcesPath and configPath.
|
||||
err = config.resolveResourcesAndConfigFilePaths()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
disableCommonSection bool
|
||||
expectedResourcesPath string
|
||||
expectedConfigFilePath string
|
||||
appIndex int
|
||||
}{
|
||||
{
|
||||
name: "resourcesPath and configPath are set in app section",
|
||||
disableCommonSection: false,
|
||||
name: "resourcesPaths and configPath are set in app section",
|
||||
expectedResourcesPath: filepath.Join(config.Apps[0].AppDirPath, "resources"),
|
||||
expectedConfigFilePath: filepath.Join(config.Apps[0].AppDirPath, "config.yaml"),
|
||||
appIndex: 0,
|
||||
},
|
||||
{
|
||||
name: "resourcesPath and configPath present in .dapr directory under appDirPath",
|
||||
disableCommonSection: false,
|
||||
name: "resourcesPaths and configPath present in .dapr directory under appDirPath",
|
||||
expectedResourcesPath: filepath.Join(config.Apps[1].AppDirPath, ".dapr", "resources"),
|
||||
expectedConfigFilePath: filepath.Join(config.Apps[1].AppDirPath, ".dapr", "config.yaml"),
|
||||
appIndex: 1,
|
||||
},
|
||||
{
|
||||
name: "resourcesPath and configPath are resolved from common's section",
|
||||
disableCommonSection: false,
|
||||
expectedResourcesPath: config.Common.ResourcesPath, // from common section.
|
||||
expectedConfigFilePath: config.Common.ConfigFile, // from common section.
|
||||
name: "resourcesPaths and configPath are resolved from common's section",
|
||||
expectedResourcesPath: config.Common.ResourcesPaths[0], // from common section.
|
||||
expectedConfigFilePath: config.Common.ConfigFile, // from common section.
|
||||
appIndex: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.disableCommonSection {
|
||||
config.Common.ResourcesPath = ""
|
||||
config.Common.ConfigFile = ""
|
||||
}
|
||||
// test precedence logic for resourcesPath and configPath.
|
||||
config.resolveResourcesAndConfigFilePaths()
|
||||
assert.Equal(t, tc.expectedResourcesPath, config.Apps[tc.appIndex].ResourcesPath)
|
||||
assert.Equal(t, tc.expectedResourcesPath, config.Apps[tc.appIndex].ResourcesPaths[0])
|
||||
assert.Equal(t, tc.expectedConfigFilePath, config.Apps[tc.appIndex].ConfigFile)
|
||||
})
|
||||
}
|
||||
|
|
@ -161,6 +159,11 @@ func TestRunConfigFile(t *testing.T) {
|
|||
app2Data := getResourcesAndConfigFilePaths(t, config.Apps[1].DaprdInstallPath)
|
||||
app2ResourcesPath := app2Data[0]
|
||||
app2ConfigFilePath := app2Data[1]
|
||||
|
||||
// test precedence logic for resourcesPath and configPath.
|
||||
err = config.resolveResourcesAndConfigFilePaths()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
expectedResourcesPath string
|
||||
|
|
@ -168,13 +171,13 @@ func TestRunConfigFile(t *testing.T) {
|
|||
appIndex int
|
||||
}{
|
||||
{
|
||||
name: "resourcesPath and configPath are resolved from dapr's default installation path.",
|
||||
name: "resourcesPaths and configPath are resolved from dapr's default installation path.",
|
||||
expectedResourcesPath: app1ResourcesPath,
|
||||
expectedConfigFilePath: app1ConfigFilePath,
|
||||
appIndex: 0,
|
||||
},
|
||||
{
|
||||
name: "resourcesPath and configPath are resolved from dapr's custom installation path.",
|
||||
name: "resourcesPaths and configPath are resolved from dapr's custom installation path.",
|
||||
expectedResourcesPath: app2ResourcesPath,
|
||||
expectedConfigFilePath: app2ConfigFilePath,
|
||||
appIndex: 1,
|
||||
|
|
@ -183,9 +186,7 @@ func TestRunConfigFile(t *testing.T) {
|
|||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
// test precedence logic for resourcesPath and configPath.
|
||||
config.resolveResourcesAndConfigFilePaths()
|
||||
assert.Equal(t, tc.expectedResourcesPath, config.Apps[tc.appIndex].ResourcesPath)
|
||||
assert.Equal(t, tc.expectedResourcesPath, config.Apps[tc.appIndex].ResourcesPaths[0])
|
||||
assert.Equal(t, tc.expectedConfigFilePath, config.Apps[tc.appIndex].ConfigFile)
|
||||
})
|
||||
}
|
||||
|
|
@ -223,6 +224,89 @@ func TestRunConfigFile(t *testing.T) {
|
|||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("test log destination for daprd and apps", func(t *testing.T) {
|
||||
config := RunFileConfig{}
|
||||
apps, err := config.GetApps(runFileForLogDestination)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 6, len(apps))
|
||||
|
||||
assert.Equal(t, "file", apps[0].DaprdLogDestination.String())
|
||||
assert.Equal(t, "fileAndConsole", apps[0].AppLogDestination.String())
|
||||
|
||||
assert.Equal(t, "fileAndConsole", apps[1].DaprdLogDestination.String())
|
||||
assert.Equal(t, "fileAndConsole", apps[1].AppLogDestination.String())
|
||||
|
||||
assert.Equal(t, "file", apps[2].DaprdLogDestination.String())
|
||||
assert.Equal(t, "file", apps[2].AppLogDestination.String())
|
||||
|
||||
assert.Equal(t, "console", apps[3].DaprdLogDestination.String())
|
||||
assert.Equal(t, "console", apps[3].AppLogDestination.String())
|
||||
|
||||
assert.Equal(t, "console", apps[4].DaprdLogDestination.String())
|
||||
assert.Equal(t, "file", apps[4].AppLogDestination.String())
|
||||
|
||||
assert.Equal(t, "file", apps[5].DaprdLogDestination.String())
|
||||
assert.Equal(t, "console", apps[5].AppLogDestination.String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestMultiResourcePathsResolution(t *testing.T) {
|
||||
config := RunFileConfig{}
|
||||
|
||||
err := config.parseAppsConfig(runFileForMultiResourcePaths)
|
||||
assert.NoError(t, err)
|
||||
err = config.validateRunConfig(runFileForMultiResourcePaths)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// test precedence logic for multiple resources paths.
|
||||
err = config.resolveResourcesAndConfigFilePaths()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
expectedNoOfResources int
|
||||
expectedResourcesPathsContains string
|
||||
appIndex int
|
||||
}{
|
||||
{
|
||||
name: "resourcesPaths should have 2 paths",
|
||||
expectedNoOfResources: 2,
|
||||
expectedResourcesPathsContains: filepath.Join(config.Apps[0].AppDirPath, "resources"),
|
||||
appIndex: 0,
|
||||
},
|
||||
{
|
||||
name: "resourcesPaths should have 2 paths",
|
||||
expectedNoOfResources: 2,
|
||||
expectedResourcesPathsContains: filepath.Join("backend", ".dapr", "resources"),
|
||||
appIndex: 0,
|
||||
},
|
||||
{
|
||||
name: "resourcesPaths should have 2 path from common section",
|
||||
expectedNoOfResources: 2,
|
||||
expectedResourcesPathsContains: filepath.Join("app", "resources"),
|
||||
appIndex: 1,
|
||||
},
|
||||
{
|
||||
name: "resourcesPaths should have 1 path from .dapr's folder",
|
||||
expectedNoOfResources: 1,
|
||||
expectedResourcesPathsContains: filepath.Join("backend", ".dapr", "resources"),
|
||||
appIndex: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.Equal(t, tc.expectedNoOfResources, len(config.Apps[tc.appIndex].ResourcesPaths))
|
||||
var rsrcFound bool
|
||||
for _, resourcePath := range config.Apps[tc.appIndex].ResourcesPaths {
|
||||
if rsrcFound = strings.Contains(resourcePath, tc.expectedResourcesPathsContains); rsrcFound {
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, rsrcFound)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBasePathFromAbsPath(t *testing.T) {
|
||||
|
|
@ -266,7 +350,7 @@ func TestGetBasePathFromAbsPath(t *testing.T) {
|
|||
func getResourcesAndConfigFilePaths(t *testing.T, daprInstallPath string) []string {
|
||||
t.Helper()
|
||||
result := make([]string, 2)
|
||||
daprDirPath, err := standalone.GetDaprPath(daprInstallPath)
|
||||
daprDirPath, err := standalone.GetDaprRuntimePath(daprInstallPath)
|
||||
assert.NoError(t, err)
|
||||
result[0] = standalone.GetDaprComponentsPath(daprDirPath)
|
||||
result[1] = standalone.GetDaprConfigPath(daprDirPath)
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ const (
|
|||
DaprZipkinContainerName = "dapr_zipkin"
|
||||
|
||||
errInstallTemplate = "please run `dapr uninstall` first before running `dapr init`"
|
||||
|
||||
healthPort = 58080
|
||||
metricPort = 59090
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -162,9 +165,9 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
|
|||
setAirGapInit(fromDir)
|
||||
if !slimMode {
|
||||
// If --slim installation is not requested, check if docker is installed.
|
||||
conatinerRuntimeAvailable := utils.IsDockerInstalled() || utils.IsPodmanInstalled()
|
||||
if !conatinerRuntimeAvailable {
|
||||
return errors.New("could not connect to Docker. Docker may not be installed or running")
|
||||
containerRuntimeAvailable := utils.IsContainerRuntimeInstalled(containerRuntime)
|
||||
if !containerRuntimeAvailable {
|
||||
return fmt.Errorf("could not connect to %s. %s may not be installed or running", containerRuntime, containerRuntime)
|
||||
}
|
||||
|
||||
// Initialize default registry only if any of --slim or --image-registry or --from-dir are not given.
|
||||
|
|
@ -215,7 +218,7 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
|
|||
|
||||
print.InfoStatusEvent(os.Stdout, "Installing runtime version %s", runtimeVersion)
|
||||
|
||||
installDir, err := GetDaprPath(daprInstallPath)
|
||||
installDir, err := GetDaprRuntimePath(daprInstallPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -520,7 +523,10 @@ func runPlacementService(wg *sync.WaitGroup, errorChan chan<- error, info initIn
|
|||
}
|
||||
|
||||
args = append(args,
|
||||
"-p", fmt.Sprintf("%v:50005", osPort))
|
||||
"-p", fmt.Sprintf("%v:50005", osPort),
|
||||
"-p", fmt.Sprintf("%v:8080", healthPort),
|
||||
"-p", fmt.Sprintf("%v:9090", metricPort),
|
||||
)
|
||||
}
|
||||
|
||||
args = append(args, image)
|
||||
|
|
@ -905,6 +911,7 @@ func moveFileToPath(filepath string, installLocation string) (string, error) {
|
|||
p := os.Getenv("PATH")
|
||||
|
||||
if !strings.Contains(strings.ToLower(p), strings.ToLower(destDir)) {
|
||||
destDir = utils.SanitizeDir(destDir)
|
||||
pathCmd := "[System.Environment]::SetEnvironmentVariable('Path',[System.Environment]::GetEnvironmentVariable('Path','user') + '" + fmt.Sprintf(";%s", destDir) + "', 'user')"
|
||||
_, err := utils.RunCmdAndWait("powershell", pathCmd)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/dapr/cli/utils"
|
||||
)
|
||||
|
||||
func TestStandaloneConfig(t *testing.T) {
|
||||
|
|
@ -96,7 +98,9 @@ func TestResolveImageWithGHCR(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got, err := resolveImageURI(test.args)
|
||||
assert.Equal(t, test.expectErr, err != nil)
|
||||
assert.Equal(t, test.expect, got)
|
||||
|
|
@ -140,7 +144,9 @@ func TestResolveImageWithDockerHub(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got, err := resolveImageURI(test.args)
|
||||
assert.Equal(t, test.expectErr, err != nil)
|
||||
assert.Equal(t, test.expect, got)
|
||||
|
|
@ -184,7 +190,9 @@ func TestResolveImageWithPrivateRegistry(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
got, err := resolveImageURI(test.args)
|
||||
assert.Equal(t, test.expectErr, err != nil)
|
||||
assert.Equal(t, test.expect, got)
|
||||
|
|
@ -304,3 +312,25 @@ func TestIsAirGapInit(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitLogActualContainerRuntimeName(t *testing.T) {
|
||||
tests := []struct {
|
||||
containerRuntime string
|
||||
testName string
|
||||
}{
|
||||
{"podman", "Init should log podman as container runtime"},
|
||||
{"docker", "Init should log docker as container runtime"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.testName, func(t *testing.T) {
|
||||
containerRuntimeAvailable := utils.IsContainerRuntimeInstalled(test.containerRuntime)
|
||||
if containerRuntimeAvailable {
|
||||
t.Skip("Skipping test as container runtime is available")
|
||||
}
|
||||
|
||||
err := Init(latestVersion, latestVersion, "", false, "", "", test.containerRuntime, "", "")
|
||||
assert.NotNil(t, err)
|
||||
assert.Contains(t, err.Error(), test.containerRuntime)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
version: 1
|
||||
common:
|
||||
apps:
|
||||
- appDirPath: ./webapp/
|
||||
appID: app_1
|
||||
- appDirPath: ./webapp/
|
||||
appID: app_2
|
||||
daprdLogDestination: fileAndConsole
|
||||
appLogDestination: fileAndConsole
|
||||
- appDirPath: ./webapp/
|
||||
appID: app_3
|
||||
daprdLogDestination: file
|
||||
appLogDestination: file
|
||||
- appDirPath: ./webapp/
|
||||
appID: app_4
|
||||
daprdLogDestination: console
|
||||
appLogDestination: console
|
||||
- appDirPath: ./webapp/
|
||||
appID: app_5
|
||||
daprdLogDestination: console
|
||||
appLogDestination: file
|
||||
- appDirPath: ./webapp/
|
||||
appID: app_6
|
||||
daprdLogDestination: file
|
||||
appLogDestination: console
|
||||
19
pkg/standalone/testdata/runfileconfig/test_run_config_multiple_resources_paths.yaml
vendored
Normal file
19
pkg/standalone/testdata/runfileconfig/test_run_config_multiple_resources_paths.yaml
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
version: 1
|
||||
common:
|
||||
# resourcesPath and resourcesPaths should be combined into resourcesPaths and should contain 1 path to load resources from.
|
||||
resourcesPath: ./app/resources
|
||||
resourcesPaths:
|
||||
- ./app/resources
|
||||
configFilePath: ./app/config.yaml
|
||||
apps:
|
||||
# resourcesPaths should contain 2 paths to load resources from.
|
||||
- appDirPath: ./webapp/
|
||||
resourcesPath: ./resources
|
||||
resourcesPaths:
|
||||
- ../backend/.dapr/resources
|
||||
# resourcesPaths should be resolved from common's section and should contain 1 path to load resources from.
|
||||
- appDirPath: ./webapp/
|
||||
appID: webapp_1
|
||||
# resourcesPaths resolved from app/.dapr folder and should contain 1 path to load resources from.
|
||||
- appID: backend
|
||||
appDirPath: ./backend/
|
||||
|
|
@ -7,4 +7,4 @@ apps:
|
|||
# tests resourcesPath and config_file resolved from dapr's custom installation directory.
|
||||
- appID: app_custom_dapr_dir
|
||||
appDirPath: ./app_precedence_rule/
|
||||
daprPath: ../custom_dapr_dir
|
||||
runtimePath: ../custom_dapr_dir
|
||||
|
|
@ -75,7 +75,7 @@ func removeDir(dirPath string) error {
|
|||
func Uninstall(uninstallAll bool, dockerNetwork string, containerRuntime string, inputInstallPath string) error {
|
||||
var containerErrs []error
|
||||
inputInstallPath = strings.TrimSpace(inputInstallPath)
|
||||
installDir, err := GetDaprPath(inputInstallPath)
|
||||
installDir, err := GetDaprRuntimePath(inputInstallPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -92,10 +92,12 @@ func Uninstall(uninstallAll bool, dockerNetwork string, containerRuntime string,
|
|||
|
||||
containerRuntime = strings.TrimSpace(containerRuntime)
|
||||
runtimeCmd := utils.GetContainerRuntimeCmd(containerRuntime)
|
||||
conatinerRuntimeAvailable := false
|
||||
conatinerRuntimeAvailable = utils.IsDockerInstalled() || utils.IsPodmanInstalled()
|
||||
if conatinerRuntimeAvailable {
|
||||
containerRuntimeAvailable := false
|
||||
containerRuntimeAvailable = utils.IsContainerRuntimeInstalled(containerRuntime)
|
||||
if containerRuntimeAvailable {
|
||||
containerErrs = removeContainers(uninstallPlacementContainer, uninstallAll, dockerNetwork, runtimeCmd)
|
||||
} else if uninstallPlacementContainer || uninstallAll {
|
||||
print.WarningStatusEvent(os.Stdout, "WARNING: could not delete supporting containers as container runtime is not installed or running")
|
||||
}
|
||||
|
||||
if uninstallAll {
|
||||
|
|
@ -111,8 +113,9 @@ func Uninstall(uninstallAll bool, dockerNetwork string, containerRuntime string,
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO move to use errors.Join once we move to go 1.20.
|
||||
for _, e := range containerErrs {
|
||||
err = fmt.Errorf("%w \n %s", err, e)
|
||||
err = fmt.Errorf("%w \n %w", err, e)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ type helmChartItems struct {
|
|||
Dapr []struct {
|
||||
Version string `yaml:"appVersion"`
|
||||
}
|
||||
DaprDashboard []struct {
|
||||
Version string `yaml:"appVersion"`
|
||||
} `yaml:"dapr-dashboard"`
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,6 +153,12 @@ func GetLatestReleaseHelmChart(helmChartURL string) (string, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Did not find a non-rc version, so we fallback to an RC.
|
||||
// This is helpful to allow us to validate installation of new charts (Dashboard).
|
||||
for _, release := range helmChartReleases.Entries.Dapr {
|
||||
return release.Version, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no releases")
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,8 +213,8 @@ func TestGetVersionsHelm(t *testing.T) {
|
|||
ExpectedVer string
|
||||
}{
|
||||
{
|
||||
"RC releases are skipped",
|
||||
"/rcs_are_skipped",
|
||||
"Use RC releases if there isn't a full release yet",
|
||||
"/fallback_to_rc",
|
||||
`apiVersion: v1
|
||||
entries:
|
||||
dapr:
|
||||
|
|
@ -268,8 +268,8 @@ entries:
|
|||
urls:
|
||||
- https://dapr.github.io/helm-charts/dapr-1.2.3-rc.1.tgz
|
||||
version: 1.2.3-rc.1 `,
|
||||
"no releases",
|
||||
"",
|
||||
"1.2.3-rc.1",
|
||||
},
|
||||
}
|
||||
m := http.NewServeMux()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
module emit-metrics
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
module processor
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
apiextensionsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/dapr/cli/pkg/kubernetes"
|
||||
"github.com/dapr/cli/tests/e2e/spawn"
|
||||
|
||||
k8s "k8s.io/client-go/kubernetes"
|
||||
|
|
@ -60,11 +61,13 @@ type VersionDetails struct {
|
|||
}
|
||||
|
||||
type TestOptions struct {
|
||||
HAEnabled bool
|
||||
MTLSEnabled bool
|
||||
ApplyComponentChanges bool
|
||||
CheckResourceExists map[Resource]bool
|
||||
UninstallAll bool
|
||||
HAEnabled bool
|
||||
MTLSEnabled bool
|
||||
ApplyComponentChanges bool
|
||||
ApplyHTTPEndpointChanges bool
|
||||
CheckResourceExists map[Resource]bool
|
||||
UninstallAll bool
|
||||
InitWithCustomCert bool
|
||||
}
|
||||
|
||||
type TestCase struct {
|
||||
|
|
@ -80,8 +83,8 @@ func GetVersionsFromEnv(t *testing.T, latest bool) (string, string) {
|
|||
runtimeEnvVar := "DAPR_RUNTIME_PINNED_VERSION"
|
||||
dashboardEnvVar := "DAPR_DASHBOARD_PINNED_VERSION"
|
||||
if latest {
|
||||
runtimeEnvVar = "DAPR_RUNTIME_LATEST_VERSION"
|
||||
dashboardEnvVar = "DAPR_DASHBOARD_LATEST_VERSION"
|
||||
runtimeEnvVar = "DAPR_RUNTIME_LATEST_STABLE_VERSION"
|
||||
dashboardEnvVar = "DAPR_DASHBOARD_LATEST_STABLE_VERSION"
|
||||
}
|
||||
if runtimeVersion, ok := os.LookupEnv(runtimeEnvVar); ok {
|
||||
daprRuntimeVersion = runtimeVersion
|
||||
|
|
@ -105,6 +108,13 @@ func UpgradeTest(details VersionDetails, opts TestOptions) func(t *testing.T) {
|
|||
"--log-as-json",
|
||||
}
|
||||
|
||||
hasDashboardInDaprChart, err := kubernetes.IsDashboardIncluded(details.RuntimeVersion)
|
||||
require.NoError(t, err, "failed to check if dashboard is included in dapr chart")
|
||||
|
||||
if !hasDashboardInDaprChart {
|
||||
args = append(args, "--dashboard-version", details.DashboardVersion)
|
||||
}
|
||||
|
||||
if details.ImageVariant != "" {
|
||||
args = append(args, "--image-variant", details.ImageVariant)
|
||||
}
|
||||
|
|
@ -171,6 +181,7 @@ func GetTestsOnInstall(details VersionDetails, opts TestOptions) []TestCase {
|
|||
{"clusterroles exist " + details.RuntimeVersion, ClusterRolesTest(details, opts)},
|
||||
{"clusterrolebindings exist " + details.RuntimeVersion, ClusterRoleBindingsTest(details, opts)},
|
||||
{"apply and check components exist " + details.RuntimeVersion, ComponentsTestOnInstallUpgrade(opts)},
|
||||
{"apply and check httpendpoints exist " + details.RuntimeVersion, HTTPEndpointsTestOnInstallUpgrade(opts)},
|
||||
{"check mtls " + details.RuntimeVersion, MTLSTestOnInstallUpgrade(opts)},
|
||||
{"status check " + details.RuntimeVersion, StatusTestOnInstallUpgrade(details, opts)},
|
||||
}
|
||||
|
|
@ -184,6 +195,7 @@ func GetTestsOnUninstall(details VersionDetails, opts TestOptions) []TestCase {
|
|||
{"clusterroles not exist " + details.RuntimeVersion, ClusterRolesTest(details, opts)},
|
||||
{"clusterrolebindings not exist " + details.RuntimeVersion, ClusterRoleBindingsTest(details, opts)},
|
||||
{"check components exist on uninstall " + details.RuntimeVersion, componentsTestOnUninstall(opts.UninstallAll)},
|
||||
{"check httpendpoints exist on uninstall " + details.RuntimeVersion, httpEndpointsTestOnUninstall(opts)},
|
||||
{"check mtls error " + details.RuntimeVersion, uninstallMTLSTest()},
|
||||
{"check status error " + details.RuntimeVersion, statusTestOnUninstall()},
|
||||
}
|
||||
|
|
@ -237,6 +249,9 @@ func MTLSTestOnInstallUpgrade(opts TestOptions) func(t *testing.T) {
|
|||
require.NoError(t, err, "expected no error on querying for mtls expiry")
|
||||
assert.Contains(t, output, "Root certificate expires in", "expected output to contain string")
|
||||
assert.Contains(t, output, "Expiry date:", "expected output to contain string")
|
||||
if opts.InitWithCustomCert {
|
||||
t.Log("check mtls expiry with custom cert: ", output)
|
||||
}
|
||||
|
||||
// export
|
||||
// check that the dir does not exist now.
|
||||
|
|
@ -288,6 +303,28 @@ func ComponentsTestOnInstallUpgrade(opts TestOptions) func(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func HTTPEndpointsTestOnInstallUpgrade(opts TestOptions) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
// if dapr is installed with httpendpoints.
|
||||
if opts.ApplyHTTPEndpointChanges {
|
||||
// apply any changes to the httpendpoint.
|
||||
t.Log("apply httpendpoint changes")
|
||||
output, err := spawn.Command("kubectl", "apply", "-f", "../testdata/namespace.yaml")
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "expected no error on kubectl apply")
|
||||
output, err = spawn.Command("kubectl", "apply", "-f", "../testdata/httpendpoint.yaml")
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "expected no error on kubectl apply")
|
||||
require.Equal(t, "httpendpoints.dapr.io/httpendpoint created\nhttpendpoints.dapr.io/httpendpoint created\n", output, "expected output to match")
|
||||
httpEndpointOutputCheck(t, output)
|
||||
|
||||
t.Log("check applied httpendpoint exists")
|
||||
_, err = spawn.Command("kubectl", "get", "httpendpoint")
|
||||
require.NoError(t, err, "expected no error on calling to retrieve httpendpoints")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func StatusTestOnInstallUpgrade(details VersionDetails, opts TestOptions) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
daprPath := GetDaprPath()
|
||||
|
|
@ -329,7 +366,10 @@ func StatusTestOnInstallUpgrade(details VersionDetails, opts TestOptions) func(t
|
|||
require.Equal(t, "True", cols[2], "healthly field must be true")
|
||||
require.Equal(t, "Running", cols[3], "pods must be Running")
|
||||
require.Equal(t, toVerify[1], cols[4], "replicas must be equal")
|
||||
require.Equal(t, toVerify[0], cols[5], "versions must match")
|
||||
// TODO: Skip the dashboard version check for now until the helm chart is updated.
|
||||
if cols[0] != "dapr-dashboard" {
|
||||
require.Equal(t, toVerify[0], cols[5], "versions must match")
|
||||
}
|
||||
delete(notFound, cols[0])
|
||||
}
|
||||
}
|
||||
|
|
@ -708,6 +748,7 @@ func installTest(details VersionDetails, opts TestOptions) func(t *testing.T) {
|
|||
"--log-as-json",
|
||||
}
|
||||
if !details.UseDaprLatestVersion {
|
||||
// TODO: Pass dashboard-version also when charts are released.
|
||||
args = append(args, "--runtime-version", details.RuntimeVersion)
|
||||
}
|
||||
if opts.HAEnabled {
|
||||
|
|
@ -722,6 +763,14 @@ func installTest(details VersionDetails, opts TestOptions) func(t *testing.T) {
|
|||
if details.ImageVariant != "" {
|
||||
args = append(args, "--image-variant", details.ImageVariant)
|
||||
}
|
||||
if opts.InitWithCustomCert {
|
||||
certParam := []string{
|
||||
"--ca-root-certificate", "../testdata/customcerts/root.pem",
|
||||
"--issuer-private-key", "../testdata/customcerts/issuer.key",
|
||||
"--issuer-public-certificate", "../testdata/customcerts/issuer.pem",
|
||||
}
|
||||
args = append(args, certParam...)
|
||||
}
|
||||
output, err := spawn.Command(daprPath, args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
|
|
@ -778,7 +827,7 @@ func componentsTestOnUninstall(all bool) func(t *testing.T) {
|
|||
return func(t *testing.T) {
|
||||
daprPath := GetDaprPath()
|
||||
// On Dapr uninstall CRDs are not removed, consequently the components will not be removed.
|
||||
// TODO Related to https://github.com/dapr/cli/issues/656.
|
||||
// TODO: Related to https://github.com/dapr/cli/issues/656.
|
||||
// For now the components remain.
|
||||
output, err := spawn.Command(daprPath, "components", "-k")
|
||||
require.NoError(t, err, "expected no error on calling dapr components")
|
||||
|
|
@ -808,6 +857,37 @@ func componentsTestOnUninstall(all bool) func(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func httpEndpointsTestOnUninstall(opts TestOptions) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
// If --all, then the below does not need to run.
|
||||
if opts.UninstallAll {
|
||||
// Note: Namespace is deleted in the uninstall components function,
|
||||
// so this should return as there is nothing to delete or do.
|
||||
return
|
||||
}
|
||||
if opts.ApplyHTTPEndpointChanges {
|
||||
// On Dapr uninstall CRDs are not removed, consequently the http endpoints will not be removed.
|
||||
output, err := spawn.Command("kubectl", "get", "httpendpoints")
|
||||
require.NoError(t, err, "expected no error on calling dapr httpendpoints")
|
||||
assert.Contains(t, output, "No resources found")
|
||||
|
||||
// Manually remove httpendpoints and verify output.
|
||||
output, err = spawn.Command("kubectl", "delete", "-f", "../testdata/httpendpoint.yaml")
|
||||
require.NoError(t, err, "expected no error on kubectl delete")
|
||||
require.Equal(t, "httpendpoints.dapr.io \"httpendpint\" deleted\nhttpendpoints.dapr.io \"httpendpoint\" deleted\n", output, "expected output to match")
|
||||
output, err = spawn.Command("kubectl", "delete", "-f", "../testdata/namespace.yaml")
|
||||
require.NoError(t, err, "expected no error on kubectl delete")
|
||||
t.Log(output)
|
||||
output, err = spawn.Command("kubectl", "get", "httpendpoints")
|
||||
require.NoError(t, err, "expected no error on calling dapr httpendpoints")
|
||||
lines := strings.Split(output, "\n")
|
||||
|
||||
// An extra empty line is there in output.
|
||||
require.Equal(t, 2, len(lines), "expected kubernetes response message to remain")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func statusTestOnUninstall() func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
daprPath := GetDaprPath()
|
||||
|
|
@ -832,7 +912,7 @@ func componentOutputCheck(t *testing.T, output string, all bool) {
|
|||
|
||||
lines = strings.Split(output, "\n")[2:] // remove header and warning message.
|
||||
|
||||
assert.Equal(t, 2, len(lines), "expected 2 componets") // default and test namespace components.
|
||||
assert.Equal(t, 2, len(lines), "expected 2 components") // default and test namespace components.
|
||||
|
||||
// for fresh cluster only one component yaml has been applied.
|
||||
testNsFields := strings.Fields(lines[0])
|
||||
|
|
@ -852,6 +932,17 @@ func namespaceComponentOutputCheck(t *testing.T, fields []string, namespace stri
|
|||
assert.Equal(t, "app1", fields[4], "expected scopes to match")
|
||||
}
|
||||
|
||||
func httpEndpointOutputCheck(t *testing.T, output string) {
|
||||
const (
|
||||
headerName = "NAME"
|
||||
headerAge = "AGE"
|
||||
)
|
||||
assert.Contains(t, output, headerName)
|
||||
assert.Contains(t, output, headerAge)
|
||||
// check for test httpendpoint named httpendpoint output to be present in output.
|
||||
assert.Contains(t, output, "httpendpoint")
|
||||
}
|
||||
|
||||
func validatePodsOnInstallUpgrade(t *testing.T, details VersionDetails) {
|
||||
ctx := context.Background()
|
||||
ctxt, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
|
|
@ -864,9 +955,9 @@ func validatePodsOnInstallUpgrade(t *testing.T, details VersionDetails) {
|
|||
require.NoError(t, err)
|
||||
|
||||
notFound := map[string]string{
|
||||
"sentry": details.RuntimeVersion,
|
||||
"sidecar": details.RuntimeVersion,
|
||||
"dashboard": details.DashboardVersion,
|
||||
"sentry": details.RuntimeVersion,
|
||||
"sidecar": details.RuntimeVersion,
|
||||
// "dashboard": details.DashboardVersion, TODO: enable when helm charts are updated.
|
||||
"placement": details.RuntimeVersion,
|
||||
"operator": details.RuntimeVersion,
|
||||
}
|
||||
|
|
@ -879,9 +970,9 @@ func validatePodsOnInstallUpgrade(t *testing.T, details VersionDetails) {
|
|||
}
|
||||
|
||||
prefixes := map[string]string{
|
||||
"sentry": "dapr-sentry-",
|
||||
"sidecar": "dapr-sidecar-injector-",
|
||||
"dashboard": "dapr-dashboard-",
|
||||
"sentry": "dapr-sentry-",
|
||||
"sidecar": "dapr-sidecar-injector-",
|
||||
// "dashboard": "dapr-dashboard-", TODO: enable when helm charts are updated.
|
||||
"placement": "dapr-placement-server-",
|
||||
"operator": "dapr-operator-",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,15 +17,20 @@ limitations under the License.
|
|||
package kubernetes_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/cli/tests/e2e/common"
|
||||
)
|
||||
|
||||
var (
|
||||
currentRuntimeVersion string
|
||||
currentDashboardVersion string
|
||||
currentVersionDetails common.VersionDetails
|
||||
currentRuntimeVersion string
|
||||
currentDashboardVersion string
|
||||
currentVersionDetails common.VersionDetails
|
||||
clusterRoles1_9_X = []string{"dapr-operator-admin", "dashboard-reader"}
|
||||
clusterRoleBindings1_9_X = []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"}
|
||||
clusterRoles1_10_X = []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"}
|
||||
clusterRoleBindings1_10_X = []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"}
|
||||
)
|
||||
|
||||
// ensureCleanEnv function needs to be called in every Test function.
|
||||
|
|
@ -36,12 +41,17 @@ func ensureCleanEnv(t *testing.T, useDaprLatestVersion bool) {
|
|||
currentVersionDetails = common.VersionDetails{
|
||||
RuntimeVersion: currentRuntimeVersion,
|
||||
DashboardVersion: currentDashboardVersion,
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io"},
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io", "httpendpoints.dapr.io"},
|
||||
ImageVariant: "",
|
||||
UseDaprLatestVersion: useDaprLatestVersion,
|
||||
}
|
||||
if strings.HasPrefix(currentRuntimeVersion, "1.9.") {
|
||||
currentVersionDetails.ClusterRoles = clusterRoles1_9_X
|
||||
currentVersionDetails.ClusterRoleBindings = clusterRoleBindings1_9_X
|
||||
} else {
|
||||
currentVersionDetails.ClusterRoles = clusterRoles1_10_X
|
||||
currentVersionDetails.ClusterRoleBindings = clusterRoleBindings1_10_X
|
||||
}
|
||||
// Ensure a clean environment
|
||||
common.EnsureUninstall(true) // does not wait for pod deletion
|
||||
}
|
||||
|
|
@ -171,6 +181,38 @@ func TestKubernetesHAModeMTLSEnabled(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestKubernetesInitWithCustomCert(t *testing.T) {
|
||||
// ensure clean env for test
|
||||
ensureCleanEnv(t, false)
|
||||
|
||||
// setup tests
|
||||
tests := []common.TestCase{}
|
||||
tests = append(tests, common.GetTestsOnInstall(currentVersionDetails, common.TestOptions{
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: true,
|
||||
InitWithCustomCert: true,
|
||||
ApplyComponentChanges: true,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
common.ClusterRoleBindings: true,
|
||||
},
|
||||
})...)
|
||||
|
||||
tests = append(tests, common.GetTestsOnUninstall(currentVersionDetails, common.TestOptions{
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: false,
|
||||
common.ClusterRoleBindings: false,
|
||||
},
|
||||
})...)
|
||||
|
||||
// execute tests
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.Name, tc.Callable)
|
||||
}
|
||||
}
|
||||
|
||||
// Test for certificate renewal
|
||||
|
||||
func TestRenewCertificateMTLSEnabled(t *testing.T) {
|
||||
|
|
@ -423,3 +465,38 @@ func TestKubernetesInstallwithoutRuntimeVersionFlag(t *testing.T) {
|
|||
t.Run(tc.Name, tc.Callable)
|
||||
}
|
||||
}
|
||||
|
||||
func TestK8sInstallwithoutRuntimeVersionwithMarinerImagesFlag(t *testing.T) {
|
||||
// ensure clean env for test
|
||||
ensureCleanEnv(t, true)
|
||||
|
||||
// install with mariner images
|
||||
currentVersionDetails.ImageVariant = "mariner"
|
||||
|
||||
tests := []common.TestCase{}
|
||||
installOpts := common.TestOptions{
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: true,
|
||||
ApplyComponentChanges: true,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
common.ClusterRoleBindings: true,
|
||||
},
|
||||
}
|
||||
|
||||
tests = append(tests, common.GetTestsOnInstall(currentVersionDetails, installOpts)...)
|
||||
|
||||
// teardown everything
|
||||
tests = append(tests, common.GetTestsOnUninstall(currentVersionDetails, common.TestOptions{
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: false,
|
||||
common.ClusterRoleBindings: false,
|
||||
},
|
||||
})...)
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.Name, tc.Callable)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ func TestStandaloneInitNegatives(t *testing.T) {
|
|||
require.NoError(t, err, "expected no error on querying for os home dir")
|
||||
|
||||
t.Run("run without install", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
output, err := cmdRun("")
|
||||
require.Error(t, err, "expected error status on run without install")
|
||||
path := filepath.Join(homeDir, ".dapr", "components")
|
||||
|
|
@ -44,18 +45,21 @@ func TestStandaloneInitNegatives(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("list without install", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
output, err := cmdList("")
|
||||
require.NoError(t, err, "expected no error status on list without install")
|
||||
require.Equal(t, "No Dapr instances found.\n", output)
|
||||
})
|
||||
|
||||
t.Run("stop without install", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
output, err := cmdStopWithAppID("test")
|
||||
require.NoError(t, err, "expected no error on stop without install")
|
||||
require.Contains(t, output, "failed to stop app id test: couldn't find app id test", "expected output to match")
|
||||
})
|
||||
|
||||
t.Run("uninstall without install", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
output, err := cmdUninstall()
|
||||
require.NoError(t, err, "expected no error on uninstall without install")
|
||||
require.Contains(t, output, "Removing Dapr from your machine...", "expected output to contain message")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,217 @@
|
|||
//go:build e2e && !template
|
||||
// +build e2e,!template
|
||||
|
||||
/*
|
||||
Copyright 2022 The Dapr Authors
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package standalone_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/cli/tests/e2e/common"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestStandaloneInitRunUninstallNonDefaultDaprPath covers init, version, run and uninstall with --runtime-path flag.
|
||||
func TestStandaloneInitRunUninstallNonDefaultDaprPath(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
t.Run("run with --runtime-path flag", func(t *testing.T) {
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-run-with-flag-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
daprRuntimeVersion, daprDashboardVersion := common.GetVersionsFromEnv(t, false)
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
"--runtime-path", daprPath,
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
// check version
|
||||
output, err = cmdVersion("", "--runtime-path", daprPath)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr version failed")
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[0], "edge")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
assert.Contains(t, lines[1], daprRuntimeVersion)
|
||||
|
||||
args = []string{
|
||||
"--runtime-path", daprPath,
|
||||
"--app-id", "run_with_dapr_runtime_path_flag",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
output, err = cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
|
||||
// Uninstall Dapr at the end of the test since it's being installed in a non-default location.
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr from custom path flag", "--runtime-path", daprPath)
|
||||
customDaprPath := filepath.Join(daprPath, ".dapr")
|
||||
assert.NoDirExists(t, customDaprPath)
|
||||
assert.DirExists(t, daprPath)
|
||||
// Check the directory is empty.
|
||||
f, err := os.ReadDir(daprPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, f, 0)
|
||||
})
|
||||
|
||||
t.Run("run with custom runtime path env var", func(t *testing.T) {
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-run-with-env-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
t.Setenv("DAPR_RUNTIME_PATH", daprPath)
|
||||
|
||||
daprRuntimeVersion, daprDashboardVersion := common.GetVersionsFromEnv(t, false)
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
// check version
|
||||
output, err = cmdVersion("", "--runtime-path", daprPath)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr version failed")
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[0], "edge")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
assert.Contains(t, lines[1], daprRuntimeVersion)
|
||||
|
||||
args = []string{
|
||||
"--app-id", "run_with_dapr_runtime_path_flag",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
output, err = cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
|
||||
// Uninstall Dapr at the end of the test since it's being installed in a non-default location.
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr from custom env var path")
|
||||
customDaprPath := filepath.Join(daprPath, ".dapr")
|
||||
assert.NoDirExists(t, customDaprPath)
|
||||
assert.DirExists(t, daprPath)
|
||||
// Check the directory is empty.
|
||||
f, err := os.ReadDir(daprPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, f, 0)
|
||||
})
|
||||
|
||||
t.Run("run with both runtime path flag and env var", func(t *testing.T) {
|
||||
daprPathEnv, err := os.MkdirTemp("", "dapr-e2e-run-with-envflag-1-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPathEnv) // clean up
|
||||
|
||||
daprPathFlag, err := os.MkdirTemp("", "dapr-e2e-run-with-envflag-2-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPathFlag) // clean up
|
||||
|
||||
t.Setenv("DAPR_RUNTIME_PATH", daprPathEnv)
|
||||
|
||||
daprRuntimeVersion, daprDashboardVersion := common.GetVersionsFromEnv(t, false)
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
"--runtime-path", daprPathFlag,
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
// check version
|
||||
output, err = cmdVersion("", "--runtime-path", daprPathFlag)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr version failed")
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[0], "edge")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
assert.Contains(t, lines[1], daprRuntimeVersion)
|
||||
|
||||
args = []string{
|
||||
"--runtime-path", daprPathFlag,
|
||||
"--app-id", "run_with_dapr_runtime_path_flag",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
flagDaprdBinPath := filepath.Join(daprPathFlag, ".dapr", "bin", "daprd")
|
||||
if runtime.GOOS == "windows" {
|
||||
flagDaprdBinPath += ".exe"
|
||||
}
|
||||
assert.FileExists(t, flagDaprdBinPath)
|
||||
|
||||
output, err = cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoDirExists(t, defaultDaprPath)
|
||||
|
||||
envDaprBinPath := filepath.Join(daprPathEnv, ".dapr", "bin")
|
||||
assert.NoDirExists(t, envDaprBinPath)
|
||||
|
||||
// Uninstall Dapr at the end of the test since it's being installed in a non-default location.
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr from custom path flag", "--runtime-path", daprPathFlag)
|
||||
customDaprPath := filepath.Join(daprPathFlag, ".dapr")
|
||||
assert.NoDirExists(t, customDaprPath)
|
||||
assert.DirExists(t, daprPathFlag)
|
||||
// Check the directory is empty.
|
||||
f, err := os.ReadDir(daprPathFlag)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, f, 0)
|
||||
})
|
||||
}
|
||||
|
|
@ -36,6 +36,11 @@ import (
|
|||
func TestStandaloneInit(t *testing.T) {
|
||||
daprRuntimeVersion, daprDashboardVersion := common.GetVersionsFromEnv(t, false)
|
||||
|
||||
t.Cleanup(func() {
|
||||
// remove dapr installation after all tests in this function.
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
})
|
||||
|
||||
t.Run("init with invalid private registry", func(t *testing.T) {
|
||||
if isSlimMode() {
|
||||
t.Skip("Skipping init with private registry test because of slim installation")
|
||||
|
|
@ -45,6 +50,7 @@ func TestStandaloneInit(t *testing.T) {
|
|||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
"--image-registry", "smplregistry.io/owner",
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
|
|
@ -61,6 +67,7 @@ func TestStandaloneInit(t *testing.T) {
|
|||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
"--image-registry", "localhost:5000",
|
||||
"--from-dir", "./local-dir",
|
||||
}
|
||||
|
|
@ -74,6 +81,7 @@ func TestStandaloneInit(t *testing.T) {
|
|||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
"--container-runtime", "invalid",
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
|
|
@ -87,6 +95,7 @@ func TestStandaloneInit(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
t.Log(output)
|
||||
|
|
@ -110,6 +119,7 @@ func TestStandaloneInit(t *testing.T) {
|
|||
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
"--image-variant", "mariner",
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
|
|
@ -128,67 +138,6 @@ func TestStandaloneInit(t *testing.T) {
|
|||
verifyConfigs(t, daprPath)
|
||||
})
|
||||
|
||||
t.Run("init with --dapr-path flag", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-init-with-flag-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion, "--dapr-path", daprPath)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
verifyContainers(t, daprRuntimeVersion)
|
||||
verifyBinaries(t, daprPath, daprRuntimeVersion, daprDashboardVersion)
|
||||
verifyConfigs(t, daprPath)
|
||||
})
|
||||
|
||||
t.Run("init with DAPR_PATH env var", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-init-with-env-var-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
t.Setenv("DAPR_PATH", daprPath)
|
||||
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
verifyContainers(t, daprRuntimeVersion)
|
||||
verifyBinaries(t, daprPath, daprRuntimeVersion, daprDashboardVersion)
|
||||
verifyConfigs(t, daprPath)
|
||||
})
|
||||
|
||||
t.Run("init with --dapr-path flag and DAPR_PATH env var", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath1, err := os.MkdirTemp("", "dapr-e2e-init-with-flag-and-env-1-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath1) // clean up
|
||||
daprPath2, err := os.MkdirTemp("", "dapr-e2e-init-with-flag-and-env-2-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath2) // clean up
|
||||
|
||||
t.Setenv("DAPR_PATH", daprPath1)
|
||||
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion, "--dapr-path", daprPath2)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
verifyContainers(t, daprRuntimeVersion)
|
||||
verifyBinaries(t, daprPath2, daprRuntimeVersion, daprDashboardVersion)
|
||||
verifyConfigs(t, daprPath2)
|
||||
})
|
||||
|
||||
t.Run("init without runtime-version flag", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
|
@ -209,6 +158,29 @@ func TestStandaloneInit(t *testing.T) {
|
|||
verifyBinaries(t, daprPath, latestDaprRuntimeVersion, latestDaprDashboardVersion)
|
||||
verifyConfigs(t, daprPath)
|
||||
})
|
||||
|
||||
t.Run("init without runtime-version flag with mariner images", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
args := []string{
|
||||
"--image-variant", "mariner",
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
daprPath := filepath.Join(homeDir, ".dapr")
|
||||
require.DirExists(t, daprPath, "Directory %s does not exist", daprPath)
|
||||
|
||||
latestDaprRuntimeVersion, latestDaprDashboardVersion := common.GetVersionsFromEnv(t, true)
|
||||
verifyContainers(t, latestDaprRuntimeVersion+"-mariner")
|
||||
verifyBinaries(t, daprPath, latestDaprRuntimeVersion, latestDaprDashboardVersion)
|
||||
verifyConfigs(t, daprPath)
|
||||
})
|
||||
}
|
||||
|
||||
// verifyContainers ensures that the correct containers are up and running.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/go-sdk/service/common"
|
||||
|
|
@ -28,10 +29,8 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStandaloneInvoke(t *testing.T) {
|
||||
ensureDaprInstallation(t)
|
||||
|
||||
s := daprHttp.NewService(":9987")
|
||||
func StartTestService(t *testing.T, port int) common.Service {
|
||||
s := daprHttp.NewService(":" + strconv.Itoa(port))
|
||||
|
||||
err := s.AddServiceInvocationHandler("/test", func(ctx context.Context, e *common.InvocationEvent) (*common.Content, error) {
|
||||
val := &common.Content{
|
||||
|
|
@ -44,7 +43,6 @@ func TestStandaloneInvoke(t *testing.T) {
|
|||
|
||||
assert.NoError(t, err, "unable to AddTopicEventHandler")
|
||||
|
||||
defer s.Stop()
|
||||
go func() {
|
||||
err = s.Start()
|
||||
|
||||
|
|
@ -53,8 +51,16 @@ func TestStandaloneInvoke(t *testing.T) {
|
|||
err = nil
|
||||
}
|
||||
|
||||
assert.NoError(t, err, "unable to listen on :9987")
|
||||
assert.NoError(t, err, "unable to listen on :%d", port)
|
||||
}()
|
||||
return s
|
||||
}
|
||||
|
||||
func TestStandaloneInvoke(t *testing.T) {
|
||||
port := 9987
|
||||
ensureDaprInstallation(t)
|
||||
s := StartTestService(t, port)
|
||||
defer s.Stop()
|
||||
|
||||
for _, path := range getSocketCases() {
|
||||
executeAgainstRunningDapr(t, func() {
|
||||
|
|
@ -106,6 +112,29 @@ func TestStandaloneInvoke(t *testing.T) {
|
|||
t.Log(output)
|
||||
require.NoError(t, err, "dapr stop failed")
|
||||
assert.Contains(t, output, "app stopped successfully: invoke_e2e")
|
||||
}, "run", "--app-id", "invoke_e2e", "--app-port", "9987", "--unix-domain-socket", path)
|
||||
}, "run", "--app-id", "invoke_e2e", "--app-port", strconv.Itoa(port), "--unix-domain-socket", path)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStandaloneInvokeWithAppChannel(t *testing.T) {
|
||||
port := 9988
|
||||
ensureDaprInstallation(t)
|
||||
s := StartTestService(t, port)
|
||||
defer s.Stop()
|
||||
|
||||
executeAgainstRunningDapr(t, func() {
|
||||
t.Run(fmt.Sprintf("data from file with app channel address set to localhost"), func(t *testing.T) {
|
||||
// empty unix domain socket path
|
||||
output, err := cmdInvoke("invoke_e2e_app_channel", "test", "", "--data-file", "../testdata/message.json")
|
||||
t.Log(output)
|
||||
assert.NoError(t, err, "unable to invoke with --data-file")
|
||||
assert.Contains(t, output, "App invoked successfully")
|
||||
assert.Contains(t, output, "{\"dapr\": \"is_great\"}")
|
||||
})
|
||||
|
||||
output, err := cmdStopWithAppID("invoke_e2e_app_channel")
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr stop failed")
|
||||
assert.Contains(t, output, "app stopped successfully: invoke_e2e_app_channel")
|
||||
}, "run", "--app-id", "invoke_e2e_app_channel", "--app-port", strconv.Itoa(port), "--app-channel-address", "localhost")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
@ -33,7 +34,6 @@ import (
|
|||
|
||||
func TestStandaloneList(t *testing.T) {
|
||||
ensureDaprInstallation(t)
|
||||
|
||||
executeAgainstRunningDapr(t, func() {
|
||||
output, err := cmdList("")
|
||||
t.Log(output)
|
||||
|
|
@ -98,6 +98,27 @@ func TestStandaloneList(t *testing.T) {
|
|||
cmd.Process.Kill()
|
||||
})
|
||||
|
||||
t.Run("daprd instance started by run in list", func(t *testing.T) {
|
||||
go func() {
|
||||
// starts dapr run in a goroutine
|
||||
runoutput, err := cmdRun("", "--app-id", "dapr_e2e_list", "--dapr-http-port", "3555", "--dapr-grpc-port", "4555", "--app-port", "0", "--enable-app-health-check", "--", "bash", "-c", "sleep 15; exit 0")
|
||||
t.Log(runoutput)
|
||||
require.NoError(t, err, "run failed")
|
||||
// daprd starts and sleep for 50s, this ensures daprd started by `dapr run ...` is stopped
|
||||
time.Sleep(15 * time.Second)
|
||||
assert.Contains(t, runoutput, "Exited Dapr successfully")
|
||||
}()
|
||||
|
||||
// wait for daprd to start
|
||||
time.Sleep(time.Second)
|
||||
output, err := cmdList("")
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr list failed with dapr run instance")
|
||||
listOutputCheck(t, output, true)
|
||||
// sleep to wait dapr run exit, in case have effect on other tests
|
||||
time.Sleep(15 * time.Second)
|
||||
})
|
||||
|
||||
t.Run("dashboard instance should not be listed", func(t *testing.T) {
|
||||
// TODO: remove this after figuring out the fix.
|
||||
// The issue is that the dashboard instance does not gets killed when the app is stopped.
|
||||
|
|
@ -124,7 +145,7 @@ func listOutputCheck(t *testing.T, output string, isCli bool) {
|
|||
// only one app is runnning at this time
|
||||
fields := strings.Fields(lines[0])
|
||||
// Fields splits on space, so Created time field might be split again
|
||||
assert.GreaterOrEqual(t, len(fields), 4, "expected at least 4 fields in components output")
|
||||
assert.GreaterOrEqual(t, len(fields), 10, "expected at least 10 fields in components output")
|
||||
if isCli {
|
||||
assert.Equal(t, "dapr_e2e_list", fields[0], "expected name to match")
|
||||
} else {
|
||||
|
|
@ -133,6 +154,7 @@ func listOutputCheck(t *testing.T, output string, isCli bool) {
|
|||
assert.Equal(t, "3555", fields[1], "expected http port to match")
|
||||
assert.Equal(t, "4555", fields[2], "expected grpc port to match")
|
||||
assert.Equal(t, "0", fields[3], "expected app port to match")
|
||||
assert.NotEmpty(t, fields[9], "expected an app PID (a real value or zero)")
|
||||
}
|
||||
|
||||
func listJsonOutputCheck(t *testing.T, output string) {
|
||||
|
|
@ -147,6 +169,9 @@ func listJsonOutputCheck(t *testing.T, output string) {
|
|||
assert.Equal(t, 3555, int(result[0]["httpPort"].(float64)), "expected http port to match")
|
||||
assert.Equal(t, 4555, int(result[0]["grpcPort"].(float64)), "expected grpc port to match")
|
||||
assert.Equal(t, 0, int(result[0]["appPort"].(float64)), "expected app port to match")
|
||||
assert.GreaterOrEqual(t, int(result[0]["appPid"].(float64)), 0, "expected an app PID (a real value or zero)")
|
||||
assert.Equal(t, "", result[0]["appLogPath"], "expected app log path to be empty")
|
||||
assert.Equal(t, "", result[0]["daprdLogPath"], "expected daprd log path to be empty")
|
||||
}
|
||||
|
||||
func listYamlOutputCheck(t *testing.T, output string) {
|
||||
|
|
@ -161,4 +186,7 @@ func listYamlOutputCheck(t *testing.T, output string) {
|
|||
assert.Equal(t, 3555, result[0]["httpPort"], "expected http port to match")
|
||||
assert.Equal(t, 4555, result[0]["grpcPort"], "expected grpc port to match")
|
||||
assert.Equal(t, 0, result[0]["appPort"], "expected app port to match")
|
||||
assert.GreaterOrEqual(t, result[0]["appPid"], 0, "expected an app PID (a real value or zero)")
|
||||
assert.Equal(t, "", result[0]["appLogPath"], "expected app log path to be empty")
|
||||
assert.Equal(t, "", result[0]["daprdLogPath"], "expected daprd log path to be empty")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import (
|
|||
|
||||
func TestStandalonePublish(t *testing.T) {
|
||||
ensureDaprInstallation(t)
|
||||
|
||||
sub := &common.Subscription{
|
||||
PubsubName: "pubsub",
|
||||
Topic: "sample",
|
||||
|
|
|
|||
|
|
@ -34,11 +34,12 @@ import (
|
|||
)
|
||||
|
||||
type AppTestOutput struct {
|
||||
appID string
|
||||
appLogContents []string
|
||||
daprdLogContent []string
|
||||
baseLogDirPath string
|
||||
appLogDoesNotExist bool
|
||||
appID string
|
||||
appLogContents []string
|
||||
daprdLogContent []string
|
||||
baseLogDirPath string
|
||||
appLogDoesNotExist bool
|
||||
daprdLogFileDoesNotExist bool
|
||||
}
|
||||
|
||||
func TestRunWithTemplateFile(t *testing.T) {
|
||||
|
|
@ -70,13 +71,13 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
// Deterministic output for template file, so we can assert line by line
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 4, "expected at least 4 lines in output of starting two apps")
|
||||
assert.Contains(t, lines[1], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[2], "Writing log files to directory")
|
||||
assert.Contains(t, lines[2], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[4], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[5], "Writing log files to directory")
|
||||
assert.Contains(t, lines[5], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.GreaterOrEqual(t, len(lines), 5, "expected at least 5 lines in output of starting two apps")
|
||||
assert.Contains(t, lines[2], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[3], "Writing log files to directory")
|
||||
assert.Contains(t, lines[3], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[5], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[6], "Writing log files to directory")
|
||||
assert.Contains(t, lines[6], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.")
|
||||
appTestOutput := AppTestOutput{
|
||||
appID: "processor",
|
||||
|
|
@ -120,21 +121,22 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
// Deterministic output for template file, so we can assert line by line
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 6, "expected at least 6 lines in output of starting two apps")
|
||||
assert.Contains(t, lines[0], "Validating config and starting app \"processor\"")
|
||||
assert.Contains(t, lines[1], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[2], "Writing log files to directory")
|
||||
assert.Contains(t, lines[2], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[3], "Validating config and starting app \"emit-metrics\"")
|
||||
assert.Contains(t, lines[4], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[5], "Writing log files to directory")
|
||||
assert.Contains(t, lines[5], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.GreaterOrEqual(t, len(lines), 7, "expected at least 7 lines in output of starting two apps")
|
||||
assert.Contains(t, lines[0], "This is a preview feature and subject to change in future releases.")
|
||||
assert.Contains(t, lines[1], "Validating config and starting app \"processor\"")
|
||||
assert.Contains(t, lines[2], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[3], "Writing log files to directory")
|
||||
assert.Contains(t, lines[3], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[4], "Validating config and starting app \"emit-metrics\"")
|
||||
assert.Contains(t, lines[5], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[6], "Writing log files to directory")
|
||||
assert.Contains(t, lines[6], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.")
|
||||
appTestOutput := AppTestOutput{
|
||||
appID: "processor",
|
||||
baseLogDirPath: "../../apps/processor/.dapr/logs",
|
||||
appLogContents: []string{
|
||||
"Received metrics: {3}",
|
||||
"Received metrics: {1}",
|
||||
},
|
||||
daprdLogContent: []string{
|
||||
"http server is running on port 3510",
|
||||
|
|
@ -148,7 +150,7 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
appLogContents: []string{
|
||||
"DAPR_HTTP_PORT set to 3511",
|
||||
"DAPR_HOST_ADD set to localhost",
|
||||
"Metrics with ID 3 sent",
|
||||
"Metrics with ID 1 sent",
|
||||
},
|
||||
daprdLogContent: []string{
|
||||
"termination signal received: shutting down",
|
||||
|
|
@ -177,13 +179,13 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
// Deterministic output for template file, so we can assert line by line
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 6, "expected at least 6 lines in output of starting two apps")
|
||||
assert.Contains(t, lines[1], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[2], "Writing log files to directory")
|
||||
assert.Contains(t, lines[2], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[4], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[5], "Writing log files to directory")
|
||||
assert.Contains(t, lines[5], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.GreaterOrEqual(t, len(lines), 7, "expected at least 7 lines in output of starting two apps")
|
||||
assert.Contains(t, lines[2], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[3], "Writing log files to directory")
|
||||
assert.Contains(t, lines[3], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[5], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[6], "Writing log files to directory")
|
||||
assert.Contains(t, lines[6], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.")
|
||||
appTestOutput := AppTestOutput{
|
||||
appID: "processor",
|
||||
|
|
@ -228,14 +230,14 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
// Deterministic output for template file, so we can assert line by line
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 7, "expected at least 7 lines in output of starting two apps with one app not having a command")
|
||||
assert.Contains(t, lines[1], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[2], "Writing log files to directory")
|
||||
assert.Contains(t, lines[2], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[4], "No application command found for app \"emit-metrics\" present in")
|
||||
assert.Contains(t, lines[5], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[6], "Writing log files to directory")
|
||||
assert.Contains(t, lines[6], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.GreaterOrEqual(t, len(lines), 8, "expected at least 8 lines in output of starting two apps with one app not having a command")
|
||||
assert.Contains(t, lines[2], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[3], "Writing log files to directory")
|
||||
assert.Contains(t, lines[3], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[5], "No application command found for app \"emit-metrics\" present in")
|
||||
assert.Contains(t, lines[6], "Started Dapr with app id \"emit-metrics\". HTTP Port: 3511.")
|
||||
assert.Contains(t, lines[7], "Writing log files to directory")
|
||||
assert.Contains(t, lines[7], "tests/apps/emit-metrics/.dapr/logs")
|
||||
assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.")
|
||||
appTestOutput := AppTestOutput{
|
||||
appID: "processor",
|
||||
|
|
@ -280,11 +282,11 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
require.Error(t, err, "run must fail")
|
||||
// Deterministic output for template file, so we can assert line by line
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 5, "expected at least 5 lines in output of starting two apps with last app having an empty command")
|
||||
assert.Contains(t, lines[1], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[2], "Writing log files to directory")
|
||||
assert.Contains(t, lines[2], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[4], "Error starting Dapr and app (\"emit-metrics\"): exec: no command")
|
||||
assert.GreaterOrEqual(t, len(lines), 6, "expected at least 6 lines in output of starting two apps with last app having an empty command")
|
||||
assert.Contains(t, lines[2], "Started Dapr with app id \"processor\". HTTP Port: 3510.")
|
||||
assert.Contains(t, lines[3], "Writing log files to directory")
|
||||
assert.Contains(t, lines[3], "tests/apps/processor/.dapr/logs")
|
||||
assert.Contains(t, lines[5], "Error starting Dapr and app (\"emit-metrics\"): exec: no command")
|
||||
appTestOutput := AppTestOutput{
|
||||
appID: "processor",
|
||||
baseLogDirPath: "../../apps/processor/.dapr/logs",
|
||||
|
|
@ -310,6 +312,64 @@ func TestRunWithTemplateFile(t *testing.T) {
|
|||
}
|
||||
assertLogOutputForRunTemplateExec(t, appTestOutput)
|
||||
})
|
||||
|
||||
t.Run("valid template file with app/daprd log destinations", func(t *testing.T) {
|
||||
runFilePath := "../testdata/run-template-files/app_output_to_file_and_console.yaml"
|
||||
t.Cleanup(func() {
|
||||
// assumption in the test is that there is only one set of app and daprd logs in the logs directory.
|
||||
os.RemoveAll("../../apps/emit-metrics/.dapr/logs")
|
||||
os.RemoveAll("../../apps/processor/.dapr/logs")
|
||||
stopAllApps(t, runFilePath)
|
||||
})
|
||||
args := []string{
|
||||
"-f", runFilePath,
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
output, err := cmdRunWithContext(ctx, "", args...)
|
||||
t.Logf(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
|
||||
// App logs for processor app should not be printed to console and only written to file.
|
||||
assert.NotContains(t, output, "== APP - processor")
|
||||
|
||||
// Daprd logs for processor app should only be printed to console and not written to file.
|
||||
assert.Contains(t, output, "msg=\"All outstanding components processed\" app_id=processor")
|
||||
|
||||
// App logs for emit-metrics app should be printed to console and written to file.
|
||||
assert.Contains(t, output, "== APP - emit-metrics")
|
||||
|
||||
// Daprd logs for emit-metrics app should only be written to file.
|
||||
assert.NotContains(t, output, "msg=\"All outstanding components processed\" app_id=emit-metrics")
|
||||
|
||||
assert.Contains(t, output, "Received signal to stop Dapr and app processes. Shutting down Dapr and app processes.")
|
||||
|
||||
appTestOutput := AppTestOutput{
|
||||
appID: "processor",
|
||||
baseLogDirPath: "../../apps/processor/.dapr/logs",
|
||||
appLogContents: []string{
|
||||
"Received metrics: {1}",
|
||||
},
|
||||
daprdLogContent: []string{},
|
||||
daprdLogFileDoesNotExist: true,
|
||||
}
|
||||
assertLogOutputForRunTemplateExec(t, appTestOutput)
|
||||
appTestOutput = AppTestOutput{
|
||||
appID: "emit-metrics",
|
||||
baseLogDirPath: "../../apps/emit-metrics/.dapr/logs",
|
||||
appLogContents: []string{
|
||||
"DAPR_HTTP_PORT set to 3511",
|
||||
"DAPR_HOST_ADD set to localhost",
|
||||
"Metrics with ID 1 sent",
|
||||
},
|
||||
daprdLogContent: []string{
|
||||
"termination signal received: shutting down",
|
||||
"Exited Dapr successfully",
|
||||
"Exited App successfully",
|
||||
},
|
||||
}
|
||||
assertLogOutputForRunTemplateExec(t, appTestOutput)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRunTemplateFileWithoutDaprInit(t *testing.T) {
|
||||
|
|
@ -327,7 +387,7 @@ func TestRunTemplateFileWithoutDaprInit(t *testing.T) {
|
|||
output, err := cmdRunWithContext(ctx, "", args...)
|
||||
t.Logf(output)
|
||||
require.Error(t, err, "run must fail")
|
||||
assert.Contains(t, output, " Error starting Dapr and app (\"processor\"): fork/exec")
|
||||
assert.Contains(t, output, "Error starting Dapr and app (\"processor\"): fork/exec")
|
||||
assert.Contains(t, output, "daprd: no such file or directory")
|
||||
})
|
||||
}
|
||||
|
|
@ -335,11 +395,12 @@ func TestRunTemplateFileWithoutDaprInit(t *testing.T) {
|
|||
func assertLogOutputForRunTemplateExec(t *testing.T, appTestOutput AppTestOutput) {
|
||||
// assumption in the test is that there is only one set of app and daprd logs in the logs directory.
|
||||
// This is true for the tests in this file.
|
||||
daprdLogFileName, err := lookUpFileFullName(appTestOutput.baseLogDirPath, "daprd")
|
||||
require.NoError(t, err, "failed to find daprd log file")
|
||||
daprdLogPath := filepath.Join(appTestOutput.baseLogDirPath, daprdLogFileName)
|
||||
readAndAssertLogFileContents(t, daprdLogPath, appTestOutput.daprdLogContent)
|
||||
|
||||
if !appTestOutput.daprdLogFileDoesNotExist {
|
||||
daprdLogFileName, err := lookUpFileFullName(appTestOutput.baseLogDirPath, "daprd")
|
||||
require.NoError(t, err, "failed to find daprd log file")
|
||||
daprdLogPath := filepath.Join(appTestOutput.baseLogDirPath, daprdLogFileName)
|
||||
readAndAssertLogFileContents(t, daprdLogPath, appTestOutput.daprdLogContent)
|
||||
}
|
||||
if appTestOutput.appLogDoesNotExist {
|
||||
return
|
||||
}
|
||||
|
|
@ -377,4 +438,5 @@ func lookUpFileFullName(dirPath, partialFilename string) (string, error) {
|
|||
func stopAllApps(t *testing.T, runfile string) {
|
||||
_, err := cmdStopWithRunTemplate(runfile)
|
||||
require.NoError(t, err, "failed to stop apps")
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,20 +18,19 @@ package standalone_test
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/cli/tests/e2e/common"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStandaloneRun(t *testing.T) {
|
||||
ensureDaprInstallation(t)
|
||||
|
||||
t.Cleanup(func() {
|
||||
// remove dapr installation after all tests in this function.
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
})
|
||||
for _, path := range getSocketCases() {
|
||||
t.Run(fmt.Sprintf("normal exit, socket: %s", path), func(t *testing.T) {
|
||||
output, err := cmdRun(path, "--", "bash", "-c", "echo test")
|
||||
|
|
@ -39,6 +38,7 @@ func TestStandaloneRun(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.NotContains(t, output, "Could not update sidecar metadata for cliPID")
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("error exit, socket: %s", path), func(t *testing.T) {
|
||||
|
|
@ -47,6 +47,7 @@ func TestStandaloneRun(t *testing.T) {
|
|||
require.Error(t, err, "run failed")
|
||||
assert.Contains(t, output, "The App process exited with error code: exit status 1")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.NotContains(t, output, "Could not update sidecar metadata for cliPID")
|
||||
})
|
||||
|
||||
t.Run("Use internal gRPC port if specified", func(t *testing.T) {
|
||||
|
|
@ -56,6 +57,7 @@ func TestStandaloneRun(t *testing.T) {
|
|||
assert.Contains(t, output, "internal gRPC server is running on port 9999")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.NotContains(t, output, "Could not update sidecar metadata for cliPID")
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -66,6 +68,7 @@ func TestStandaloneRun(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully", "App should be shutdown before it has a chance to return non-zero")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.NotContains(t, output, "Could not update sidecar metadata for cliPID")
|
||||
})
|
||||
|
||||
t.Run("API shutdown with socket", func(t *testing.T) {
|
||||
|
|
@ -78,6 +81,7 @@ func TestStandaloneRun(t *testing.T) {
|
|||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.NotContains(t, output, "Could not update sidecar metadata for cliPID")
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("check enableAPILogging flag in enabled mode"), func(t *testing.T) {
|
||||
|
|
@ -91,7 +95,10 @@ func TestStandaloneRun(t *testing.T) {
|
|||
output, err := cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "level=info msg=\"HTTP API Called: PUT /v1.0/metadata/appCommand")
|
||||
assert.Contains(t, output, "level=info msg=\"HTTP API Called\" app_id=enableApiLogging_info")
|
||||
assert.Contains(t, output, "method=\"PUT /v1.0/metadata/appCommand\"")
|
||||
assert.Contains(t, output, "method=\"PUT /v1.0/metadata/cliPID\"")
|
||||
assert.Contains(t, output, "method=\"PUT /v1.0/metadata/appPID\"")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
})
|
||||
|
|
@ -107,7 +114,28 @@ func TestStandaloneRun(t *testing.T) {
|
|||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.NotContains(t, output, "level=info msg=\"HTTP API Called: PUT /v1.0/metadata/appCommand\"")
|
||||
assert.NotContains(t, output, "level=info msg=\"HTTP API Called\" app_id=enableApiLogging_info")
|
||||
assert.NotContains(t, output, "method=\"PUT /v1.0/metadata/appCommand\"")
|
||||
assert.NotContains(t, output, "method=\"PUT /v1.0/metadata/cliPID\"")
|
||||
assert.NotContains(t, output, "method=\"PUT /v1.0/metadata/appPID\"")
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("check enableAPILogging with obfuscation through dapr config file"), func(t *testing.T) {
|
||||
args := []string{
|
||||
"--app-id", "enableApiLogging_info",
|
||||
"--config", "../testdata/config.yaml",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
output, err := cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
assert.Contains(t, output, "level=info msg=\"HTTP API Called\" app_id=enableApiLogging_info")
|
||||
assert.Contains(t, output, "method=\"PUT /v1.0/metadata/{key}\"")
|
||||
assert.Contains(t, output, "method=\"PUT /v1.0/metadata/{key}\"")
|
||||
assert.Contains(t, output, "method=\"PUT /v1.0/metadata/{key}\"")
|
||||
})
|
||||
|
||||
t.Run(fmt.Sprintf("check run with log JSON enabled"), func(t *testing.T) {
|
||||
|
|
@ -145,7 +173,23 @@ func TestStandaloneRun(t *testing.T) {
|
|||
output, err := cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "component loaded. name: test-statestore, type: state.in-memory/v1")
|
||||
assert.Contains(t, output, "Component loaded: test-statestore (state.in-memory/v1)")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
})
|
||||
|
||||
t.Run("check run with multiple resources-path", func(t *testing.T) {
|
||||
args := []string{
|
||||
"--app-id", "testapp",
|
||||
"--resources-path", "../testdata/resources",
|
||||
"--resources-path", "../testdata/additional_resources",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
output, err := cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Component loaded: test-statestore (state.in-memory/v1)")
|
||||
assert.Contains(t, output, "Component loaded: test-statestore-additional-resource (state.in-memory/v1)")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
})
|
||||
|
|
@ -158,127 +202,3 @@ func TestStandaloneRun(t *testing.T) {
|
|||
require.Contains(t, output, "The id for your application, used for service discovery", "expected usage to be printed")
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandaloneRunNonDefaultDaprPath(t *testing.T) {
|
||||
// Uninstall Dapr at the end of the test since it's being installed in a non-default location.
|
||||
t.Cleanup(func() {
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
})
|
||||
|
||||
t.Run("run with flag", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-run-with-flag-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion, "--dapr-path", daprPath)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
args := []string{
|
||||
"--dapr-path", daprPath,
|
||||
"--app-id", "run_with_dapr_path_flag",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
output, err = cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
})
|
||||
|
||||
t.Run("run with env var", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-run-with-env-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
t.Setenv("DAPR_PATH", daprPath)
|
||||
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
args := []string{
|
||||
"--app-id", "run_with_dapr_path_flag",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
output, err = cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
})
|
||||
|
||||
t.Run("run with both flag and env var", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPathForEnv, err := os.MkdirTemp("", "dapr-e2e-run-with-envflag-1-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPathForEnv) // clean up
|
||||
|
||||
daprPathForFlag, err := os.MkdirTemp("", "dapr-e2e-run-with-envflag-2-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPathForFlag) // clean up
|
||||
|
||||
t.Setenv("DAPR_PATH", daprPathForEnv)
|
||||
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion, "--dapr-path", daprPathForFlag)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
args := []string{
|
||||
"--dapr-path", daprPathForFlag,
|
||||
"--app-id", "run_with_dapr_path_flag",
|
||||
"--", "bash", "-c", "echo 'test'",
|
||||
}
|
||||
|
||||
flagDaprdBinPath := filepath.Join(daprPathForFlag, "bin", "daprd")
|
||||
if runtime.GOOS == "windows" {
|
||||
flagDaprdBinPath += ".exe"
|
||||
}
|
||||
assert.FileExists(t, flagDaprdBinPath)
|
||||
|
||||
output, err = cmdRun("", args...)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "run failed")
|
||||
assert.Contains(t, output, "Exited App successfully")
|
||||
assert.Contains(t, output, "Exited Dapr successfully")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
|
||||
envDaprBinPath := filepath.Join(daprPathForEnv, "bin")
|
||||
assert.NoFileExists(t, envDaprBinPath)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import (
|
|||
|
||||
func TestStandaloneStop(t *testing.T) {
|
||||
ensureDaprInstallation(t)
|
||||
|
||||
executeAgainstRunningDapr(t, func() {
|
||||
t.Run("stop", func(t *testing.T) {
|
||||
output, err := cmdStopWithAppID("dapr_e2e_stop")
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ func TestStopAppsStartedWithRunTemplate(t *testing.T) {
|
|||
go ensureAllAppsStartedWithRunTemplate(t)
|
||||
time.Sleep(10 * time.Second)
|
||||
cliPID := getCLIPID(t)
|
||||
// Assert dapr list contains template name
|
||||
assertTemplateListOutput(t, "test_dapr_template")
|
||||
output, err := cmdStopWithRunTemplate("../testdata/run-template-files/dapr.yaml")
|
||||
assert.NoError(t, err, "failed to stop apps started with run template")
|
||||
assert.Contains(t, output, "Dapr and app processes stopped successfully")
|
||||
|
|
@ -110,7 +112,24 @@ func getCLIPID(t *testing.T) string {
|
|||
}
|
||||
|
||||
func verifyCLIPIDNotExist(t *testing.T, pid string) {
|
||||
time.Sleep(5 * time.Second)
|
||||
output, err := cmdList("")
|
||||
require.NoError(t, err, "failed to list apps")
|
||||
assert.NotContains(t, output, pid)
|
||||
}
|
||||
|
||||
func assertTemplateListOutput(t *testing.T, name string) {
|
||||
output, err := cmdList("json")
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr list failed")
|
||||
var result []map[string]interface{}
|
||||
|
||||
err = json.Unmarshal([]byte(output), &result)
|
||||
|
||||
assert.NoError(t, err, "output was not valid JSON")
|
||||
|
||||
assert.Len(t, result, 2, "expected two apps to be running")
|
||||
assert.Equal(t, name, result[0]["runTemplateName"], "expected run template name to be %s", name)
|
||||
assert.NotEmpty(t, result[0]["appLogPath"], "expected appLogPath to be non-empty")
|
||||
assert.NotEmpty(t, result[0]["daprdLogPath"], "expected daprdLogPath to be non-empty")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ func executeAgainstRunningDapr(t *testing.T, f func(), daprArgs ...string) {
|
|||
// ensureDaprInstallation ensures that Dapr is installed.
|
||||
// If Dapr is not installed, a new installation is attempted.
|
||||
func ensureDaprInstallation(t *testing.T) {
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
daprRuntimeVersion, daprDashboardVersion := common.GetVersionsFromEnv(t, false)
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
|
|
@ -134,6 +134,7 @@ func ensureDaprInstallation(t *testing.T) {
|
|||
if os.IsNotExist(err) {
|
||||
args := []string{
|
||||
"--runtime-version", daprRuntimeVersion,
|
||||
"--dashboard-version", daprDashboardVersion,
|
||||
}
|
||||
output, err := cmdInit(args...)
|
||||
require.NoError(t, err, "failed to install dapr:%v", output)
|
||||
|
|
|
|||
|
|
@ -18,20 +18,16 @@ package standalone_test
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/cli/tests/e2e/common"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStandaloneVersion(t *testing.T) {
|
||||
ensureDaprInstallation(t)
|
||||
|
||||
t.Run("version", func(t *testing.T) {
|
||||
output, err := cmdVersion("")
|
||||
t.Log(output)
|
||||
|
|
@ -39,7 +35,10 @@ func TestStandaloneVersion(t *testing.T) {
|
|||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[0], "edge")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
runtimeVer, _ := common.GetVersionsFromEnv(t, false)
|
||||
assert.Contains(t, lines[1], runtimeVer)
|
||||
})
|
||||
|
||||
t.Run("version json", func(t *testing.T) {
|
||||
|
|
@ -49,105 +48,8 @@ func TestStandaloneVersion(t *testing.T) {
|
|||
var result map[string]interface{}
|
||||
err = json.Unmarshal([]byte(output), &result)
|
||||
assert.NoError(t, err, "output was not valid JSON")
|
||||
})
|
||||
}
|
||||
|
||||
func TestStandaloneVersionNonDefaultDaprPath(t *testing.T) {
|
||||
t.Run("version with flag", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-ver-with-flag-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion, "--dapr-path", daprPath)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
output, err = cmdVersion("", "--dapr-path", daprPath)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr version failed")
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
})
|
||||
|
||||
t.Run("version with env var", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath, err := os.MkdirTemp("", "dapr-e2e-ver-with-env-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath) // clean up
|
||||
|
||||
t.Setenv("DAPR_PATH", daprPath)
|
||||
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
output, err = cmdVersion("")
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr version failed")
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
})
|
||||
|
||||
t.Run("version with both flag and env var", func(t *testing.T) {
|
||||
// Ensure a clean environment
|
||||
must(t, cmdUninstall, "failed to uninstall Dapr")
|
||||
|
||||
daprPath1, err := os.MkdirTemp("", "dapr-e2e-ver-with-both-flag-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath1) // clean up
|
||||
|
||||
daprPath2, err := os.MkdirTemp("", "dapr-e2e-ver-with-both-env-*")
|
||||
assert.NoError(t, err)
|
||||
defer os.RemoveAll(daprPath2) // clean up
|
||||
|
||||
t.Setenv("DAPR_PATH", daprPath2)
|
||||
|
||||
daprRuntimeVersion, _ := common.GetVersionsFromEnv(t, false)
|
||||
output, err := cmdInit("--runtime-version", daprRuntimeVersion, "--dapr-path", daprPath1)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "init failed")
|
||||
assert.Contains(t, output, "Success! Dapr is up and running.")
|
||||
|
||||
output, err = cmdVersion("", "--dapr-path", daprPath1)
|
||||
t.Log(output)
|
||||
require.NoError(t, err, "dapr version failed")
|
||||
lines := strings.Split(output, "\n")
|
||||
assert.GreaterOrEqual(t, len(lines), 2, "expected at least 2 fields in components outptu")
|
||||
assert.Contains(t, lines[0], "CLI version")
|
||||
assert.Contains(t, lines[1], "Runtime version")
|
||||
|
||||
homeDir, err := os.UserHomeDir()
|
||||
require.NoError(t, err, "failed to get user home directory")
|
||||
|
||||
defaultDaprPath := filepath.Join(homeDir, ".dapr")
|
||||
assert.NoFileExists(t, defaultDaprPath)
|
||||
|
||||
envDaprBinPath := filepath.Join(daprPath2, "bin")
|
||||
assert.NoFileExists(t, envDaprBinPath)
|
||||
assert.Contains(t, result["Cli version"], "edge")
|
||||
runtimeVer, _ := common.GetVersionsFromEnv(t, false)
|
||||
assert.Contains(t, result["Runtime version"], runtimeVer)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: test-statestore-additional-resource
|
||||
spec:
|
||||
type: state.in-memory
|
||||
version: v1
|
||||
metadata:
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: daprConfig
|
||||
spec:
|
||||
logging:
|
||||
apiLogging:
|
||||
enabled: true
|
||||
obfuscateURLs: true
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEINqlhfOSK2ivIM6PZEQLLMKzN2XYoj+rsnuUiFPFNgh3oAoGCCqGSM49
|
||||
AwEHoUQDQgAE32a9w5gISgHyxKSKDaQcJGKPVzPoil9VzbIx01bPg+xjzIEyw+Ab
|
||||
ubZ7i9o0uaSlpyenBhUhyR6I6sT8UA92QQ==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICkzCCAjmgAwIBAgIUYTVByaDUJwdVWOtFyoqMoU+XvgAwCgYIKoZIzj0EAwIw
|
||||
eDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMRIwEAYDVQQHDAlEYXBydmlsbGUx
|
||||
FzAVBgNVBAoMDmRhcHIuaW8vc2VudHJ5MRcwFQYDVQQLDA5kYXByLmlvL3NlbnRy
|
||||
eTEWMBQGA1UEAwwNY2x1c3Rlci5sb2NhbDAeFw0yMzAyMjcxNDE0MTVaFw0zMzAy
|
||||
MjQxNDE0MTVaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTESMBAGA1UEBwwJ
|
||||
RGFwcnZpbGxlMRcwFQYDVQQKDA5kYXByLmlvL3NlbnRyeTEXMBUGA1UECwwOZGFw
|
||||
ci5pby9zZW50cnkxFjAUBgNVBAMMDWNsdXN0ZXIubG9jYWwwWTATBgcqhkjOPQIB
|
||||
BggqhkjOPQMBBwNCAATfZr3DmAhKAfLEpIoNpBwkYo9XM+iKX1XNsjHTVs+D7GPM
|
||||
gTLD4Bu5tnuL2jS5pKWnJ6cGFSHJHojqxPxQD3ZBo4GgMIGdMBIGA1UdEwEB/wQI
|
||||
MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr
|
||||
BgEFBQcDAjAYBgNVHREEETAPgg1jbHVzdGVyLmxvY2FsMB0GA1UdDgQWBBRt6RVG
|
||||
Y/Tu0iu/2n8Lw8LWYTAhLDAfBgNVHSMEGDAWgBSuUlkVIBFlcn6lB4XOeKRJeNLy
|
||||
cTAKBggqhkjOPQQDAgNIADBFAiEAve7rRSuFt4zpeui5vnPvWvDhxzt1TaCe54iN
|
||||
Y4SkoM8CIDQaa0EVxK+vSfew2t9b6KZ3/7rkLbUb3bjFhYqBCDCB
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICbTCCAhOgAwIBAgIUcDykAW2uO32/kmitYwg4vqntygQwCgYIKoZIzj0EAwIw
|
||||
eDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMRIwEAYDVQQHDAlEYXBydmlsbGUx
|
||||
FzAVBgNVBAoMDmRhcHIuaW8vc2VudHJ5MRcwFQYDVQQLDA5kYXByLmlvL3NlbnRy
|
||||
eTEWMBQGA1UEAwwNY2x1c3Rlci5sb2NhbDAeFw0yMzAyMjcxNDEzNTBaFw0zMzAy
|
||||
MjQxNDEzNTBaMHgxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJWQTESMBAGA1UEBwwJ
|
||||
RGFwcnZpbGxlMRcwFQYDVQQKDA5kYXByLmlvL3NlbnRyeTEXMBUGA1UECwwOZGFw
|
||||
ci5pby9zZW50cnkxFjAUBgNVBAMMDWNsdXN0ZXIubG9jYWwwWTATBgcqhkjOPQIB
|
||||
BggqhkjOPQMBBwNCAAS492cvbcRQj2xhI7SVRWMidesLgEdcts7qwtXl0p/2AXB8
|
||||
j/iYHJQh5ANugZW12WJnpM9/AVQ5fmp4B6GBcmI2o3sweTAPBgNVHRMBAf8EBTAD
|
||||
AQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
|
||||
AwIwGAYDVR0RBBEwD4INY2x1c3Rlci5sb2NhbDAdBgNVHQ4EFgQUrlJZFSARZXJ+
|
||||
pQeFznikSXjS8nEwCgYIKoZIzj0EAwIDSAAwRQIgHCDe5YBRz0BHPJDUnHEzgYAt
|
||||
FJo72wjN6BU5Sp0UbyUCIQCZAaEaLe7oUPIdLyaIiWj+FHTAi141uOOulP26AGwn
|
||||
wQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: HTTPEndpoint
|
||||
metadata:
|
||||
name: "httpendpoint"
|
||||
namespace: default
|
||||
spec:
|
||||
baseUrl: "https://test.com"
|
||||
headers:
|
||||
- name: "Accept-Language"
|
||||
value: "en-US"
|
||||
scopes:
|
||||
- app1
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
version: 1
|
||||
apps:
|
||||
- appDirPath: ../../../apps/processor/
|
||||
appPort: 9081
|
||||
daprHTTPPort: 3510
|
||||
command: ["go","run", "app.go"]
|
||||
appLogDestination: file
|
||||
daprdLogDestination: console
|
||||
- appID: emit-metrics
|
||||
appDirPath: ../../../apps/emit-metrics/
|
||||
daprHTTPPort: 3511
|
||||
env:
|
||||
DAPR_HOST_ADD: localhost
|
||||
command: ["go","run", "app.go"]
|
||||
|
|
@ -1,12 +1,15 @@
|
|||
version: 1
|
||||
name: test_dapr_template
|
||||
apps:
|
||||
- appDirPath: ../../../apps/processor/
|
||||
appPort: 9081
|
||||
daprHTTPPort: 3510
|
||||
command: ["go","run", "app.go"]
|
||||
appLogDestination: file
|
||||
- appID: emit-metrics
|
||||
appDirPath: ../../../apps/emit-metrics/
|
||||
daprHTTPPort: 3511
|
||||
env:
|
||||
DAPR_HOST_ADD: localhost
|
||||
command: ["go","run", "app.go"]
|
||||
appLogDestination: file
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ apps:
|
|||
appPort: 9081
|
||||
daprHTTPPort: 3510
|
||||
command: ["go","run", "app.go"]
|
||||
appLogDestination: file
|
||||
- appID: emit-metrics
|
||||
appDirPath: ../../../apps/emit-metrics/
|
||||
daprHTTPPort: 3511
|
||||
appLogDestination: file
|
||||
env:
|
||||
DAPR_HOST_ADD: localhost
|
||||
command: [""]
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ apps:
|
|||
- appDirPath: ../../../apps/processor/
|
||||
appPort: 9081
|
||||
daprHTTPPort: 3510
|
||||
appLogDestination: file
|
||||
command: ["go","run", "app.go"]
|
||||
- appID: emit-metrics
|
||||
appDirPath: ../../../apps/emit-metrics/
|
||||
daprHTTPPort: 3511 # required env var DAPR_HOST_ADD not set in the yaml file
|
||||
appLogDestination: file
|
||||
command: ["go","run", "app.go"]
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ apps:
|
|||
appPort: 9081
|
||||
daprHTTPPort: 3510
|
||||
command: ["go","run", "app.go"]
|
||||
appLogDestination: file
|
||||
- appID: emit-metrics
|
||||
appDirPath: ../../../apps/emit-metrics/
|
||||
daprHTTPPort: 3511
|
||||
appLogDestination: file
|
||||
env:
|
||||
DAPR_HOST_ADD: localhost
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ apps:
|
|||
appPort: 9081
|
||||
daprHTTPPort: 3510
|
||||
command: ["go","run", "app.go"]
|
||||
appLogDestination: file
|
||||
- appID: emit-metrics
|
||||
appDirPath: ../../../apps/emit-metrics/
|
||||
daprHTTPPort: 3511
|
||||
|
|
@ -11,3 +12,4 @@ apps:
|
|||
DAPR_HOST_ADD: localhost
|
||||
# Set wrong app name
|
||||
command: ["go","run", "wrongappname.go"]
|
||||
appLogDestination: file
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ package upgrade
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/dapr/cli/tests/e2e/common"
|
||||
|
|
@ -37,7 +38,7 @@ var supportedUpgradePaths = []upgradePath{
|
|||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
next: common.VersionDetails{
|
||||
RuntimeVersion: "1.8.4",
|
||||
RuntimeVersion: "1.8.7",
|
||||
DashboardVersion: "0.10.0",
|
||||
ImageVariant: "mariner",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
|
|
@ -47,66 +48,50 @@ var supportedUpgradePaths = []upgradePath{
|
|||
},
|
||||
{
|
||||
previous: common.VersionDetails{
|
||||
RuntimeVersion: "1.7.4",
|
||||
DashboardVersion: "0.10.0",
|
||||
RuntimeVersion: "1.9.5",
|
||||
DashboardVersion: "0.11.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
next: common.VersionDetails{
|
||||
RuntimeVersion: "1.8.0",
|
||||
DashboardVersion: "0.10.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
RuntimeVersion: "1.10.7",
|
||||
DashboardVersion: "0.12.0",
|
||||
ClusterRoles: []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"},
|
||||
ClusterRoleBindings: []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
},
|
||||
{
|
||||
previous: common.VersionDetails{
|
||||
RuntimeVersion: "1.6.0",
|
||||
DashboardVersion: "0.9.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io"},
|
||||
RuntimeVersion: "1.10.7",
|
||||
DashboardVersion: "0.12.0",
|
||||
ClusterRoles: []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"},
|
||||
ClusterRoleBindings: []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
next: common.VersionDetails{
|
||||
RuntimeVersion: "1.7.0",
|
||||
DashboardVersion: "0.10.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
RuntimeVersion: "1.11.0",
|
||||
DashboardVersion: "0.13.0",
|
||||
ClusterRoles: []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"},
|
||||
ClusterRoleBindings: []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io", "httpendpoints.dapr.io"},
|
||||
},
|
||||
},
|
||||
// test downgrade.
|
||||
{
|
||||
previous: common.VersionDetails{
|
||||
RuntimeVersion: "1.9.0",
|
||||
DashboardVersion: "0.11.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
RuntimeVersion: "1.11.0",
|
||||
DashboardVersion: "0.13.0",
|
||||
ClusterRoles: []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"},
|
||||
ClusterRoleBindings: []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io", "httpendpoints.dapr.io"},
|
||||
},
|
||||
next: common.VersionDetails{
|
||||
RuntimeVersion: "1.8.4",
|
||||
DashboardVersion: "0.10.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
},
|
||||
{
|
||||
previous: common.VersionDetails{
|
||||
RuntimeVersion: "1.8.4",
|
||||
DashboardVersion: "0.10.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
next: common.VersionDetails{
|
||||
RuntimeVersion: "1.9.0",
|
||||
DashboardVersion: "0.11.0",
|
||||
ClusterRoles: []string{"dapr-operator-admin", "dashboard-reader"},
|
||||
ClusterRoleBindings: []string{"dapr-operator", "dapr-role-tokenreview-binding", "dashboard-reader-global"},
|
||||
RuntimeVersion: "1.10.7",
|
||||
DashboardVersion: "0.12.0",
|
||||
ClusterRoles: []string{"dapr-dashboard", "dapr-injector", "dapr-operator-admin", "dapr-placement", "dapr-sentry"},
|
||||
ClusterRoleBindings: []string{"dapr-operator-admin", "dapr-dashboard", "dapr-injector", "dapr-placement", "dapr-sentry"},
|
||||
CustomResourceDefs: []string{"components.dapr.io", "configurations.dapr.io", "subscriptions.dapr.io", "resiliencies.dapr.io"},
|
||||
},
|
||||
},
|
||||
|
|
@ -126,6 +111,7 @@ func getTestsOnUpgrade(p upgradePath, installOpts, upgradeOpts common.TestOption
|
|||
{Name: "clusterroles exist " + details.RuntimeVersion, Callable: common.ClusterRolesTest(details, upgradeOpts)},
|
||||
{Name: "clusterrolebindings exist " + details.RuntimeVersion, Callable: common.ClusterRoleBindingsTest(details, upgradeOpts)},
|
||||
{Name: "previously applied components exist " + details.RuntimeVersion, Callable: common.ComponentsTestOnInstallUpgrade(upgradeOpts)},
|
||||
{Name: "previously applied http endpoints exist " + details.RuntimeVersion, Callable: common.HTTPEndpointsTestOnInstallUpgrade(upgradeOpts)},
|
||||
{Name: "check mtls " + details.RuntimeVersion, Callable: common.MTLSTestOnInstallUpgrade(upgradeOpts)},
|
||||
{Name: "status check " + details.RuntimeVersion, Callable: common.StatusTestOnInstallUpgrade(details, upgradeOpts)},
|
||||
}...)
|
||||
|
|
@ -163,9 +149,10 @@ func TestUpgradePathNonHAModeMTLSDisabled(t *testing.T) {
|
|||
for _, p := range supportedUpgradePaths {
|
||||
t.Run(fmt.Sprintf("v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||
installOpts := common.TestOptions{
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: false,
|
||||
ApplyComponentChanges: true,
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: false,
|
||||
ApplyComponentChanges: true,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -176,8 +163,9 @@ func TestUpgradePathNonHAModeMTLSDisabled(t *testing.T) {
|
|||
upgradeOpts := common.TestOptions{
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: false,
|
||||
// do not apply changes on upgrade, verify existing components.
|
||||
ApplyComponentChanges: false,
|
||||
// do not apply changes on upgrade, verify existing components and httpendpoints.
|
||||
ApplyComponentChanges: false,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -206,9 +194,10 @@ func TestUpgradePathNonHAModeMTLSEnabled(t *testing.T) {
|
|||
for _, p := range supportedUpgradePaths {
|
||||
t.Run(fmt.Sprintf("v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||
installOpts := common.TestOptions{
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: true,
|
||||
ApplyComponentChanges: true,
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: true,
|
||||
ApplyComponentChanges: true,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -219,8 +208,9 @@ func TestUpgradePathNonHAModeMTLSEnabled(t *testing.T) {
|
|||
upgradeOpts := common.TestOptions{
|
||||
HAEnabled: false,
|
||||
MTLSEnabled: true,
|
||||
// do not apply changes on upgrade, verify existing components.
|
||||
ApplyComponentChanges: false,
|
||||
// do not apply changes on upgrade, verify existing components and httpendpoints.
|
||||
ApplyComponentChanges: false,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -249,9 +239,10 @@ func TestUpgradePathHAModeMTLSDisabled(t *testing.T) {
|
|||
for _, p := range supportedUpgradePaths {
|
||||
t.Run(fmt.Sprintf("v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||
installOpts := common.TestOptions{
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: false,
|
||||
ApplyComponentChanges: true,
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: false,
|
||||
ApplyComponentChanges: true,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -262,8 +253,9 @@ func TestUpgradePathHAModeMTLSDisabled(t *testing.T) {
|
|||
upgradeOpts := common.TestOptions{
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: false,
|
||||
// do not apply changes on upgrade, verify existing components.
|
||||
ApplyComponentChanges: false,
|
||||
// do not apply changes on upgrade, verify existing components and httpendpoints.
|
||||
ApplyComponentChanges: false,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -292,9 +284,10 @@ func TestUpgradePathHAModeMTLSEnabled(t *testing.T) {
|
|||
for _, p := range supportedUpgradePaths {
|
||||
t.Run(fmt.Sprintf("v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||
installOpts := common.TestOptions{
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: true,
|
||||
ApplyComponentChanges: true,
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: true,
|
||||
ApplyComponentChanges: true,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
@ -305,8 +298,60 @@ func TestUpgradePathHAModeMTLSEnabled(t *testing.T) {
|
|||
upgradeOpts := common.TestOptions{
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: true,
|
||||
// do not apply changes on upgrade, verify existing components.
|
||||
ApplyComponentChanges: false,
|
||||
// do not apply changes on upgrade, verify existing components and httpendpoints.
|
||||
ApplyComponentChanges: false,
|
||||
ApplyHTTPEndpointChanges: false,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
common.ClusterRoleBindings: true,
|
||||
},
|
||||
}
|
||||
tests := getTestsOnUpgrade(p, installOpts, upgradeOpts)
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.Name, tc.Callable)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPEndpoint Dapr resource is a new type as of v1.11.
|
||||
// This test verifies install/upgrade functionality with this additional resource.
|
||||
func TestUpgradeWithHTTPEndpoint(t *testing.T) {
|
||||
// Ensure a clean environment.
|
||||
common.EnsureUninstall(false) // does not wait for pod deletion.
|
||||
for _, p := range supportedUpgradePaths {
|
||||
t.Run(fmt.Sprintf("setup v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||
t.Run("delete CRDs "+p.previous.RuntimeVersion, common.DeleteCRD(p.previous.CustomResourceDefs))
|
||||
t.Run("delete CRDs "+p.next.RuntimeVersion, common.DeleteCRD(p.next.CustomResourceDefs))
|
||||
})
|
||||
}
|
||||
|
||||
for _, p := range supportedUpgradePaths {
|
||||
// only check runtime versions that support HTTPEndpoint resource.
|
||||
if !strings.Contains(p.next.RuntimeVersion, "1.11") {
|
||||
return
|
||||
}
|
||||
t.Run(fmt.Sprintf("v%s to v%s", p.previous.RuntimeVersion, p.next.RuntimeVersion), func(t *testing.T) {
|
||||
installOpts := common.TestOptions{
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: true,
|
||||
ApplyComponentChanges: false,
|
||||
ApplyHTTPEndpointChanges: true,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
common.ClusterRoleBindings: true,
|
||||
},
|
||||
}
|
||||
|
||||
upgradeOpts := common.TestOptions{
|
||||
HAEnabled: true,
|
||||
MTLSEnabled: true,
|
||||
// do not apply changes on upgrade, verify existing components and httpendpoints.
|
||||
ApplyComponentChanges: false,
|
||||
ApplyHTTPEndpointChanges: true,
|
||||
CheckResourceExists: map[common.Resource]bool{
|
||||
common.CustomResourceDefs: true,
|
||||
common.ClusterRoles: true,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -44,6 +45,12 @@ const (
|
|||
marinerImageVariantName = "mariner"
|
||||
|
||||
socketFormat = "%s/dapr-%s-%s.socket"
|
||||
|
||||
windowsOsType = "windows"
|
||||
homeDirPrefix = "~/"
|
||||
|
||||
// DefaultAppChannelAddress is the default local network address that user application listen on.
|
||||
DefaultAppChannelAddress = "127.0.0.1"
|
||||
)
|
||||
|
||||
// IsValidContainerRuntime checks if the input is a valid container runtime.
|
||||
|
|
@ -169,10 +176,21 @@ func CreateDirectory(dir string) error {
|
|||
return os.Mkdir(dir, 0o777)
|
||||
}
|
||||
|
||||
// IsDockerInstalled checks whether docker is installed/running.
|
||||
func IsDockerInstalled() bool {
|
||||
//nolint:staticcheck
|
||||
cli, err := client.NewEnvClient()
|
||||
// IsContainerRuntimeInstalled checks whether the given container runtime is installed.
|
||||
// If the container runtime is unsupported, false is returned.
|
||||
func IsContainerRuntimeInstalled(containerRuntime string) bool {
|
||||
if containerRuntime == string(PODMAN) {
|
||||
return isPodmanInstalled()
|
||||
} else if containerRuntime == string(DOCKER) {
|
||||
return isDockerInstalled()
|
||||
}
|
||||
// This should never happen.
|
||||
return false
|
||||
}
|
||||
|
||||
// isDockerInstalled checks whether docker is installed.
|
||||
func isDockerInstalled() bool {
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
|
@ -180,7 +198,8 @@ func IsDockerInstalled() bool {
|
|||
return err == nil
|
||||
}
|
||||
|
||||
func IsPodmanInstalled() bool {
|
||||
// isPodmanInstalled checks whether podman is installed.
|
||||
func isPodmanInstalled() bool {
|
||||
cmd := exec.Command("podman", "version")
|
||||
if err := cmd.Run(); err != nil {
|
||||
return false
|
||||
|
|
@ -350,6 +369,24 @@ func GetAbsPath(baseDir, path string) string {
|
|||
return absPath
|
||||
}
|
||||
|
||||
// ResolveHomeDir resolves prefix of the given path, if present, to the user's home directory and returns it.
|
||||
func ResolveHomeDir(filePath string) (string, error) {
|
||||
if filePath == "" {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Resolve the home directory prefix, if present. This is only supported on non-Windows platforms.
|
||||
if runtime.GOOS != windowsOsType && strings.HasPrefix(filePath, homeDirPrefix) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error in getting the home directory for %s: %w", filePath, err)
|
||||
}
|
||||
filePath = filepath.Join(homeDir, filePath[len(homeDirPrefix):])
|
||||
}
|
||||
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
func ReadFile(filePath string) ([]byte, error) {
|
||||
bytes, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
|
|
@ -366,3 +403,8 @@ func FindFileInDir(dirPath, fileName string) (string, error) {
|
|||
}
|
||||
return filePath, nil
|
||||
}
|
||||
|
||||
// SanitizeDir sanitizes the input string to make it a valid directory.
|
||||
func SanitizeDir(destDir string) string {
|
||||
return strings.ReplaceAll(destDir, "'", "''")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import (
|
|||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
|
@ -75,7 +76,9 @@ func TestContainerRuntimeUtils(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actualValid := IsValidContainerRuntime(tc.input)
|
||||
if actualValid != tc.valid {
|
||||
t.Errorf("expected %v, got %v", tc.valid, actualValid)
|
||||
|
|
@ -117,7 +120,9 @@ func TestContains(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actualValid := Contains(tc.input, tc.expected)
|
||||
if actualValid != tc.valid {
|
||||
t.Errorf("expected %v, got %v", tc.valid, actualValid)
|
||||
|
|
@ -160,7 +165,9 @@ func TestGetVersionAndImageVariant(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
version, imageVariant := GetVersionAndImageVariant(tc.input)
|
||||
assert.Equal(t, tc.expectedVersion, version)
|
||||
assert.Equal(t, tc.expectedImageVariant, imageVariant)
|
||||
|
|
@ -195,7 +202,9 @@ func TestValidateFilePaths(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actual := ValidateFilePath(tc.input)
|
||||
assert.Equal(t, tc.expectedErr, actual != nil)
|
||||
})
|
||||
|
|
@ -235,13 +244,77 @@ func TestGetAbsPath(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actual := GetAbsPath(baseDir, tc.input)
|
||||
assert.Equal(t, tc.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveHomeDir(t *testing.T) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
assert.NoError(t, err)
|
||||
|
||||
testcases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
skipWindows bool
|
||||
}{
|
||||
{
|
||||
name: "empty path",
|
||||
input: "",
|
||||
expected: "",
|
||||
skipWindows: false,
|
||||
},
|
||||
{
|
||||
name: "home directory prefix with ~/",
|
||||
input: "~/home/path",
|
||||
expected: filepath.Join(homeDir, "home", "path"),
|
||||
skipWindows: true,
|
||||
},
|
||||
{
|
||||
name: "home directory prefix with ~/.",
|
||||
input: "~/./home/path",
|
||||
expected: filepath.Join(homeDir, ".", "home", "path"),
|
||||
skipWindows: true,
|
||||
},
|
||||
{
|
||||
name: "home directory prefix with ~/..",
|
||||
input: "~/../home/path",
|
||||
expected: filepath.Join(homeDir, "..", "home", "path"),
|
||||
skipWindows: true,
|
||||
},
|
||||
{
|
||||
name: "no home directory prefix",
|
||||
input: "../home/path",
|
||||
expected: "../home/path",
|
||||
skipWindows: false,
|
||||
},
|
||||
{
|
||||
name: "absolute path",
|
||||
input: "/absolute/path",
|
||||
expected: "/absolute/path",
|
||||
skipWindows: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.skipWindows && runtime.GOOS == "windows" {
|
||||
t.Skip("Skipping test on Windows")
|
||||
}
|
||||
t.Parallel()
|
||||
actual, err := ResolveHomeDir(tc.input)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadFile(t *testing.T) {
|
||||
fileName := createTempFile(t, "", "test_read_file")
|
||||
defer cleanupTempDir(t, fileName)
|
||||
|
|
@ -262,7 +335,9 @@ func TestReadFile(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, actual := ReadFile(tc.input)
|
||||
assert.Equal(t, tc.expectedErr, actual != nil)
|
||||
})
|
||||
|
|
@ -323,7 +398,9 @@ func TestFindFileInDir(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
filePath, err := FindFileInDir(tc.input, "dapr.yaml")
|
||||
assert.Equal(t, tc.expectedErr, err != nil)
|
||||
assert.Equal(t, tc.expectedFilePath, filePath)
|
||||
|
|
@ -403,7 +480,9 @@ func TestPrintDetail(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var buf bytes.Buffer
|
||||
err := PrintDetail(&buf, tc.format, tc.list)
|
||||
if tc.shouldError {
|
||||
|
|
@ -433,3 +512,51 @@ func cleanupTempDir(t *testing.T, fileName string) {
|
|||
err := os.RemoveAll(fileName)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSanitizeDir(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "directory with single quote in three places",
|
||||
input: "C:\\Use'rs\\sta'rk\\Docum'ents",
|
||||
expected: "C:\\Use''rs\\sta''rk\\Docum''ents",
|
||||
},
|
||||
{
|
||||
name: "directory with single quote in two places",
|
||||
input: "C:\\Use'rs\\sta'rk",
|
||||
expected: "C:\\Use''rs\\sta''rk",
|
||||
},
|
||||
{
|
||||
name: "directory with single quote in username",
|
||||
input: "C:\\Users\\Debash'ish",
|
||||
expected: "C:\\Users\\Debash''ish",
|
||||
},
|
||||
{
|
||||
name: "directory with no single quote",
|
||||
input: "C:\\Users\\Shubham",
|
||||
expected: "C:\\Users\\Shubham",
|
||||
},
|
||||
{
|
||||
name: "directory with single quote in one place",
|
||||
input: "C:\\Use'rs\\Shubham",
|
||||
expected: "C:\\Use''rs\\Shubham",
|
||||
},
|
||||
{
|
||||
name: "directory with single quote in many places in username",
|
||||
input: "C:\\Users\\Shu'bh'am",
|
||||
expected: "C:\\Users\\Shu''bh''am",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actual := SanitizeDir(tc.input)
|
||||
assert.Equal(t, tc.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue