Gitlab CI 拉源前检查目录是否存在
Gitlab CI check if directory exists before pulling origin
我正在尝试使用 gitlab ci runner 将我的 flask 应用程序部署到 AWS EC2 实例。
.gitlab.ci.yml
stages:
- test
- deploy
test_app:
image: python:latest
stage: test
before_script:
- python -V
- pip install virtualenv
- virtualenv env
- source env/bin/activate
- pip install flask
script:
- cd flask-ci-cd
- python test.py
prod-deploy:
stage: deploy
only:
- master # Run this job only on changes for stage branch
before_script:
- mkdir -p ~/.ssh
- echo -e "$RSA_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- bash .gitlab-deploy-prod.sh
environment:
name: deploy
.gitlab-deploy-prod.sh
#!/bin/bash
# Get servers list
set -f
# access server terminal
shell="ssh -o StrictHostKeyChecking=no ${SERVER_URL}"
git_token=$DEPLOY_TOKEN
echo "Deploy project on server ${SERVER_URL}"
if [ ${shell} -d "/flask-ci-cd" ] # check if directory exists
then
eval "${shell} cd flask-ci-cd && git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd"
else
eval "${shell} git pull https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd && cd flask-ci-cd"
fi
Error: .gitlab-deploy-prod.sh: line 7: -o: command not found
如何检查目录是否存在?
What i've tried.
#!/bin/bash
# Get servers list
set -f
# access server terminal
shell="ssh -o StrictHostKeyChecking=no ${SERVER_URL}"
git_token=$DEPLOY_TOKEN
eval "${shell}" # i thought gitlab would provide me with shell access
echo "Deploy project on server ${SERVER_URL}"
if [-d "/flask-ci-cd" ] # check if directory exists
then
eval "cd flask-ci-cd && git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd"
else
eval "git pull https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd && cd flask-ci-cd"
fi
我尝试在执行 if else 中的脚本之前登录到 ssh shell。但它没有按预期方式工作。
有一个测试命令明确检查文件和目录:
test -d "/flask-ci-cd" && eval $then_commands || eval $else_commands
根据 AWS 实例,我希望“测试”可用。我建议将命令放在变量中。 (例如 eval $then_commands)
- 您的脚本有一些错误。
- 不要使用评估。不,eval 不是那样工作的。 eval is evil
- 将命令存储到变量时,不要使用普通变量。使用 bash 数组来保留“单词”。
- 通过 ssh 传递的命令被双重转义。我建议更喜欢使用 here documents,它们更容易获得正确的引用。请注意此处文档定界符是否被引号引起来的扩展差异。
i thought gitlab would provide me with shell access
不,如果没有开放标准输入,远程 shell 将终止,因为它将从输入中读取 EOF。不,这样不行。
- 与其进行多次远程连接,只需将执行转移到远程端一次并在那里完成所有工作。
- 花点时间研究 quoting and word splitting 在 shell 中的工作原理。
git_token=$DEPLOY_TOKEN
不,设置变量不会导出到远程 shell。在调用远程端之前手动传递它们或展开它们。 (或者您也可以使用 ssh -o SendEnv=git_token
并使用 AcceptEnv=git_token
配置远程 ssh,我认为,从未尝试过)。
- 阅读您使用的实用程序的文档。
- 没有,
git clone
doesn't take branch name after url. You can specify branch with --branch
or -b
option. After url it takes directory name. See git clone --help
. Same for git pull
.
How can i check if directory existing??
使用bash数组来存储命令。通过在远程端执行 test
命令来检查目录是否存在。
shell=(ssh -o StrictHostKeyChecking=no "${SERVER_URL}")
if "${shell[@]}" [ -d "/flask-ci-cd" ]; then
...
如果目录名有空格,我会选择:
if "${shell[@]}" sh <<'EOF'
[ -d "/directory with spaces" ]
EOF
then
将 set -x
传递给 sh
以查看远程端发生的情况。
对于您的脚本,请尝试将执行移至远程端 - 建立 3 个单独的连接几乎没有逻辑。我说只是
echo "Deploy project on server ${SERVER_URL}"
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
if [ ! -d /flask-ci-cd ]; then
# Note: git_token is expanded on host side
git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git /flask-ci-cd
fi
cd /flask-ci-cd
git pull
EOF
但不是在某些情况下正确引用,而是使用 declare -p
和 declare -f
将正确引用的内容传输到远程端。这样你就不需要关于正确引用的案例 - 它会自然地工作:
echo "Deploy project on server ${SERVER_URL}"
work() {
if [ ! -d /flask-ci-cd ]; then
# Note: git_token is expanded on host side
git clone https://sbhusal123:"${git_token}"@gitlab.com/sbhusal123/flask-ci-cd.git /flask-ci-cd
fi
cd /flask-ci-cd
git pull
{
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
$(declare -p git_token) # transfer variables you need
$(declare -f work) # transfer function you need
work # call the function.
EOF
为以后阅读更新的答案。
.gitlab-ci.yml
stages:
- test
- deploy
test_app:
image: python:latest
stage: test
before_script:
- python -V
- pip install virtualenv
- virtualenv env
- source env/bin/activate
- pip install flask
script:
- cd flask-ci-cd
- python test.py
prod-deploy:
stage: deploy
only:
- master
before_script:
- mkdir -p ~/.ssh
- echo -e "$RSA_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- bash .gitlab-deploy-prod.sh
environment:
name: deploy
.gitlab-deploy-prod.sh
#!/bin/bash
# Get servers list
set -f
shell=(ssh -o StrictHostKeyChecking=no "${SERVER_URL}")
git_token=$DEPLOY_TOKEN
echo "Deploy project on server ${SERVER_URL}"
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
if [ ! -d flask-ci-cd ]; then
echo "\n Cloning into remote repo..."
git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git
# Create and activate virtualenv
echo "\n Creating virtual env"
python3 -m venv env
else
echo "Pulling remote repo origin..."
cd flask-ci-cd
git pull
cd ..
fi
# Activate virtual env
echo "\n Activating virtual env..."
source env/bin/activate
# Install packages
cd flask-ci-cd/
echo "\n Installing dependencies..."
pip install -r requirements.txt
EOF
我正在尝试使用 gitlab ci runner 将我的 flask 应用程序部署到 AWS EC2 实例。
.gitlab.ci.yml
stages:
- test
- deploy
test_app:
image: python:latest
stage: test
before_script:
- python -V
- pip install virtualenv
- virtualenv env
- source env/bin/activate
- pip install flask
script:
- cd flask-ci-cd
- python test.py
prod-deploy:
stage: deploy
only:
- master # Run this job only on changes for stage branch
before_script:
- mkdir -p ~/.ssh
- echo -e "$RSA_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- bash .gitlab-deploy-prod.sh
environment:
name: deploy
.gitlab-deploy-prod.sh
#!/bin/bash
# Get servers list
set -f
# access server terminal
shell="ssh -o StrictHostKeyChecking=no ${SERVER_URL}"
git_token=$DEPLOY_TOKEN
echo "Deploy project on server ${SERVER_URL}"
if [ ${shell} -d "/flask-ci-cd" ] # check if directory exists
then
eval "${shell} cd flask-ci-cd && git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd"
else
eval "${shell} git pull https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd && cd flask-ci-cd"
fi
Error: .gitlab-deploy-prod.sh: line 7: -o: command not found
如何检查目录是否存在?
What i've tried.
#!/bin/bash
# Get servers list
set -f
# access server terminal
shell="ssh -o StrictHostKeyChecking=no ${SERVER_URL}"
git_token=$DEPLOY_TOKEN
eval "${shell}" # i thought gitlab would provide me with shell access
echo "Deploy project on server ${SERVER_URL}"
if [-d "/flask-ci-cd" ] # check if directory exists
then
eval "cd flask-ci-cd && git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd"
else
eval "git pull https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git master && cd flask-ci-cd && cd flask-ci-cd"
fi
我尝试在执行 if else 中的脚本之前登录到 ssh shell。但它没有按预期方式工作。
有一个测试命令明确检查文件和目录:
test -d "/flask-ci-cd" && eval $then_commands || eval $else_commands
根据 AWS 实例,我希望“测试”可用。我建议将命令放在变量中。 (例如 eval $then_commands)
- 您的脚本有一些错误。
- 不要使用评估。不,eval 不是那样工作的。 eval is evil
- 将命令存储到变量时,不要使用普通变量。使用 bash 数组来保留“单词”。
- 通过 ssh 传递的命令被双重转义。我建议更喜欢使用 here documents,它们更容易获得正确的引用。请注意此处文档定界符是否被引号引起来的扩展差异。
i thought gitlab would provide me with shell access
不,如果没有开放标准输入,远程 shell 将终止,因为它将从输入中读取 EOF。不,这样不行。- 与其进行多次远程连接,只需将执行转移到远程端一次并在那里完成所有工作。
- 花点时间研究 quoting and word splitting 在 shell 中的工作原理。
git_token=$DEPLOY_TOKEN
不,设置变量不会导出到远程 shell。在调用远程端之前手动传递它们或展开它们。 (或者您也可以使用ssh -o SendEnv=git_token
并使用AcceptEnv=git_token
配置远程 ssh,我认为,从未尝试过)。- 阅读您使用的实用程序的文档。
- 没有,
git clone
doesn't take branch name after url. You can specify branch with--branch
or-b
option. After url it takes directory name. Seegit clone --help
. Same forgit pull
.
How can i check if directory existing??
使用bash数组来存储命令。通过在远程端执行 test
命令来检查目录是否存在。
shell=(ssh -o StrictHostKeyChecking=no "${SERVER_URL}")
if "${shell[@]}" [ -d "/flask-ci-cd" ]; then
...
如果目录名有空格,我会选择:
if "${shell[@]}" sh <<'EOF'
[ -d "/directory with spaces" ]
EOF
then
将 set -x
传递给 sh
以查看远程端发生的情况。
对于您的脚本,请尝试将执行移至远程端 - 建立 3 个单独的连接几乎没有逻辑。我说只是
echo "Deploy project on server ${SERVER_URL}"
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
if [ ! -d /flask-ci-cd ]; then
# Note: git_token is expanded on host side
git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git /flask-ci-cd
fi
cd /flask-ci-cd
git pull
EOF
但不是在某些情况下正确引用,而是使用 declare -p
和 declare -f
将正确引用的内容传输到远程端。这样你就不需要关于正确引用的案例 - 它会自然地工作:
echo "Deploy project on server ${SERVER_URL}"
work() {
if [ ! -d /flask-ci-cd ]; then
# Note: git_token is expanded on host side
git clone https://sbhusal123:"${git_token}"@gitlab.com/sbhusal123/flask-ci-cd.git /flask-ci-cd
fi
cd /flask-ci-cd
git pull
{
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
$(declare -p git_token) # transfer variables you need
$(declare -f work) # transfer function you need
work # call the function.
EOF
为以后阅读更新的答案。
.gitlab-ci.yml
stages:
- test
- deploy
test_app:
image: python:latest
stage: test
before_script:
- python -V
- pip install virtualenv
- virtualenv env
- source env/bin/activate
- pip install flask
script:
- cd flask-ci-cd
- python test.py
prod-deploy:
stage: deploy
only:
- master
before_script:
- mkdir -p ~/.ssh
- echo -e "$RSA_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- bash .gitlab-deploy-prod.sh
environment:
name: deploy
.gitlab-deploy-prod.sh
#!/bin/bash
# Get servers list
set -f
shell=(ssh -o StrictHostKeyChecking=no "${SERVER_URL}")
git_token=$DEPLOY_TOKEN
echo "Deploy project on server ${SERVER_URL}"
ssh -o StrictHostKeyChecking=no "${SERVER_URL}" bash <<EOF
if [ ! -d flask-ci-cd ]; then
echo "\n Cloning into remote repo..."
git clone https://sbhusal123:${git_token}@gitlab.com/sbhusal123/flask-ci-cd.git
# Create and activate virtualenv
echo "\n Creating virtual env"
python3 -m venv env
else
echo "Pulling remote repo origin..."
cd flask-ci-cd
git pull
cd ..
fi
# Activate virtual env
echo "\n Activating virtual env..."
source env/bin/activate
# Install packages
cd flask-ci-cd/
echo "\n Installing dependencies..."
pip install -r requirements.txt
EOF