Autoupdater ГИТ


В моем офисе у нас есть инструмент внутреннего мониторинга мы используем в системах клиента, чтобы отслеживать различные показатели и сообщите нам через слабину. Наши ведут разработки и главный архитектор очень параноидальный о Git и наотрез отказываются ставить его на системах поддержки, но они по-прежнему нравится идея использовать его для развития.

Поэтому я создал скрипт autoupdater для Наш инструмент мониторинга, которая позволяет внесения изменений в Git, и средство автоматического обновления из репозитория без необходимости ставить Git на системы.

Это написано в PHP, так как это основной язык в использования в офисе (в частности, 5.3.3, хотя один из наших разработчиков работает над написанием технического задания для обновления до 5.6), и он использует API Гитлаб на наших собственных внутренних гитлаб узла.

Я также отправил несколько деталей по причинам конфиденциальности, например файл config не называется config.confи эта служба не называется tool.

<?php
//Until config can be loaded, assume _LOC is the directory of this script
$_LOC = realpath(dirname(__FILE__)).'/';

//Look for config file
echo "Searching for ".$_LOC."config/config.conf\n";
if (!file_exists($_LOC.'config/config.conf')) {
    echo "Searching for ".$_LOC."config/config.template.conf\n";
    if (!file_exists($_LOC.'config/config.template.conf')) {
        exit('Config file does not exist and template was not found!');
    }

    //Create config from template
    echo "Template exists, creating config file\n";
    copy($_LOC.'config/config.template.conf', $_LOC.'config/config.conf');
}

//Imports
require($_LOC.'lib/functions.php');
require($_LOC.'config/config.conf');
require('/etc/casper/defaults.conf');

if ($_DEBUG) echo "Starting update check\n";

if ($_DEBUG) echo "Fetching commits\n";
//Fetch all commits for set branch, default sorted by newest first
$commitsjson = gitlab_fetch("projects/$_GIT_ID/repository/commits", array('ref' => $_GIT_BRANCH));
$commits = json_decode($commitsjson);
$lastcommit = $commits[0];
$lastcommit = $lastcommit->id;

if ($_DEBUG) echo "Latest commit is ".$lastcommit."\n";
if ($lastcommit !== $_UPDATE_SHA) {
    if ($_DEBUG) echo "But current update is ".$_UPDATE_SHA."\nUpdating...";
    //Fetch recursive tree of all files and directories
    $filejson = gitlab_fetch("projects/$_GIT_ID/repository/tree", array('recursive' => 'true', 'ref' => $_GIT_BRANCH));
    $fileinfo = json_decode($filejson);

    //Create backup directory
    $bakdate = date('Ymd');
    $bakloc = $_LOC.'bak'.$bakdate.'/';
    mkdir($bakloc);

    $files = array();
    $dirs  = array();
    //Format each file to url to fetch file contents and filter directories to separate array
    foreach($fileinfo as $file) {
        if ($file->type == "blob")
            $files[$file->path] = "projects/$_GIT_ID/repository/files/".$file->path;
        else if ($file->type == "tree")
            $dirs[] = $file->path;
    }
    //Create directories
    foreach($dirs as $dir) {
        if ($_DEBUG) echo "Creating directory $dir\n";
        if (!file_exists($_LOC.$dir)) mkdir($_LOC.$dir);
        else mkdir($bakloc.$dir);
    }
    //Fetch files
    foreach($files as $path => $fileapi) {
        if ($_DEBUG) echo "Fetching $path\n";
        //Fetch json
        $fileraw = gitlab_fetch($fileapi, array('ref' => $_GIT_BRANCH));
        $fileobj = json_decode($fileraw);
        //If content is set, file was successfully pulled
        if (isset($fileobj->content)) {
            //content is provided in base64, need to decode
            $filecontent = base64_decode($fileobj->content);
            if ($_DEBUG) echo "Fetched ".strlen($fileobj->content)." bytes, decoded into ".strlen($filecontent)." bytes\n";
            //Backup file if it already exists
            if (file_exists($_LOC.$path)) {
                if ($_DEBUG) echo "Backing up $_LOC$path to $bakloc$path\n";
                copy($_LOC.$path, $bakloc.$path);
            }
            if ($_DEBUG) echo "Overwriting $_LOC$path\n";
            file_put_contents($_LOC.$path, $filecontent);
            if ($_DEBUG) echo "Done\n";
        //If message is set, an error was returned
        } else if (isset($fileobj->message)) {
            //Output the error
            if ($_DEBUG) echo "Failed to download $path with response ".$fileobj->message."\n";
        }
    }

    //Update the commit hash
    if ($_DEBUG) echo "Updating commit hash\n";
    file_put_contents($_LOC.'config/update-hash', $lastcommit);
    if ($_DEBUG) echo "Restarting tool...\n";
    //Log restart in slack, and restart service
    slack_pretty_log('Tool Updated', "Tool $_VERSION has updated! Restarting...", 'good');
    $output = shell_exec('sudo /etc/init.d/tool restart 2>&1');
    if ($_DEBUG) echo $output;
    //End
} else {
    if ($_DEBUG) echo "No new updates\n";
}

Такие функции, как slack_pretty_log и gitlab_fetch определены извне и использовать соответствующие API-интерфейсы, и все переменные, начинающиеся с подчеркивания (например, $_DEBUG и $_GIT_BRANCH) определены в файле config.

Я в основном заинтересованы в обратной связи на потоке логики, а также именования (который я правда не делают большую работу, придерживаясь) и комментарии.

Это автономный скрипт, предназначенный для запуска один раз в день по расписанию, поэтому в ней много логики, вне какой-либо функции или классы.



122
1
задан 7 февраля 2018 в 04:02 Источник Поделиться
Комментарии
1 ответ

Зачем ты повторил if ($_DEBUG) echo в миллион раз? Что умоляет, чтобы быть вложенными в debug() функция.

Каждый раз, когда вы хотите оставить комментарий с блока логики под ним, что должен быть метод (по имени какого комментария говорит).

1
ответ дан 7 февраля 2018 в 05:02 Источник Поделиться