Add qemu stdout/stderr to log; Implements database versioning
This commit is contained in:
		
							
								
								
									
										98
									
								
								db.go
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								db.go
									
									
									
									
									
								
							@@ -6,6 +6,8 @@ package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	_ "github.com/mattn/go-sqlite3"
 | 
			
		||||
@@ -14,6 +16,10 @@ import (
 | 
			
		||||
	"code.dumpstack.io/tools/out-of-tree/qemu"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const CURRENT_DATABASE_VERSION = 1
 | 
			
		||||
 | 
			
		||||
const VERSION_FIELD = "db_version"
 | 
			
		||||
 | 
			
		||||
type logEntry struct {
 | 
			
		||||
	ID        int
 | 
			
		||||
	Timestamp time.Time
 | 
			
		||||
@@ -46,12 +52,71 @@ func createLogTable(db *sql.DB) (err error) {
 | 
			
		||||
		test_output	TEXT,
 | 
			
		||||
		test_ok		BOOLEAN,
 | 
			
		||||
 | 
			
		||||
		qemu_stdout	TEXT,
 | 
			
		||||
		qemu_stderr	TEXT,
 | 
			
		||||
 | 
			
		||||
		kernel_panic	BOOLEAN,
 | 
			
		||||
		timeout_kill	BOOLEAN
 | 
			
		||||
	)`)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createMetadataTable(db *sql.DB) (err error) {
 | 
			
		||||
	_, err = db.Exec(`
 | 
			
		||||
	CREATE TABLE IF NOT EXISTS metadata (
 | 
			
		||||
		id	INTEGER PRIMARY KEY,
 | 
			
		||||
		key	TEXT,
 | 
			
		||||
		value	TEXT
 | 
			
		||||
	)`)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func metaChkValue(db *sql.DB, key string) (exist bool, err error) {
 | 
			
		||||
	sql := "SELECT EXISTS(SELECT id FROM metadata WHERE key = $1)"
 | 
			
		||||
	stmt, err := db.Prepare(sql)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer stmt.Close()
 | 
			
		||||
 | 
			
		||||
	err = stmt.QueryRow(key).Scan(&exist)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func metaGetValue(db *sql.DB, key string) (value string, err error) {
 | 
			
		||||
	stmt, err := db.Prepare("SELECT value FROM metadata " +
 | 
			
		||||
		"WHERE key = $1")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer stmt.Close()
 | 
			
		||||
 | 
			
		||||
	err = stmt.QueryRow(key).Scan(&value)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func metaSetValue(db *sql.DB, key, value string) (err error) {
 | 
			
		||||
	stmt, err := db.Prepare("INSERT INTO metadata " +
 | 
			
		||||
		"(key, value) VALUES ($1, $2)")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer stmt.Close()
 | 
			
		||||
 | 
			
		||||
	_, err = stmt.Exec(key, value)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getVersion(db *sql.DB) (version int, err error) {
 | 
			
		||||
	s, err := metaGetValue(db, VERSION_FIELD)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	version, err = strconv.Atoi(s)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func addToLog(db *sql.DB, q *qemu.QemuSystem, ka config.Artifact,
 | 
			
		||||
	ki config.KernelInfo, res *phasesResult) (err error) {
 | 
			
		||||
 | 
			
		||||
@@ -60,9 +125,10 @@ func addToLog(db *sql.DB, q *qemu.QemuSystem, ka config.Artifact,
 | 
			
		||||
		"build_output, build_ok, " +
 | 
			
		||||
		"run_output, run_ok, " +
 | 
			
		||||
		"test_output, test_ok, " +
 | 
			
		||||
		"qemu_stdout, qemu_stderr, " +
 | 
			
		||||
		"kernel_panic, timeout_kill) " +
 | 
			
		||||
		"VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, " +
 | 
			
		||||
		"$10, $11, $12, $13);")
 | 
			
		||||
		"$10, $11, $12, $13, $14, $15);")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@@ -75,6 +141,7 @@ func addToLog(db *sql.DB, q *qemu.QemuSystem, ka config.Artifact,
 | 
			
		||||
		res.Build.Output, res.Build.Ok,
 | 
			
		||||
		res.Run.Output, res.Run.Ok,
 | 
			
		||||
		res.Test.Output, res.Test.Ok,
 | 
			
		||||
		q.Stdout, q.Stderr,
 | 
			
		||||
		q.KernelPanic, q.KilledByTimeout,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -161,6 +228,7 @@ func getLogByID(db *sql.DB, id int) (le logEntry, err error) {
 | 
			
		||||
		"distro_type, distro_release, kernel_release, " +
 | 
			
		||||
		"build_ok, run_ok, test_ok, " +
 | 
			
		||||
		"build_output, run_output, test_output, " +
 | 
			
		||||
		"qemu_stdout, qemu_stderr, " +
 | 
			
		||||
		"kernel_panic, timeout_kill " +
 | 
			
		||||
		"FROM log WHERE id=$1")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -173,12 +241,18 @@ func getLogByID(db *sql.DB, id int) (le logEntry, err error) {
 | 
			
		||||
		&le.DistroType, &le.DistroRelease, &le.KernelRelease,
 | 
			
		||||
		&le.Build.Ok, &le.Run.Ok, &le.Test.Ok,
 | 
			
		||||
		&le.Build.Output, &le.Run.Output, &le.Test.Output,
 | 
			
		||||
		&le.Stdout, &le.Stderr,
 | 
			
		||||
		&le.KernelPanic, &le.KilledByTimeout,
 | 
			
		||||
	)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createSchema(db *sql.DB) (err error) {
 | 
			
		||||
	err = createMetadataTable(db)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = createLogTable(db)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
@@ -193,10 +267,30 @@ func openDatabase(path string) (db *sql.DB, err error) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = createSchema(db)
 | 
			
		||||
	db.SetMaxOpenConns(1)
 | 
			
		||||
 | 
			
		||||
	exists, _ := metaChkValue(db, VERSION_FIELD)
 | 
			
		||||
	if !exists {
 | 
			
		||||
		err = createSchema(db)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		err = metaSetValue(db, VERSION_FIELD,
 | 
			
		||||
			strconv.Itoa(CURRENT_DATABASE_VERSION))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	version, err := getVersion(db)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if version != CURRENT_DATABASE_VERSION {
 | 
			
		||||
		err = fmt.Errorf("Database is not supported (%d instead of %d)",
 | 
			
		||||
			version, CURRENT_DATABASE_VERSION)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user