mirror of
https://github.com/CopterExpress/clover.git
synced 2026-05-26 21:19:35 +00:00
Merge branch 'master' of github.com:CopterExpress/clever
This commit is contained in:
35
image_builder/Jenkinsfile
vendored
Normal file
35
image_builder/Jenkinsfile
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
string(name: 'GWBT_REF', defaultValue: "master")
|
||||
string(name: 'GWBT_URL', defaultValue: "https://github.com/CopterExpress/clever.git")
|
||||
string(name: 'GWBT_FILE', defaultValue: "")
|
||||
string(name: 'IMAGE_NAME', defaultValue: "\$(cat ${GWBT_FILE} | jq '.repository.name' -r)_${params.GWBT_REF}_\$(cat ${GWBT_FILE} | jq '.release.published_at' -r).img")
|
||||
string(name: 'GWBT_EVENT', defaultValue: 'release')
|
||||
booleanParam(name: 'ONLY_PUBLISH', defaultValue: false, description: 'ONLY PUBLISH')
|
||||
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')
|
||||
}
|
||||
environment {
|
||||
DEBIAN_FRONTEND = 'noninteractive'
|
||||
LANG = 'C.UTF-8'
|
||||
LC_ALL = 'C.UTF-8'
|
||||
}
|
||||
stages {
|
||||
stage('Build image') {
|
||||
when { not { expression { return params.ONLY_PUBLISH } } }
|
||||
steps {
|
||||
build job: 'CopterExpress-clever-build', parameters: [[$class: 'StringParameterValue', name: 'IMAGE_NAME', value: "${params.IMAGE_NAME}"], [$class: 'StringParameterValue', name: 'IMAGE_VERSION', value: "${params.GWBT_REF}"], [$class: 'StringParameterValue', name: 'GWBT_REF', value: "${params.GWBT_REF}"], [$class: 'StringParameterValue', name: 'GWBT_URL', value: "${params.GWBT_URL}"]]
|
||||
}
|
||||
}
|
||||
stage('Publish image') {
|
||||
when { environment name: 'GWBT_EVENT', value: 'release' }
|
||||
environment {
|
||||
CONFIG_FILE = "${params.BUILD_DIR}/coex-ci.json"
|
||||
YA_SCRIPT = "$WORKSPACE/image_builder/yadisk.py"
|
||||
}
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh publish_image ${params.BUILD_DIR} ${params.IMAGE_NAME} ${YA_SCRIPT} ${CONFIG_FILE} \$(cat ${params.GWBT_FILE} | jq '.release.id' -r) \"\$(cat ${params.GWBT_FILE} | jq '.release.body' | sed 's/\"//' | rev | sed 's/\"//' | rev)\""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
69
image_builder/README.md
Normal file
69
image_builder/README.md
Normal file
@@ -0,0 +1,69 @@
|
||||
## Setup your builder
|
||||
|
||||
1. Install requirements
|
||||
```(bash)
|
||||
sudo apt-get install unzip zip git python-pip jq curl
|
||||
sudo pip install YaDiskClient
|
||||
```
|
||||
2. Mount HDD
|
||||
> TODO
|
||||
|
||||
3. Enable swap on HDD
|
||||
> TODO:
|
||||
|
||||
And disable `dphys-swapfile`
|
||||
```(bash)
|
||||
sudo systemctl stop dphys-swapfile
|
||||
sudo systemctl disable dphys-swapfile
|
||||
```
|
||||
|
||||
3. Create /mnt/hdd_builder/workspace/coex-ci.json
|
||||
```(json)
|
||||
{
|
||||
"yadisk":
|
||||
{
|
||||
"login":"LOGIN",
|
||||
"password":"PASS",
|
||||
"server_dir":"/clever_images"
|
||||
},
|
||||
"github":
|
||||
{
|
||||
"login":"LOGIN",
|
||||
"password":"PASS",
|
||||
"url":"https://api.github.com/repos/CopterExpress/clever/releases/"
|
||||
}
|
||||
|
||||
```
|
||||
6. Add webhook to release on your github project
|
||||
> TODO
|
||||
|
||||
9. Install Jenkins
|
||||
> Manual https://www.digitalocean.com/community/tutorials/how-to-install-jenkins-on-ubuntu-16-04
|
||||
|
||||
10. Change user & group invoked Jenkins
|
||||
```(bash)
|
||||
sudo sed -i 's/JENKINS_USER=$NAME/JENKINS_USER=root/' /etc/default/jenkins
|
||||
sudo sed -i 's/JENKINS_GROUP=$NAME/JENKINS_GROUP=root/' /etc/default/jenkins
|
||||
```
|
||||
11. Install Jenikins plugins
|
||||
> Pipeline, Git SCM
|
||||
|
||||
12. Create Jenkins pipeline job
|
||||
> TODO
|
||||
|
||||
13. Configure Jenkins
|
||||
> TODO: Matrix autorization, GIT Token
|
||||
|
||||
13. Add Jenkins service to autostart
|
||||
```(bash)
|
||||
sudo systemctl enable jenkins
|
||||
```
|
||||
|
||||
14. Start service
|
||||
```(bash)
|
||||
sudo systemctl start jenkins
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
* Jenkins (BlueOcean plugin, optional)
|
||||
@@ -2,8 +2,8 @@ pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
string(name: 'IMAGE_NAME', defaultValue: 'clever_noname.img', description: 'Output image file name')
|
||||
string(name: 'GWBT_RELEASE_TAG_NAME', defaultValue: "master", description: 'Release tag name')
|
||||
string(name: 'IMAGE_VERSION', defaultValue: "${params.GWBT_RELEASE_TAG_NAME}", description: 'Image version')
|
||||
string(name: 'GWBT_REF', defaultValue: 'master', description: 'Checkout ref-param')
|
||||
string(name: 'IMAGE_VERSION', defaultValue: 'no_version', description: 'Image version')
|
||||
|
||||
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')
|
||||
string(name: 'MOUNT_POINT', defaultValue: '/mnt/hdd_builder/image', description: 'Mount point')
|
||||
@@ -32,43 +32,43 @@ pipeline {
|
||||
}
|
||||
stage('Initialize image') {
|
||||
environment {
|
||||
EXECUTE_FILE = 'scripts/init_image.sh'
|
||||
EXECUTE_FILE = 'image_builder/scripts/init_image.sh'
|
||||
}
|
||||
// TODO: Transfer apps.sh initialisation code here
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/image_builder/$EXECUTE_FILE ${params.IMAGE_VERSION} \$(basename ${params.RPI_DONWLOAD_URL})"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE ${params.IMAGE_VERSION} \$(basename ${params.RPI_DONWLOAD_URL})"
|
||||
}
|
||||
}
|
||||
stage('Hardware setup') {
|
||||
environment {
|
||||
EXECUTE_FILE = 'scripts/hardware_setup.sh'
|
||||
EXECUTE_FILE = 'image_builder/scripts/hardware_setup.sh'
|
||||
}
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/image_builder/$EXECUTE_FILE"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
|
||||
}
|
||||
}
|
||||
stage('Software install') {
|
||||
environment {
|
||||
EXECUTE_FILE = 'scripts/software_install.sh'
|
||||
EXECUTE_FILE = 'image_builder/scripts/software_install.sh'
|
||||
}
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/image_builder/$EXECUTE_FILE"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
|
||||
}
|
||||
}
|
||||
stage('Network setup') {
|
||||
environment {
|
||||
EXECUTE_FILE = 'scripts/network_setup.sh'
|
||||
EXECUTE_FILE = 'image_builder/scripts/network_setup.sh'
|
||||
}
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/image_builder/$EXECUTE_FILE"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
|
||||
}
|
||||
}
|
||||
stage('Install ROS') {
|
||||
environment {
|
||||
EXECUTE_FILE = 'scripts/ros_install.sh'
|
||||
EXECUTE_FILE = 'image_builder/scripts/ros_install.sh'
|
||||
}
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/image_builder/$EXECUTE_FILE"
|
||||
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
|
||||
}
|
||||
}
|
||||
// TODO: Add finalising step, transfer mirror removal from ros.sh
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Simple github release body-editor
|
||||
# @urpylka Artem Smirnov
|
||||
#
|
||||
# Use:
|
||||
# python git_release.py CONFIG_FILE RELEASE_ID RELEASE_BODY
|
||||
#
|
||||
|
||||
|
||||
from ConfigParser import SafeConfigParser
|
||||
import requests, sys, urllib
|
||||
|
||||
def json_wrapper(image_name, image_link, image_size, old_text):
|
||||
# Don't need for Jenkins plugin
|
||||
#old_text = urllib.unquote_plus(old_text)
|
||||
buffer = "### Download\n* [" + image_name + ".zip](" + image_link + ") (" + image_size + ")\n\n" + old_text
|
||||
js = {}
|
||||
js["body"] = buffer
|
||||
return js
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
cfgParser = SafeConfigParser()
|
||||
cfgParser.read(sys.argv[1])
|
||||
|
||||
js = json_wrapper(sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[3])
|
||||
|
||||
r = requests.patch(cfgParser.get('github','url') + sys.argv[2], json=js, auth=(cfgParser.get('github','login'), cfgParser.get('github','password')))
|
||||
|
||||
if r.status_code == 200:
|
||||
print("Message has been successfully added!")
|
||||
else:
|
||||
return 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -25,7 +25,7 @@ get_image() {
|
||||
fi
|
||||
echo "$(date) | 2. Unzipping Linux distribution image"
|
||||
local RPI_IMAGE_NAME=$(echo $RPI_ZIP_NAME | sed 's/zip/img/')
|
||||
unzip -p $1/$RPI_ZIP_NAME $RPI_IMAGE_NAME > $1/$IMAGE_NAME
|
||||
unzip -p $1/$RPI_ZIP_NAME $RPI_IMAGE_NAME > $1/$3
|
||||
echo "$(date) | Unzipping complete"
|
||||
}
|
||||
|
||||
@@ -51,8 +51,8 @@ resize_fs() {
|
||||
# --show : печатает имя устройства, например /dev/loop4
|
||||
|
||||
# http://karelzak.blogspot.ru/2015/05/resize-by-sfdisk.html
|
||||
# ", +" : расширяет раздел до размеров образа
|
||||
# -N 2 : выбирает раздел 2 для работы
|
||||
# ", +" : expand partition for volume size
|
||||
# -N 2 : select second partition for work
|
||||
|
||||
# There is a risk that sfdisk will ask for a disk remount to update partition table
|
||||
# TODO: Check sfdisk exit code
|
||||
@@ -79,46 +79,6 @@ resize_fs() {
|
||||
set -e
|
||||
}
|
||||
|
||||
publish_image_python() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: publish_image_python $BUILD_DIR $IMAGE_NAME $WORKSPACE $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
|
||||
|
||||
# https://developer.github.com/v3/repos/releases/
|
||||
#RELEASE_BODY="### Changelog\n* Add /boot/cmdline.txt net.ifnames=0 https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/\n* Updated cophelper\n* Installed copstat"
|
||||
|
||||
echo 'Zip image' \
|
||||
&& if [ ! -e "$1/$2.zip" ];
|
||||
then zip $1/$2.zip $1/$2
|
||||
fi
|
||||
echo 'Upload image' \
|
||||
&& local IMAGE_LINK=$($3/image_builder/yadisk.py $1/$4 $1/$2.zip) \
|
||||
&& local IMAGE_SIZE=$(du -sh $1/$2.zip | awk '{ print $1 }') \
|
||||
&& echo "Make downloads in GH-release" \
|
||||
&& $3/image_builder/git_release.py $1/$4 $5 $6 $2 $IMAGE_LINK $IMAGE_SIZE
|
||||
# echo "Fake publish"
|
||||
}
|
||||
|
||||
publish_image_bash() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: publish_image_bash $BUILD_DIR $IMAGE_NAME $WORKSPACE $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
|
||||
|
||||
# https://developer.github.com/v3/repos/releases/
|
||||
#RELEASE_BODY="### Changelog\n* Add /boot/cmdline.txt net.ifnames=0 https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/\n* Updated cophelper\n* Installed copstat"
|
||||
|
||||
echo 'Zip image' \
|
||||
&& if [ ! -e "$1/$2.zip" ];
|
||||
then zip $1/$2.zip $1/$2
|
||||
fi
|
||||
echo 'Upload image' \
|
||||
&& local IMAGE_LINK=$($3/image_builder/yadisk.py $1/$4 $1/$2.zip) \
|
||||
&& local IMAGE_SIZE=$(du -sh $1/$2.zip | awk '{ print $1 }') \
|
||||
&& local NEW_RELEASE_BODY="### Download\n* [$2.zip]($IMAGE_LINK) ($IMAGE_SIZE)\n\n$6" \
|
||||
&& local DATA="{ \"body\":\"$NEW_RELEASE_BODY\" }" \
|
||||
&& curl -d "$(echo $DATA)" -u "LOGIN:PASS" --request PATCH https://api.github.com/repos/ONWER/REPO/releases/$5
|
||||
}
|
||||
|
||||
burn_image() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
@@ -308,125 +268,10 @@ umount_system() {
|
||||
losetup -d $2
|
||||
}
|
||||
|
||||
set_config_var() {
|
||||
lua - "$1" "$2" "$3" <<EOF > "$3.bak"
|
||||
local key=assert(arg[1])
|
||||
local value=assert(arg[2])
|
||||
local fn=assert(arg[3])
|
||||
local file=assert(io.open(fn))
|
||||
local made_change=false
|
||||
for line in file:lines() do
|
||||
if line:match("^#?%s*"..key.."=.*$") then
|
||||
line=key.."="..value
|
||||
made_change=true
|
||||
end
|
||||
print(line)
|
||||
end
|
||||
|
||||
if not made_change then
|
||||
print(key.."="..value)
|
||||
end
|
||||
EOF
|
||||
mv "$3.bak" "$3"
|
||||
}
|
||||
|
||||
configure_system() {
|
||||
|
||||
# TEMPLATE: configure_system $IMAGE $MOUNT_POINT $ROOT_PARTITON $BOOT_PARTITION
|
||||
|
||||
local BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
|
||||
local CONFIG=/boot/config.txt
|
||||
|
||||
# Partitions numbers
|
||||
local BOOT_PARTITION=1
|
||||
local ROOT_PARTITION=2
|
||||
|
||||
BLACKLIST=$2$BLACKLIST
|
||||
CONFIG=$2$CONFIG
|
||||
|
||||
# 1. Примонитровать образ
|
||||
|
||||
# https://raspberrypi.stackexchange.com/questions/13137/how-can-i-mount-a-raspberry-pi-linux-distro-image
|
||||
# mount -v -o offset=48234496 -t ext4 2017-11-29-raspbian-stretch-lite.img $MOUNT_POINT
|
||||
# mount -v -o offset=4194304,sizelimit=29360128 -t vfat 2017-11-29-raspbian-stretch-lite.img $MOUNT_POINT/boot
|
||||
#
|
||||
# fdisk -l 2017-11-29-raspbian-stretch-lite.img
|
||||
# https://www.stableit.ru/2011/05/losetup.html
|
||||
# -f : losetup сам выбрал loop (минуя занятые)
|
||||
# -P : losetup монтирует разделы в образе как отдельные подразделы,
|
||||
# например /dev/loop0p1 и /dev/loop0p2
|
||||
# --show : печатает имя устройства, например /dev/loop4
|
||||
echo -e "\033[0;31m\033[1mMount loop-image: $1\033[0m\033[0m"
|
||||
DEV_IMAGE=$(losetup -Pf $1 --show)
|
||||
sleep 0.5
|
||||
|
||||
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
|
||||
mount ${DEV_IMAGE}p${ROOT_PARTITION} $2
|
||||
mount ${DEV_IMAGE}p${BOOT_PARTITION} $2/boot
|
||||
|
||||
# 2. Изменить необходимые настройки
|
||||
|
||||
# 2.1. Включить sshd
|
||||
echo -e "\033[0;31m\033[1mTurn on sshd\033[0m\033[0m"
|
||||
touch $2/boot/ssh
|
||||
|
||||
# 2.2. Включить GPIO
|
||||
# Включено по умолчанию
|
||||
|
||||
# 2.3. Включить I2C
|
||||
echo -e "\033[0;31m\033[1mTurn on I2C\033[0m\033[0m"
|
||||
|
||||
set_config_var dtparam=i2c_arm on $CONFIG &&
|
||||
if ! [ -e $BLACKLIST ]; then
|
||||
touch $BLACKLIST
|
||||
fi
|
||||
sed $BLACKLIST -i -e "s/^\(blacklist[[:space:]]*i2c[-_]bcm2708\)/#\1/"
|
||||
sed $2/etc/modules -i -e "s/^#[[:space:]]*\(i2c[-_]dev\)/\1/"
|
||||
if ! grep -q "^i2c[-_]dev" $2/etc/modules; then
|
||||
printf "i2c-dev\n" >> $2/etc/modules
|
||||
fi
|
||||
|
||||
# 2.4. Включить SPI
|
||||
echo -e "\033[0;31m\033[1mTurn on SPI\033[0m\033[0m"
|
||||
|
||||
set_config_var dtparam=spi on $CONFIG &&
|
||||
if ! [ -e $BLACKLIST ]; then
|
||||
touch $BLACKLIST
|
||||
fi
|
||||
sed $BLACKLIST -i -e "s/^\(blacklist[[:space:]]*spi[-_]bcm2708\)/#\1/"
|
||||
|
||||
# 2.5. Включить raspicam
|
||||
# Включена по умолчанию вроде как
|
||||
|
||||
# 2.6. Настроить AP wifi
|
||||
# 2.7. Настроить сеть на wlan
|
||||
# 2.8. Настроить DHCPd на wlan
|
||||
|
||||
# Отмонтировать образ
|
||||
umount_system $2 $DEV_IMAGE
|
||||
}
|
||||
|
||||
|
||||
prepare_fs() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: prepare_fs $IMAGE $SIZE
|
||||
|
||||
date
|
||||
# Удаляем старый образ
|
||||
# -f : не выводить ошибки, если файла нет
|
||||
rm -f $1
|
||||
# Копируем origin образ
|
||||
# --progress : Вывод прогресс-бара
|
||||
rsync --progress -av $1.orig $1
|
||||
expand_image $1 $2G
|
||||
date
|
||||
}
|
||||
|
||||
install_docker() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: install_docker $IMAGE $MOUNT_POINT $DEV_ROOTFS $DEV_BOOT
|
||||
# TEMPLATE: install_docker $IMAGE $MOUNT_POINT
|
||||
|
||||
# https://askubuntu.com/questions/485567/unexpected-end-of-file
|
||||
mount_system $1 $2 << EOF
|
||||
@@ -468,6 +313,53 @@ EOF
|
||||
# service docker start
|
||||
# https://forums.docker.com/t/cannot-connect-to-the-docker-daemon-is-the-docker-daemon-running-on-this-host/8925/17
|
||||
|
||||
publish_image() {
|
||||
|
||||
# STATIC FUNCTION
|
||||
# TEMPLATE: publish_image_bash $BUILD_DIR $IMAGE_NAME $YA_SCRIPT $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
|
||||
|
||||
# https://developer.github.com/v3/repos/releases/
|
||||
#RELEASE_BODY="### Changelog\n* Add /boot/cmdline.txt net.ifnames=0 https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/\n* Updated cophelper\n* Installed copstat"
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | Zip image\033[0m\033[0m"
|
||||
if [ ! -e "$1/$2.zip" ];
|
||||
then
|
||||
cd $1 && zip $2.zip $2
|
||||
echo -e "\033[0;31m\033[1m$(date) | Zipping complete!\033[0m\033[0m"
|
||||
else
|
||||
echo -e "\033[0;31m\033[1m$(date) | Zip-archive already created\033[0m\033[0m"
|
||||
fi
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | Upload image\033[0m\033[0m"
|
||||
local IMAGE_LINK=$($3 $4 $1/$2.zip)
|
||||
echo -e "\033[0;31m\033[1m$(date) | Upload copmlete!\033[0m\033[0m"
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | Meashure size of zip-image\033[0m\033[0m"
|
||||
local IMAGE_SIZE=$(du -sh $1/$2.zip | awk '{ print $1 }')
|
||||
echo -e "\033[0;31m\033[1m$(date) | Meashuring copmlete!\033[0m\033[0m"
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | Meashure hash-sum of zip-image\033[0m\033[0m"
|
||||
local IMAGE_HASH=$(sha256sum $1/$2.zip | awk '{ print $1 }')
|
||||
echo -e "\033[0;31m\033[1m$(date) | Meashuring copmlete!\033[0m\033[0m"
|
||||
|
||||
echo ""
|
||||
echo "\$6: $6"
|
||||
echo ""
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | Post message to GH\033[0m\033[0m"
|
||||
local NEW_RELEASE_BODY="### Download\n* [$2.zip]($IMAGE_LINK) ($IMAGE_SIZE)\nsha256: $IMAGE_HASH\n\n$6"
|
||||
local DATA="{ \"body\":\"$NEW_RELEASE_BODY\" }"
|
||||
|
||||
echo ""
|
||||
echo "\$DATA: $DATA"
|
||||
echo ""
|
||||
|
||||
local GH_LOGIN=$(cat $4 | jq '.github.login' -r)
|
||||
local GH_PASS=$(cat $4 | jq '.github.password' -r)
|
||||
local GH_URL=$(cat $4 | jq '.github.url' -r)
|
||||
curl -d "$DATA" -u "$GH_LOGIN:$GH_PASS" --request PATCH $GH_URL$5
|
||||
echo -e "\033[0;31m\033[1m$(date) | Post message to GH copmlete!\033[0m\033[0m"
|
||||
}
|
||||
|
||||
if [ $(whoami) != "root" ];
|
||||
then echo "" \
|
||||
@@ -487,29 +379,29 @@ echo "\$5: $5"
|
||||
echo "\$6: $6"
|
||||
echo "\$7: $7"
|
||||
|
||||
|
||||
# test_docker
|
||||
# install_docker
|
||||
# prepare_fs
|
||||
# configure_system
|
||||
# burn_image
|
||||
|
||||
case "$1" in
|
||||
mount_system) # mount_system $IMAGE $MOUNT_POINT
|
||||
mount_system)
|
||||
# mount_system $IMAGE $MOUNT_POINT
|
||||
mount_system $2 $3;;
|
||||
|
||||
get_image) # get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
|
||||
get_image)
|
||||
# get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
|
||||
get_image $2 $3 $4;;
|
||||
|
||||
resize_fs) # resize_fs $SIZE $BUILD_DIR $IMAGE_NAME
|
||||
resize_fs)
|
||||
# resize_fs $SIZE $BUILD_DIR $IMAGE_NAME
|
||||
resize_fs $2 $3 $4 $5;;
|
||||
|
||||
publish_image) # publish_image_python $BUILD_DIR $IMAGE_NAME $WORKSPACE $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
|
||||
publish_image_python $2 $3 $4 $5 $6 $7;;
|
||||
publish_image)
|
||||
# publish_image $BUILD_DIR $IMAGE_NAME $YA_SCRIPT $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
|
||||
publish_image $2 $3 $4 $5 $6 "$7";;
|
||||
|
||||
publish_image_bash) # publish_image_bash $BUILD_DIR $IMAGE_NAME $WORKSPACE $CONFIG_FILE $RELEASE_ID $RELEASE_BODY
|
||||
publish_image_bash $2 $3 $4 $5 $6 $7;;
|
||||
|
||||
execute) # execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ...
|
||||
execute)
|
||||
# execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ...
|
||||
execute $2 $3 $4 ${@:5};;
|
||||
|
||||
*)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
pipeline {
|
||||
agent any
|
||||
parameters {
|
||||
//string(name: 'GWBT_REPO_NAME', defaultValue: 'master', description: 'GWBT_REPO_NAME')
|
||||
//string(name: 'GWBT_RELEASE_TAG_NAME', defaultValue: 'master', description: 'REPO')
|
||||
//string(name: 'GWBT_RELEASE_PUBLISHED_AT', defaultValue: 'master', description: 'GWBT_RELEASE_PUBLISHED_AT')
|
||||
string(name: 'GWBT_RELEASE_ID', defaultValue: '', description: 'GWBT_RELEASE_ID')
|
||||
string(name: 'GWBT_RELEASE_BODY', defaultValue: '', description: 'GWBT_RELEASE_BODY')
|
||||
string(name: 'IMAGE_NAME', defaultValue: "${params.GWBT_REPO_NAME}_${params.GWBT_RELEASE_TAG_NAME}_${params.GWBT_RELEASE_PUBLISHED_AT}.img", description: 'IMAGE_NAME')
|
||||
string(name: 'GWBT_TRIGGER', defaultValue: 'release', description: 'GWBT_TRIGGER')
|
||||
booleanParam(name: 'ONLY_PUBLISH', defaultValue: false, description: 'ONLY PUBLISH')
|
||||
|
||||
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')
|
||||
}
|
||||
environment {
|
||||
DEBIAN_FRONTEND = 'noninteractive'
|
||||
LANG = 'C.UTF-8'
|
||||
LC_ALL = 'C.UTF-8'
|
||||
}
|
||||
stages {
|
||||
stage('Build image') {
|
||||
when { not { expression { return params.ONLY_PUBLISH } } }
|
||||
steps {
|
||||
build job: 'CopterExpress-clever-build', parameters: [[$class: 'StringParameterValue', name: 'IMAGE_NAME', value: "${params.IMAGE_NAME}"], [$class: 'StringParameterValue', name: 'GWBT_RELEASE_TAG_NAME', value: "${params.GWBT_RELEASE_TAG_NAME}"]]
|
||||
sh "echo ${params.IMAGE_NAME}"
|
||||
}
|
||||
}
|
||||
stage('Publish image') {
|
||||
when { environment name: 'GWBT_TRIGGER', value: 'release' }
|
||||
environment {
|
||||
CONFIG_FILE = 'coex-ci.conf'
|
||||
}
|
||||
steps {
|
||||
sh "$WORKSPACE/image_builder/image_config.sh publish_image ${params.BUILD_DIR} ${params.IMAGE_NAME} $WORKSPACE $CONFIG_FILE ${params.GWBT_RELEASE_ID} \'${params.GWBT_RELEASE_BODY}\'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,135 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immidiately on non-zero result
|
||||
set -e
|
||||
|
||||
##################################################################################################################################
|
||||
# Настройка интерфейсов
|
||||
##################################################################################################################################
|
||||
#
|
||||
# Script for image configure
|
||||
# @urpylka Artem Smirnov
|
||||
#
|
||||
|
||||
# вот так все в принципе должно включиться
|
||||
# /usr/bin/raspi-config nonint do_i2c 0
|
||||
# /usr/bin/raspi-config nonint do_spi 0
|
||||
# /usr/bin/raspi-config nonint do_camera 0
|
||||
# /usr/bin/raspi-config nonint do_rgpio 0
|
||||
# /usr/bin/raspi-config nonint do_ssh 0
|
||||
##################################################
|
||||
# Configure hardware interfaces
|
||||
##################################################
|
||||
|
||||
# по идеи эти настройки должны проводиться до по другому как сделано в prepare_image.sh
|
||||
|
||||
set_config_var() {
|
||||
lua - "$1" "$2" "$3" <<EOF > "$3.bak"
|
||||
local key=assert(arg[1])
|
||||
local value=assert(arg[2])
|
||||
local fn=assert(arg[3])
|
||||
local file=assert(io.open(fn))
|
||||
local made_change=false
|
||||
for line in file:lines() do
|
||||
if line:match("^#?%s*"..key.."=.*$") then
|
||||
line=key.."="..value
|
||||
made_change=true
|
||||
end
|
||||
print(line)
|
||||
end
|
||||
|
||||
if not made_change then
|
||||
print(key.."="..value)
|
||||
end
|
||||
EOF
|
||||
mv "$3.bak" "$3"
|
||||
}
|
||||
|
||||
BLACKLIST=/etc/modprobe.d/raspi-blacklist.conf
|
||||
CONFIG=/boot/config.txt
|
||||
|
||||
# 2. Изменить необходимые настройки
|
||||
|
||||
# 2.1. Включить sshd
|
||||
# 1. Enable sshd
|
||||
echo -e "\033[0;31m\033[1m$(date) | #1 Turn on sshd\033[0m\033[0m"
|
||||
touch /boot/ssh
|
||||
# /usr/bin/raspi-config nonint do_ssh 0
|
||||
|
||||
# 2.2. Включить GPIO
|
||||
# Включено по умолчанию
|
||||
# 2. Enable GPIO
|
||||
echo -e "\033[0;31m\033[1m$(date) | #2 GPIO enabled by default\033[0m\033[0m"
|
||||
|
||||
# 2.3. Включить I2C
|
||||
echo -e "\033[0;31m\033[1m$(date) | #2 Turn on I2C\033[0m\033[0m"
|
||||
# 3. Enable I2C
|
||||
echo -e "\033[0;31m\033[1m$(date) | #3 Turn on I2C\033[0m\033[0m"
|
||||
/usr/bin/raspi-config nonint do_i2c 0
|
||||
|
||||
set_config_var dtparam=i2c_arm on $CONFIG &&
|
||||
if ! [ -e $BLACKLIST ]; then
|
||||
touch $BLACKLIST
|
||||
fi
|
||||
sed $BLACKLIST -i -e "s/^\(blacklist[[:space:]]*i2c[-_]bcm2708\)/#\1/"
|
||||
sed /etc/modules -i -e "s/^#[[:space:]]*\(i2c[-_]dev\)/\1/"
|
||||
if ! grep -q "^i2c[-_]dev" /etc/modules; then
|
||||
printf "i2c-dev\n" >> /etc/modules
|
||||
fi
|
||||
# 4. Enable SPI
|
||||
echo -e "\033[0;31m\033[1m$(date) | #4 Turn on SPI\033[0m\033[0m"
|
||||
/usr/bin/raspi-config nonint do_spi 0
|
||||
|
||||
# 2.4. Включить SPI
|
||||
echo -e "\033[0;31m\033[1m$(date) | #3 Turn on SPI\033[0m\033[0m"
|
||||
# 5. Enable raspicam
|
||||
echo -e "\033[0;31m\033[1m$(date) | #5 Turn on raspicam\033[0m\033[0m"
|
||||
/usr/bin/raspi-config nonint do_camera 0
|
||||
|
||||
set_config_var dtparam=spi on $CONFIG &&
|
||||
if ! [ -e $BLACKLIST ]; then
|
||||
touch $BLACKLIST
|
||||
fi
|
||||
sed $BLACKLIST -i -e "s/^\(blacklist[[:space:]]*spi[-_]bcm2708\)/#\1/"
|
||||
# 6. Enable hardware UART
|
||||
echo -e "\033[0;31m\033[1m$(date) | #6 Turn on UART\033[0m\033[0m"
|
||||
# Temporary solution
|
||||
# https://github.com/RPi-Distro/raspi-config/pull/75
|
||||
/usr/bin/raspi-config nonint do_serial 1
|
||||
/usr/bin/raspi-config nonint set_config_var enable_uart 1 /boot/config.txt
|
||||
|
||||
# 2.5. Включить raspicam
|
||||
echo -e "\033[0;31m\033[1m$(date) | #4 Turn on raspicam\033[0m\033[0m"
|
||||
# After adding to Raspbian OS
|
||||
# https://github.com/RPi-Distro/raspi-config/commit/d6d9ecc0d9cbe4aaa9744ae733b9cb239e79c116
|
||||
#/usr/bin/raspi-config nonint do_serial 2
|
||||
|
||||
get_config_var() {
|
||||
lua - "$1" "$2" <<EOF
|
||||
local key=assert(arg[1])
|
||||
local fn=assert(arg[2])
|
||||
local file=assert(io.open(fn))
|
||||
local found=false
|
||||
for line in file:lines() do
|
||||
local val = line:match("^%s*"..key.."=(.*)$")
|
||||
if (val ~= nil) then
|
||||
print(val)
|
||||
found=true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
print(0)
|
||||
end
|
||||
EOF
|
||||
}
|
||||
|
||||
# тут уже немного иначе, но по сути одно и тоже
|
||||
# https://github.com/RPi-Distro/raspi-config/blob/master/raspi-config#L1136
|
||||
# $1 is 0 to disable camera, 1 to enable it
|
||||
set_camera() {
|
||||
# Stop if /boot is not a mountpoint
|
||||
#if ! mountpoint -q /boot; then
|
||||
# return 1
|
||||
#fi
|
||||
|
||||
[ -e $CONFIG ] || touch $CONFIG
|
||||
|
||||
if [ "$1" -eq 0 ]; then # disable camera
|
||||
set_config_var start_x 0 $CONFIG
|
||||
sed $CONFIG -i -e "s/^startx/#startx/"
|
||||
sed $CONFIG -i -e "s/^start_file/#start_file/"
|
||||
sed $CONFIG -i -e "s/^fixup_file/#fixup_file/"
|
||||
else # enable camera
|
||||
set_config_var start_x 1 $CONFIG
|
||||
CUR_GPU_MEM=$(get_config_var gpu_mem $CONFIG)
|
||||
if [ -z "$CUR_GPU_MEM" ] || [ "$CUR_GPU_MEM" -lt 128 ]; then
|
||||
set_config_var gpu_mem 128 $CONFIG
|
||||
fi
|
||||
sed $CONFIG -i -e "s/^startx/#startx/"
|
||||
sed $CONFIG -i -e "s/^fixup_file/#fixup_file/"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ ! -e /boot/start_x.elf ];
|
||||
then echo "Your firmware appears to be out of date (no start_x.elf). Please update"
|
||||
else set_camera 1
|
||||
fi
|
||||
|
||||
# Включение V4L драйвера http://robocraft.ru/blog/electronics/3158.html
|
||||
# 7. Enable V4L driver http://robocraft.ru/blog/electronics/3158.html
|
||||
#echo "bcm2835-v4l2" >> /etc/modules
|
||||
if ! grep -q "^bcm2835-v4l2" /etc/modules; then
|
||||
printf "bcm2835-v4l2\n" >> /etc/modules
|
||||
echo -e "\033[0;31m\033[1m$(date) | #7 Turn on v4l2 driver\033[0m\033[0m"
|
||||
if ! grep -q "^bcm2835-v4l2" /etc/modules;
|
||||
then printf "bcm2835-v4l2\n" >> /etc/modules
|
||||
fi
|
||||
|
||||
echo -e "\033[0;31m\033[1m$(date) | #5 End of configuring interfaces\033[0m\033[0m"
|
||||
echo -e "\033[0;31m\033[1m$(date) | End of configure hardware interfaces\033[0m\033[0m"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
|
||||
from YaDiskClient.YaDiskClient import YaDisk
|
||||
import os.path, sys
|
||||
import os.path, sys, json
|
||||
|
||||
def upload(_login, _password, _server_dir, _file):
|
||||
if os.path.isfile(_file):
|
||||
@@ -36,14 +36,10 @@ def main():
|
||||
|
||||
if os.path.isfile(sys.argv[1]) and os.path.isfile(sys.argv[2]):
|
||||
|
||||
from ConfigParser import SafeConfigParser
|
||||
cfgParser = SafeConfigParser()
|
||||
cfgParser.read(sys.argv[1])
|
||||
# print "login: " + cfgParser.get('yadisk','login')
|
||||
# print "password: " + cfgParser.get('yadisk','password')
|
||||
# print "server_dir: " + cfgParser.get('yadisk','server_dir')
|
||||
with open(sys.argv[1]) as json_data:
|
||||
d = json.load(json_data)
|
||||
upload(d['yadisk']['login'], d['yadisk']['password'], d['yadisk']['server_dir'], sys.argv[2])
|
||||
|
||||
upload(cfgParser.get('yadisk','login'), cfgParser.get('yadisk','password'), cfgParser.get('yadisk','server_dir'), sys.argv[2])
|
||||
else:
|
||||
print "Error: file-path or config-path is bad"
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user