1
0

23 Commits

Author SHA1 Message Date
7b6e3a9ad6 Avoid slow mirrors 2019-09-05 18:27:23 +00:00
b117739c49 Add policykit-1 to rootfs 2019-08-31 12:45:55 +00:00
b28c47e64d Fix link to Travis-CI 2019-08-31 10:56:45 +00:00
4b14187dad GitHub Actions: convert case 2019-08-31 10:53:36 +00:00
950b1e5e83 Add Ubuntu build for GitHub Actions 2019-08-31 09:28:36 +00:00
bf90a10692 Add macOS build for GitHub Actions 2019-08-31 08:28:38 +00:00
3e7c564a5a Exclude host kernel generation for macOS 2019-08-31 08:05:43 +00:00
dc73413114 Set version 2019-08-30 17:40:01 +00:00
104e70f861 Implements global timeout 2019-08-30 16:34:14 +00:00
365c9d0e95 Implements reliablity threshold for exit code 2019-08-30 16:33:43 +00:00
5bad772125 Support custom docker commands
Resolves #17
2019-08-30 00:05:50 +00:00
f3b0c07af2 Implements parameter for setting up docker registry server 2019-08-29 22:49:59 +00:00
f3d67cc3c2 Update CHANGELOG 2019-08-29 22:29:23 +00:00
12b5bd2a99 Introduce global configuration file 2019-08-29 21:12:24 +00:00
b05c44ab9d Travis-CI: migrate to travis-ci.com 2019-08-28 03:18:37 +00:00
19535fc75c Do not produce error if existing 2019-08-23 10:46:37 +00:00
5e6a9dec93 Add rootfs generator for Ubuntu 14.04 2019-08-23 10:44:16 +00:00
0f89a868bd Add brief description 2019-08-21 08:08:35 +00:00
14b8010fee Fix spelling 2019-08-21 06:16:25 +00:00
7fd8614e3c Using sed to fix spelling was not a really good idea.
Revert "Fix spelling"

This reverts commit 3d958c1e10.
2019-08-21 06:14:58 +00:00
3d958c1e10 Fix spelling 2019-08-20 23:17:23 +00:00
e4bed2a4c3 Set version 2019-08-20 22:55:56 +00:00
a9d4d64e30 Update changelog 2019-08-20 21:58:42 +00:00
19 changed files with 420 additions and 101 deletions

12
.github/workflows/macos.yml vendored Normal file
View File

@ -0,0 +1,12 @@
name: macOS
on: [push]
jobs:
build:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
- name: Build
run: go build

23
.github/workflows/ubuntu.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: Ubuntu
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Build
run: go build
- name: Install dependencies for tests
run: |
sudo apt-get update
sudo apt-get install qemu
- name: Bootstrap
run: ./tools/qemu-debian-img/bootstrap.sh
- name: Test
run: go test -parallel 1 -v ./...

View File

@ -4,7 +4,50 @@
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.1.2] 2019-09-05
### Added
- Added policykit-1 to rootfs for Ubuntu.
### Fixed
- Avoided slow mirrors with use of mirror://mirrors.ubuntu.com for
Ubuntu 16.04 and newer.
## [1.1.1] 2019-08-31
### Fixed
- macOS support.
## [1.1.0] 2019-08-30
### Added
- Global configuration file (~/.out-of-tree/out-of-tree.toml) allow to
set up default values for settings.
- rootfs generator for Ubuntu 14.04.
- Parameter for setting up docker registry server.
- Support for (distro-specific) custom docker commands that will be
executed before the base template.
- Parameter for setting up a reliability threshold for exit code.
- Parameter for setting up global timeout, after which no new tasks
will be started.
### Fixed
- Spelling in output.
- Now kernel generation will not fail if there are no directory
/lib/modules inside the container.
## [1.0.0] 2019-08-20
### Added

View File

