summaryrefslogblamecommitdiffstats
path: root/dmt/dmt
blob: 05445963e743e058d03432d5a93811deabec62f9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10





                                                                                
                                  


                                
                
 









                                                                           



                                     




                                                                                 



                                                          




                                                     







                                                



                                                                            












                                                           

















                                                              
                                                               


      









                                                  















                                             




                                             




                                             


                                     



                                            




                                            
    
#!/bin/bash -a

# cychedelic DMT daemon
# cychedelic is an automated Continuous Deployment solution.  See the README for
# more information.

CYCHE_SERVICE_DIR="/data/services"
CYCHE_LOG_DIR="/data/logs"
CYCHE_STATUS_FILE="/data/status"
CYCHE_VERSION_FILE="/version"
source config.sh

sane_path_info() {
    # Permit only '-_./' and alphanumeric, as in "/Foo/bar_baz/ex-420.txt".
    # Fail if any ".." or "//" is detected to prevent bad file access.
    # Final path info is split on '/' for easy forming into an array.
    ( (! echo "$PATH_INFO" | grep -Eq '^[-_\.\/A-Za-z0-9]+$') \
        || (! echo "$PATH_INFO" | grep -Evq '\.\.|//') ) \
        && exit 1
    echo "$PATH_INFO" | sed 's/\// /g'
}

integer() {
    [ "$1" -eq "$1" ] >/dev/null 2>&1
}

escape_html() {
    sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&#39;/g'
}

escape_json() {
    sed 's/\\/\\\\/g; s/\r/\\r/g; s/\t/\\t/g; s/"/\\"/g' \
        | awk '{printf "%s\\n", $0}'
}

template() {
    [ -n "$2" ] && printf 'Content-type: %s\n\n' "$2"
    template.awk "$1" | bash
}

newest_job() {
    ls -A "$CYCHE_LOG_DIR" | sort -rn | head -n1
}

oldest_job() {
    ls -A "$CYCHE_LOG_DIR" | sort -n | head -n1
}

log_tail() {
    tail -n "$CYCHE_LOG_TAIL_LENGTH" "$CYCHE_LOG_DIR/$1/log" | sed 's/\r//g'
}

api_status() {
    status=$(cat "$CYCHE_STATUS_FILE")
    [ "$status" == "" ] && active="false" || active="true"
    integer "$status" && job="$status" || job="-1"

    printf 'Content-type: text/json\n\n{'
    printf '"version":"%s",' "$(cat "$CYCHE_VERSION_FILE")"
    printf '"active":%s,' "$active"
    printf '"job":%i,' "$job"
    printf '"newest":%i,' "$(newest_job)"
    printf '"oldest":%i}' "$(oldest_job)"
}

api_job() {
    [ -z "$1" ] && job="$(newest_job)" || job="$1"
    jobdir="$CYCHE_LOG_DIR/$job"

    if [ -d "$jobdir" ]; then
        status=$(cat "$CYCHE_STATUS_FILE")

        result=$( ([ "$status" == "$job" ] && echo "active") \
            || ([ -f "$jobdir/fail" ] && echo "fail") \
            || echo "pass" )

        printf 'Content-type: text/json\n\n{'
        printf '"job":%i,' "$job"
        printf '"hash":"%s",' "$(cat "$jobdir/hash")"
        printf '"reason":"%s",' "$(cat "$jobdir/reason")"
        printf '"service":"%s",' "$(cat "$jobdir/service")"
        printf '"time":%i,' "$(cat "$jobdir/time")"
        printf '"result":"%s",' "$result"
        printf '"log":"%s"}' "$(log_tail "$job" | escape_json)"
    fi
}

api_log() {
    [ -z "$1" ] && job="$(newest_job)" || job="$1"
    jobdir="$CYCHE_LOG_DIR/$job"

    if [ -d "$jobdir" ]; then
        printf 'Content-type: text/plain\n\n'
        cat "$jobdir/log"
    fi
}

route=($(sane_path_info)) || exit 1

case ${route[0]} in
    "api")
        case ${route[1]} in
            "status") api_status ;;
            "job") api_job "${route[2]}" ;;
            "log") api_log "${route[2]}" ;;
        esac
        ;;

    "")
        page_template="html/jobs.html"
        template "html/master.html" text/html
        ;;

    "services")
        page_template="html/services.html"
        template "html/master.html" text/html
        ;;

    "stats")
        page_template="html/stats.html"
        template "html/master.html" text/html
        ;;

    "style.css")
        template "style.css" text/css
        ;;

    "script.js")
        template "script.js" text/javascript
        ;;

    "favicon.png")
        printf 'Content-type: image/png\n\n'
        cat "favicon.png"
        ;;
esac