@ -1,5 +1,5 @@
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/aba4aad2046b4d1a9a99cf98e22c018b)](https://app.codacy.com/app/jollheef/out-of-tree?utm_source=github.com&utm_medium=referral&utm_content=jollheef/out-of-tree&utm_campaign=Badge_Grade_Dashboard)
[![Build Status](https://travis-ci.org/jollheef/out-of-tree.svg?branch=master)](https://travis-ci.org/jollheef/out-of-tree)
[![Build Status](https://travis-ci.com/jollheef/out-of-tree.svg?branch=master)](https://travis-ci.com/jollheef/out-of-tree)
[![Go Report Card](https://goreportcard.com/badge/code.dumpstack.io/tools/out-of-tree)](https://goreportcard.com/report/code.dumpstack.io/tools/out-of-tree)
[![Documentation Status](https://readthedocs.org/projects/out-of-tree/badge/?version=latest)](https://out-of-tree.readthedocs.io/en/latest/?badge=latest)
[![Donate](https://img.shields.io/badge/donate-paypal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=R8W2UQPZ5X5JE&source=url)
@ -9,6 +9,8 @@
out-of-tree kernel {module, exploit} development tool
out-of-tree is for automating some routine actions for creating development environments for debugging kernel modules and exploits, generating reliability statistics for exploits, and also provides the ability to easily integrate into CI (Continuous Integration).
![Screenshot](https://cloudflare-ipfs.com/ipfs/Qmb88fgdDjbWkxz91sWsgmoZZNfVThnCtj37u3mF2s3T3T)
## Requirements

77
config/out-of-tree.go Normal file
View File

@ -0,0 +1,77 @@
// Copyright 2019 Mikhail Klementev. All rights reserved.
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
package config
import (
"os/user"
"github.com/naoina/toml"
)
type DockerCommand struct {
DistroType DistroType
Command string
}
type OutOfTree struct {
Kernels string
UserKernels string
Database string
Qemu struct {
Timeout string
}
Docker struct {
Timeout string
Registry string
// Commands that will be executed before
// the base layer of Dockerfile
Commands []DockerCommand
}
}
func ReadOutOfTreeConf(path string) (c OutOfTree, err error) {
buf, err := readFileAll(path)
if err == nil {
err = toml.Unmarshal(buf, &c)
if err != nil {
return
}
} else {
// It's ok if there's no configuration
// then we'll just set default values
err = nil
}
usr, err := user.Current()
if err != nil {
return
}
if c.Kernels == "" {
c.Kernels = usr.HomeDir + "/.out-of-tree/kernels.toml"
}
if c.UserKernels == "" {
c.UserKernels = usr.HomeDir + "/.out-of-tree/kernels.user.toml"
}
if c.Database == "" {
c.Database = usr.HomeDir + "/.out-of-tree/db.sqlite"
}
if c.Qemu.Timeout == "" {
c.Qemu.Timeout = "1m"
}
if c.Docker.Timeout == "" {
c.Docker.Timeout = "1m"
}
return
}

View File

@ -161,7 +161,7 @@ func debugHandler(kcfg config.KernelConfig, workPath, kernRegex, gdb string,
q.Debug(gdb)
coloredGdbAddress := aurora.BgGreen(aurora.Black(gdb))
fmt.Printf("[*] gdb runned on %s\n", coloredGdbAddress)
fmt.Printf("[*] gdb is listening on %s\n", coloredGdbAddress)
err = q.Start()
if err != nil {

View File

@ -54,7 +54,7 @@ Overview
$ out-of-tree debug --kernel 'Ubuntu:4.15.0-58-generic'
[*] KASLR SMEP SMAP
[*] gdb runned on tcp::1234
[*] gdb is listening on tcp::1234
[*] build result copied to /tmp/exploit
ssh -o StrictHostKeyChecking=no -p 29308 root@127.133.45.236

View File

@ -2,7 +2,7 @@
# - KERNEL: kernel headers path
# - TARGET: name of exploit binary that MUST be produced by makefile.
# - $(TARGET)_test: name of test binary that MUST be produced by makefile
# and it's will be runned on a LPE stage. TARGET_TEST MUST accept two argument:
# and it's will be executed on a LPE stage. TARGET_TEST MUST accept two argument:
# - Path to exploit binary
# - File that MUST be created with exploit. It uses for test that exploit works
# correctly.

116
kernel.go
View File

@ -19,7 +19,6 @@ import (
"time"
"github.com/naoina/toml"
"github.com/zcalusic/sysinfo"
"code.dumpstack.io/tools/out-of-tree/config"
)
@ -109,7 +108,9 @@ func vsyscallAvailable() (available bool, err error) {
return
}
func generateBaseDockerImage(sk config.KernelMask) (err error) {
func generateBaseDockerImage(registry string, commands []config.DockerCommand,
sk config.KernelMask) (err error) {
imagePath, err := dockerImagePath(sk)
if err != nil {
return
@ -128,7 +129,12 @@ func generateBaseDockerImage(sk config.KernelMask) (err error) {
sk.DistroType.String(), sk.DistroRelease)
os.MkdirAll(imagePath, os.ModePerm)
d += fmt.Sprintf("FROM %s:%s\n",
d += "FROM "
if registry != "" {
d += registry + "/"
}
d += fmt.Sprintf("%s:%s\n",
strings.ToLower(sk.DistroType.String()),
sk.DistroRelease,
)
@ -138,16 +144,38 @@ func generateBaseDockerImage(sk config.KernelMask) (err error) {
return
}
for _, c := range commands {
switch c.DistroType {
case config.Ubuntu:
d += "RUN " + c.Command + "\n"
case config.CentOS:
d += "RUN " + c.Command + "\n"
case config.Debian:
d += "RUN " + c.Command + "\n"
default:
err = fmt.Errorf("%s not yet supported",
sk.DistroType.String())
return
}
}
switch sk.DistroType {
case config.Ubuntu:
d += "ENV DEBIAN_FRONTEND=noninteractive\n"
if sk.DistroRelease >= "16.04" {
from := "http://.*ubuntu/"
to := "mirror://mirrors.ubuntu.com/mirrors.txt"
file := "/etc/apt/sources.list"
s := fmt.Sprintf("sed -i 's;%s;%s;' %s", from, to, file)
d += "RUN " + s + "\n"
}
d += "RUN apt-get update\n"
d += "RUN apt-get install -y build-essential libelf-dev\n"
d += "RUN apt-get install -y wget git\n"
if sk.DistroRelease >= "14.04" {
d += "RUN apt-get install -y libseccomp-dev\n"
}
d += "RUN mkdir /lib/modules\n"
d += "RUN mkdir -p /lib/modules\n"
case config.CentOS:
if sk.DistroRelease < "7" && !vsyscall {
log.Println("Old CentOS requires `vsyscall=emulate` " +
@ -397,66 +425,6 @@ func listDockerImages() (diis []dockerImageInfo, err error) {
return
}
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
si := sysinfo.SysInfo{}
si.GetSysInfo()
distroType, err := config.NewDistroType(si.OS.Vendor)
if err != nil {
return
}
cmd := exec.Command("ls", "/lib/modules")
rawOutput, err := cmd.CombinedOutput()
if err != nil {
log.Println(string(rawOutput), err)
return
}
kernelsBase := "/boot/"
files, err := ioutil.ReadDir(kernelsBase)
if err != nil {
return
}
// only for compatibility, docker is not really used
dii := dockerImageInfo{
ContainerName: config.KernelMask{
DistroType: distroType,
DistroRelease: si.OS.Version,
}.DockerName(),
}
rootfs, err := genRootfsImage(dii, download)
if err != nil {
return
}
for _, k := range strings.Fields(string(rawOutput)) {
ki := config.KernelInfo{
DistroType: distroType,
DistroRelease: si.OS.Version,
KernelRelease: k,
KernelSource: "/lib/modules/" + k + "/build",
KernelPath: kernelsBase + genKernelPath(files, k),
InitrdPath: kernelsBase + genInitrdPath(files, k),
RootFS: rootfs,
}
vmlinux := "/usr/lib/debug/boot/vmlinux-" + k
log.Println("vmlinux", vmlinux)
if exists(vmlinux) {
ki.VmlinuxPath = vmlinux
}
kcfg.Kernels = append(kcfg.Kernels, ki)
}
return
}
func updateKernelsCfg(host, download bool) (err error) {
newkcfg := config.KernelConfig{}
@ -573,7 +541,10 @@ func shuffle(a []string) []string {
return a
}
func generateKernels(km config.KernelMask, max int64, download bool) (err error) {
func generateKernels(km config.KernelMask, registry string,
commands []config.DockerCommand, max int64,
download bool) (err error) {
log.Println("Generating for kernel mask", km)
_, err = genRootfsImage(dockerImageInfo{ContainerName: km.DockerName()},
@ -582,7 +553,7 @@ func generateKernels(km config.KernelMask, max int64, download bool) (err error)
return
}
err = generateBaseDockerImage(km)
err = generateBaseDockerImage(registry, commands, km)
if err != nil {
return
}
@ -632,7 +603,10 @@ func generateKernels(km config.KernelMask, max int64, download bool) (err error)
return
}
func kernelAutogenHandler(workPath string, max int64, host, download bool) (err error) {
func kernelAutogenHandler(workPath, registry string,
commands []config.DockerCommand,
max int64, host, download bool) (err error) {
ka, err := config.ReadArtifactConfig(workPath + "/.out-of-tree.toml")
if err != nil {
return
@ -644,7 +618,7 @@ func kernelAutogenHandler(workPath string, max int64, host, download bool) (err
return
}
err = generateKernels(sk, max, download)
err = generateKernels(sk, registry, commands, max, download)
if err != nil {
return
}
@ -695,7 +669,9 @@ func kernelDockerRegenHandler(host, download bool) (err error) {
return updateKernelsCfg(host, download)
}
func kernelGenallHandler(distro, version string, host, download bool) (err error) {
func kernelGenallHandler(distro, version, registry string,
commands []config.DockerCommand, host, download bool) (err error) {
distroType, err := config.NewDistroType(distro)
if err != nil {
return
@ -706,7 +682,7 @@ func kernelGenallHandler(distro, version string, host, download bool) (err error
DistroRelease: version,
ReleaseMask: ".*",
}
err = generateKernels(km, kernelsAll, download)
err = generateKernels(km, registry, commands, kernelsAll, download)
if err != nil {
return
}

77
kernel_linux.go Normal file
View File

@ -0,0 +1,77 @@
// Copyright 2018 Mikhail Klementev. All rights reserved.
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
// +build linux
package main
import (
"io/ioutil"
"log"
"os/exec"
"strings"
"code.dumpstack.io/tools/out-of-tree/config"
"github.com/zcalusic/sysinfo"
)
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
si := sysinfo.SysInfo{}
si.GetSysInfo()
distroType, err := config.NewDistroType(si.OS.Vendor)
if err != nil {
return
}
cmd := exec.Command("ls", "/lib/modules")
rawOutput, err := cmd.CombinedOutput()
if err != nil {
log.Println(string(rawOutput), err)
return
}
kernelsBase := "/boot/"
files, err := ioutil.ReadDir(kernelsBase)
if err != nil {
return
}
// only for compatibility, docker is not really used
dii := dockerImageInfo{
ContainerName: config.KernelMask{
DistroType: distroType,
DistroRelease: si.OS.Version,
}.DockerName(),
}
rootfs, err := genRootfsImage(dii, download)
if err != nil {
return
}
for _, k := range strings.Fields(string(rawOutput)) {
ki := config.KernelInfo{
DistroType: distroType,
DistroRelease: si.OS.Version,
KernelRelease: k,
KernelSource: "/lib/modules/" + k + "/build",
KernelPath: kernelsBase + genKernelPath(files, k),
InitrdPath: kernelsBase + genInitrdPath(files, k),
RootFS: rootfs,
}
vmlinux := "/usr/lib/debug/boot/vmlinux-" + k
log.Println("vmlinux", vmlinux)
if exists(vmlinux) {
ki.VmlinuxPath = vmlinux
}
kcfg.Kernels = append(kcfg.Kernels, ki)
}
return
}

18
kernel_macos.go Normal file
View File

@ -0,0 +1,18 @@
// Copyright 2018 Mikhail Klementev. All rights reserved.
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
// +build darwin
package main
import (
"errors"
"code.dumpstack.io/tools/out-of-tree/config"
)
func genHostKernels(download bool) (kcfg config.KernelConfig, err error) {
err = errors.New("generate host kernels for macOS is not supported")
return
}

45
main.go
View File

@ -84,7 +84,7 @@ func main() {
)
app.Author("Mikhail Klementev <root@dumpstack.io>")
app.Version("0.2.0")
app.Version("1.1.2")
pathFlag := app.Flag("path", "Path to work directory")
path := pathFlag.Default(".").ExistingDir()
@ -95,25 +95,36 @@ func main() {
}
os.MkdirAll(usr.HomeDir+"/.out-of-tree", os.ModePerm)
defaultKcfgPath := usr.HomeDir + "/.out-of-tree/kernels.toml"
confPath := usr.HomeDir + "/.out-of-tree/out-of-tree.toml"
conf, err := config.ReadOutOfTreeConf(confPath)
if err != nil {
return
}
kcfgPathFlag := app.Flag("kernels", "Path to main kernels config")
kcfgPath := kcfgPathFlag.Default(defaultKcfgPath).String()
kcfgPath := kcfgPathFlag.Default(conf.Kernels).String()
defaultDbPath := usr.HomeDir + "/.out-of-tree/db.sqlite"
dbPathFlag := app.Flag("db", "Path to database")
dbPath := dbPathFlag.Default(defaultDbPath).String()
dbPath := dbPathFlag.Default(conf.Database).String()
defaultUserKcfgPath := usr.HomeDir + "/.out-of-tree/kernels.user.toml"
userKcfgPathFlag := app.Flag("user-kernels", "User kernels config")
userKcfgPathEnv := userKcfgPathFlag.Envar("OUT_OF_TREE_KCFG")
userKcfgPath := userKcfgPathEnv.Default(defaultUserKcfgPath).String()
userKcfgPath := userKcfgPathEnv.Default(conf.UserKernels).String()
timeoutFlag := app.Flag("timeout", "Timeout after tool will not spawn new tests")
timeout := timeoutFlag.Duration()
qemuTimeoutFlag := app.Flag("qemu-timeout", "Timeout for qemu")
qemuTimeout := qemuTimeoutFlag.Default("1m").Duration()
qemuTimeout := qemuTimeoutFlag.Default(conf.Qemu.Timeout).Duration()
dockerTimeoutFlag := app.Flag("docker-timeout", "Timeout for docker")
dockerTimeout := dockerTimeoutFlag.Default("1m").Duration()
dockerTimeout := dockerTimeoutFlag.Default(conf.Docker.Timeout).Duration()
dockerRegistryFlag := app.Flag("docker-registry", "Registry for docker")
dockerRegistry := dockerRegistryFlag.Default(conf.Docker.Registry).String()
thresholdFlag := app.Flag("threshold", "Reliablity threshold for exit code")
threshold := thresholdFlag.Default("1.00").Float64()
pewCommand := app.Command("pew", "Build, run and test module/exploit")
@ -279,20 +290,27 @@ func main() {
}
defer db.Close()
stop := time.Time{} // never stop
if *timeout != 0 {
stop = time.Now().Add(*timeout)
}
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
case pewCommand.FullCommand():
err = pewHandler(kcfg, *path, *pewKernel, *pewBinary,
*pewTest, *pewGuess, *qemuTimeout, *dockerTimeout,
*pewTest, *pewGuess, stop, *qemuTimeout, *dockerTimeout,
*pewMax, *pewRuns, *pewDist, *pewTag, *pewThreads, db)
case kernelListCommand.FullCommand():
err = kernelListHandler(kcfg)
case kernelAutogenCommand.FullCommand():
err = kernelAutogenHandler(*path, *kernelAutogenMax,
err = kernelAutogenHandler(*path, *dockerRegistry,
conf.Docker.Commands, *kernelAutogenMax,
*kernelUseHost, !*kernelNoDownload)
case kernelDockerRegenCommand.FullCommand():
err = kernelDockerRegenHandler(*kernelUseHost, !*kernelNoDownload)
case kernelGenallCommand.FullCommand():
err = kernelGenallHandler(*distro, *version,
*dockerRegistry, conf.Docker.Commands,
*kernelUseHost, !*kernelNoDownload)
case genModuleCommand.FullCommand():
err = genConfig(config.KernelModule)
@ -316,7 +334,8 @@ func main() {
case logMarkdownCommand.FullCommand():
err = logMarkdownHandler(db, *path, *logMarkdownTag)
case packCommand.FullCommand():
err = packHandler(db, *path, kcfg, *packAutogen,
err = packHandler(db, *path, *dockerRegistry, stop,
conf.Docker.Commands, kcfg, *packAutogen,
!*packNoDownload, *packExploitRuns, *packKernelRuns)
}
@ -324,7 +343,7 @@ func main() {
log.Fatalln(err)
}
if somethingFailed {
if successRate(state) < *threshold {
os.Exit(1)
}
}

View File

@ -15,7 +15,8 @@ import (
"code.dumpstack.io/tools/out-of-tree/config"
)
func packHandler(db *sql.DB, path string, kcfg config.KernelConfig,
func packHandler(db *sql.DB, path, registry string, stop time.Time,
commands []config.DockerCommand, kcfg config.KernelConfig,
autogen, download bool, exploitRuns, kernelRuns int64) (err error) {
dockerTimeout := time.Minute
@ -39,7 +40,8 @@ func packHandler(db *sql.DB, path string, kcfg config.KernelConfig,
if autogen {
var perRegex int64 = 1
err = kernelAutogenHandler(workPath, perRegex, false, download)
err = kernelAutogenHandler(workPath, registry,
commands, perRegex, false, download)
if err != nil {
return
}
@ -48,7 +50,7 @@ func packHandler(db *sql.DB, path string, kcfg config.KernelConfig,
log.Println(f.Name())
pewHandler(kcfg, workPath, "", "", "", false,
dockerTimeout, qemuTimeout,
stop, dockerTimeout, qemuTimeout,
kernelRuns, exploitRuns, pathDevNull, tag, threads, db)
}

27
pew.go
View File

@ -26,7 +26,17 @@ import (
"code.dumpstack.io/tools/out-of-tree/qemu"
)
var somethingFailed = false
type runstate struct {
Overall, Success float64
}
var (
state runstate
)
func successRate(state runstate) float64 {
return state.Success / state.Overall
}
const pathDevNull = "/dev/null"
@ -134,11 +144,12 @@ func testKernelExploit(q *qemu.System, ka config.Artifact,
}
func genOkFail(name string, ok bool) (aurv aurora.Value) {
state.Overall += 1
if ok {
state.Success += 1
s := " " + name + " SUCCESS "
aurv = aurora.BgGreen(aurora.Black(s))
} else {
somethingFailed = true
s := " " + name + " FAILURE "
aurv = aurora.BgRed(aurora.Gray(aurora.Bold(s)))
}
@ -380,7 +391,8 @@ func shuffleKernels(a []config.KernelInfo) []config.KernelInfo {
}
func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
testPath string, qemuTimeout, dockerTimeout time.Duration,
testPath string, stop time.Time,
qemuTimeout, dockerTimeout time.Duration,
max, runs int64, dist, tag string, threads int,
db *sql.DB) (err error) {
@ -402,6 +414,9 @@ func performCI(ka config.Artifact, kcfg config.KernelConfig, binaryPath,
found = true
max--
for i := int64(0); i < runs; i++ {
if !stop.IsZero() && time.Now().After(stop) {
break
}
swg.Add()
go whatever(&swg, ka, kernel, binaryPath,
testPath, qemuTimeout, dockerTimeout,
@ -457,9 +472,10 @@ func genAllKernels() (sk []config.KernelMask, err error) {
return
}
// TODO: Now too many parameters, move all of them to some structure
func pewHandler(kcfg config.KernelConfig,
workPath, ovrrdKrnl, binary, test string, guess bool,
qemuTimeout, dockerTimeout time.Duration,
stop time.Time, qemuTimeout, dockerTimeout time.Duration,
max, runs int64, dist, tag string, threads int,
db *sql.DB) (err error) {
@ -489,7 +505,8 @@ func pewHandler(kcfg config.KernelConfig,
}
}
err = performCI(ka, kcfg, binary, test, qemuTimeout, dockerTimeout,
err = performCI(ka, kcfg, binary, test,
stop, qemuTimeout, dockerTimeout,
max, runs, dist, tag, threads, db)
if err != nil {
return

View File

@ -60,7 +60,7 @@ type Kernel struct {
InitrdPath string
}
// System describe qemu parameters and runned process
// System describe qemu parameters and executed process
type System struct {
arch arch
kernel Kernel
@ -86,7 +86,7 @@ type System struct {
Died bool
sshAddrPort string
// accessible while qemu is runned
// accessible while qemu is running
cmd *exec.Cmd
pipe struct {
stdin io.WriteCloser

View File

@ -47,7 +47,7 @@ ENV IMAGE=/shared/out_of_tree_centos_7.img
RUN mkdir $IMAGEDIR
# Must be runned with --privileged because of /dev/loop
# Must be executed with --privileged because of /dev/loop
CMD qemu-img create $IMAGE 2G && \
mkfs.ext4 -F $IMAGE && \
mount -o loop $IMAGE $IMAGEDIR && \

View File

@ -0,0 +1,35 @@
# Copyright 2018 Mikhail Klementev. All rights reserved.
# Use of this source code is governed by a AGPLv3 license
# (or later) that can be found in the LICENSE file.
#
# Usage:
#
# $ docker build -t gen-ubuntu1404-image .
# $ docker run --privileged -v $(pwd):/shared -t gen-ubuntu1404-image
#
# ubuntu1404.img will be created in current directory. You can change $(pwd) to
# different directory to use different destination for image.
#
FROM ubuntu:14.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update
RUN apt-get install -y debootstrap qemu
ENV TMPDIR=/tmp/ubuntu
ENV IMAGEDIR=/tmp/image
ENV IMAGE=/shared/out_of_tree_ubuntu_14__04.img
ENV REPOSITORY=http://archive.ubuntu.com/ubuntu
ENV RELEASE=trusty
RUN mkdir $IMAGEDIR
# Must be executed with --privileged because of /dev/loop
CMD debootstrap --include=openssh-server,policykit-1 \
$RELEASE $TMPDIR $REPOSITORY && \
/shared/setup.sh $TMPDIR && \
qemu-img create $IMAGE 2G && \
mkfs.ext4 -F $IMAGE && \
mount -o loop $IMAGE $IMAGEDIR && \
cp -a $TMPDIR/* $IMAGEDIR/ && \
umount $IMAGEDIR

View File

@ -0,0 +1,17 @@
#!/bin/sh -eux
# Copyright 2018 Mikhail Klementev. All rights reserved.
# Use of this source code is governed by a AGPLv3 license
# (or later) that can be found in the LICENSE file.
TMPDIR=$1
chroot $TMPDIR /bin/sh -c 'useradd -m user'
sed -i 's/root:\*:/root::/' $TMPDIR/etc/shadow
sed -i 's/user:!!:/user::/' $TMPDIR/etc/shadow
echo auth sufficient pam_permit.so > $TMPDIR/etc/pam.d/sshd
sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
echo '#!/bin/sh' > $TMPDIR/etc/rc.local
echo 'dhclient eth0' >> $TMPDIR/etc/rc.local
chmod +x $TMPDIR/etc/rc.local

View File

@ -25,8 +25,9 @@ ENV RELEASE=bionic
RUN mkdir $IMAGEDIR
# Must be runned with --privileged because of /dev/loop
CMD debootstrap --include=openssh-server $RELEASE $TMPDIR $REPOSITORY && \
# Must be executed with --privileged because of /dev/loop
CMD debootstrap --include=openssh-server,policykit-1 \
$RELEASE $TMPDIR $REPOSITORY && \
/shared/setup.sh $TMPDIR && \
qemu-img create $IMAGE 2G && \
mkfs.ext4 -F $IMAGE && \