Compare commits
26 Commits
4e3313b6db
...
master
Author | SHA1 | Date | |
---|---|---|---|
fb536f5292
|
|||
82f186fe71
|
|||
8999a65f4e
|
|||
426bd3864a
|
|||
e6ae8a9c2f
|
|||
82e03b79fc
|
|||
081b534bd2
|
|||
eb04c74c1b
|
|||
8f34ec0be0
|
|||
2daa111196
|
|||
48854bf40d
|
|||
8d0941b406
|
|||
bd0160aa85
|
|||
1a0578c541
|
|||
2df0d81782
|
|||
77547cedce
|
|||
24ec99bacd
|
|||
354b1cbedd
|
|||
e96cfac95c
|
|||
9bb15afa21
|
|||
27abdc3687
|
|||
c53e0cc99b
|
|||
ef4a9364a1
|
|||
0bc66ec025
|
|||
1814fe1144
|
|||
77442a31b1
|
5
.github/workflows/e2e.yml
vendored
5
.github/workflows/e2e.yml
vendored
@ -14,6 +14,7 @@ on:
|
|||||||
- ".github/workflows/macos.yml"
|
- ".github/workflows/macos.yml"
|
||||||
- ".github/workflows/debian-cache.yml"
|
- ".github/workflows/debian-cache.yml"
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
|
- 'tools/**'
|
||||||
- ".readthedocs.yaml"
|
- ".readthedocs.yaml"
|
||||||
- "README.md"
|
- "README.md"
|
||||||
|
|
||||||
@ -125,7 +126,7 @@ jobs:
|
|||||||
echo 'distro = { id = "${{ matrix.os.distro }}", release = "${{ matrix.os.release }}" }' >> examples/kernel-module/.out-of-tree.toml
|
echo 'distro = { id = "${{ matrix.os.distro }}", release = "${{ matrix.os.release }}" }' >> examples/kernel-module/.out-of-tree.toml
|
||||||
echo 'kernel = { regex = ".*" }' >> examples/kernel-module/.out-of-tree.toml
|
echo 'kernel = { regex = ".*" }' >> examples/kernel-module/.out-of-tree.toml
|
||||||
echo '[qemu]' >> examples/kernel-module/.out-of-tree.toml
|
echo '[qemu]' >> examples/kernel-module/.out-of-tree.toml
|
||||||
echo 'timeout = "10m"' >> examples/kernel-module/.out-of-tree.toml
|
echo 'timeout = "5m"' >> examples/kernel-module/.out-of-tree.toml
|
||||||
echo 'after_start_timeout = "10s"' >> examples/kernel-module/.out-of-tree.toml
|
echo 'after_start_timeout = "10s"' >> examples/kernel-module/.out-of-tree.toml
|
||||||
|
|
||||||
echo 'modprobe uio || modprobe 9p || modprobe xfs' >> examples/kernel-module/test.sh
|
echo 'modprobe uio || modprobe 9p || modprobe xfs' >> examples/kernel-module/test.sh
|
||||||
@ -142,7 +143,7 @@ jobs:
|
|||||||
echo 'WorkingDirectory=/root/test' >> test.service
|
echo 'WorkingDirectory=/root/test' >> test.service
|
||||||
echo 'TimeoutStopSec=1' >> test.service
|
echo 'TimeoutStopSec=1' >> test.service
|
||||||
echo 'ExecStart=/usr/local/bin/out-of-tree kernel --no-prebuilt-containers autogen --threads=8 --max=64 --shuffle' >> test.service
|
echo 'ExecStart=/usr/local/bin/out-of-tree kernel --no-prebuilt-containers autogen --threads=8 --max=64 --shuffle' >> test.service
|
||||||
echo 'ExecStart=/usr/local/bin/out-of-tree pew --qemu-timeout=10m --threads=4 --include-internal-errors' >> test.service
|
echo 'ExecStart=/usr/local/bin/out-of-tree pew --threads=4 --include-internal-errors' >> test.service
|
||||||
|
|
||||||
scp test.service root@$IP:/etc/systemd/system/test.service
|
scp test.service root@$IP:/etc/systemd/system/test.service
|
||||||
|
|
||||||
|
87
.github/workflows/images-centos.yml
vendored
Normal file
87
.github/workflows/images-centos.yml
vendored
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
name: CentOS images
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- 'tools/qemu-centos-img/**'
|
||||||
|
- '.github/workflows/images-centos.yml'
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow_ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
images-centos:
|
||||||
|
name: Qemu Images
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: digitalocean/action-doctl@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
- uses: webfactory/ssh-agent@v0.8.0
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
|
||||||
|
- name: create droplet
|
||||||
|
run: doctl compute droplet create --ssh-keys='b4:4c:66:7d:be:19:25:43:1c:e0:02:61:9f:49:12:94,37:46:77:a8:4a:96:3b:20:16:46:35:04:95:ca:0c:5c' --tag-name=github-actions ga-out-of-tree-images-centos-$GITHUB_SHA --size s-1vcpu-1gb --image ubuntu-22-04-x64 --wait
|
||||||
|
|
||||||
|
# TODO Move to common script
|
||||||
|
- name: generate images
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sleep 1m
|
||||||
|
|
||||||
|
IP=$(doctl compute droplet list --tag-name=github-actions --format "Name,Public IPv4" | grep -v ID | grep ga-out-of-tree-images-centos-$GITHUB_SHA | awk '{print $2}')
|
||||||
|
|
||||||
|
while ! ssh -o StrictHostKeyChecking=accept-new root@$IP echo
|
||||||
|
do
|
||||||
|
sleep 1s
|
||||||
|
done
|
||||||
|
|
||||||
|
ssh root@$IP "cloud-init status --wait | grep done"
|
||||||
|
|
||||||
|
ssh root@$IP apt-get update
|
||||||
|
ssh root@$IP apt-get install -y git podman s3cmd
|
||||||
|
ssh root@$IP git clone https://github.com/out-of-tree/out-of-tree
|
||||||
|
ssh root@$IP "cd out-of-tree && git checkout $GITHUB_SHA"
|
||||||
|
|
||||||
|
ssh root@$IP "echo -e '[Unit]\nDescription=CentOS image generator and uploader\n[Service]\nRemainAfterExit=yes\nStandardError=append:/var/log/images-centos.log\nStandardOutput=append:/var/log/images-centos.log\nType=oneshot' >> /etc/systemd/system/images-centos.service"
|
||||||
|
|
||||||
|
ssh root@$IP "echo Environment=HOST=fra1.digitaloceanspaces.com >> /etc/systemd/system/images-centos.service"
|
||||||
|
ssh root@$IP "echo Environment=HOST_BUCKET=out-of-tree.fra1.digitaloceanspaces.com >> /etc/systemd/system/images-centos.service"
|
||||||
|
ssh root@$IP "echo Environment=ACCESS_KEY=${{ secrets.DIGITALOCEAN_SPACES_ACCESS_KEY }} >> /etc/systemd/system/images-centos.service"
|
||||||
|
ssh root@$IP "echo Environment=SECRET_KEY=${{ secrets.DIGITALOCEAN_SPACES_SECRET_KEY }} >> /etc/systemd/system/images-centos.service"
|
||||||
|
|
||||||
|
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-centos-img/6/generate.sh' >> /etc/systemd/system/images-centos.service"
|
||||||
|
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-centos-img/7/generate.sh' >> /etc/systemd/system/images-centos.service"
|
||||||
|
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-centos-img/8/generate.sh' >> /etc/systemd/system/images-centos.service"
|
||||||
|
|
||||||
|
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-centos-img/*/*.tar.gz s3://out-of-tree/3.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-centos.service'
|
||||||
|
|
||||||
|
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-centos.service"
|
||||||
|
|
||||||
|
ssh root@$IP systemctl daemon-reload
|
||||||
|
|
||||||
|
ssh root@$IP systemctl start images-centos --no-block
|
||||||
|
|
||||||
|
while ! ssh root@$IP systemctl show images-centos -p SubState --value | grep -E '(failed|exited)'
|
||||||
|
do
|
||||||
|
sleep 3m
|
||||||
|
done
|
||||||
|
|
||||||
|
scp root@$IP:/var/log/images-centos.log .
|
||||||
|
|
||||||
|
ssh root@$IP systemctl is-active images-centos
|
||||||
|
|
||||||
|
- name: Archive logs
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: images-centos-log
|
||||||
|
path: images-centos.log
|
||||||
|
|
||||||
|
- name: delete droplet
|
||||||
|
if: always()
|
||||||
|
run: doctl compute droplet delete -f ga-out-of-tree-images-centos-$GITHUB_SHA
|
9
.github/workflows/images-debian.yml
vendored
9
.github/workflows/images-debian.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Debian
|
name: Debian images
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@ -25,7 +25,7 @@ jobs:
|
|||||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
|
||||||
- name: create droplet
|
- name: create droplet
|
||||||
run: doctl compute droplet create --ssh-keys='b4:4c:66:7d:be:19:25:43:1c:e0:02:61:9f:49:12:94' --tag-name=github-actions ga-out-of-tree-images-debian-$GITHUB_SHA --size s-1vcpu-1gb --image ubuntu-22-04-x64 --wait
|
run: doctl compute droplet create --ssh-keys='b4:4c:66:7d:be:19:25:43:1c:e0:02:61:9f:49:12:94,37:46:77:a8:4a:96:3b:20:16:46:35:04:95:ca:0c:5c' --tag-name=github-actions ga-out-of-tree-images-debian-$GITHUB_SHA --size s-1vcpu-1gb --image ubuntu-22-04-x64 --wait
|
||||||
|
|
||||||
# TODO Move to common script
|
# TODO Move to common script
|
||||||
- name: generate images
|
- name: generate images
|
||||||
@ -40,8 +40,7 @@ jobs:
|
|||||||
sleep 1s
|
sleep 1s
|
||||||
done
|
done
|
||||||
|
|
||||||
sleep 5m
|
ssh root@$IP "cloud-init status --wait | grep done"
|
||||||
ssh root@$IP pkill apt-get || true
|
|
||||||
|
|
||||||
ssh root@$IP apt-get update
|
ssh root@$IP apt-get update
|
||||||
ssh root@$IP apt-get install -y git podman s3cmd
|
ssh root@$IP apt-get install -y git podman s3cmd
|
||||||
@ -57,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-debian-img/generate-images.sh' >> /etc/systemd/system/images-debian.service"
|
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-debian-img/generate-images.sh' >> /etc/systemd/system/images-debian.service"
|
||||||
|
|
||||||
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-debian-img/*.tar.gz s3://out-of-tree/1.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-debian.service'
|
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-debian-img/*.tar.gz s3://out-of-tree/3.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-debian.service'
|
||||||
|
|
||||||
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-debian.service"
|
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-debian.service"
|
||||||
|
|
||||||
|
16
.github/workflows/images-oraclelinux.yml
vendored
16
.github/workflows/images-oraclelinux.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Oracle Linux
|
name: Oracle Linux images
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@ -25,7 +25,7 @@ jobs:
|
|||||||
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
|
||||||
- name: create droplet
|
- name: create droplet
|
||||||
run: doctl compute droplet create --ssh-keys='b4:4c:66:7d:be:19:25:43:1c:e0:02:61:9f:49:12:94' --tag-name=github-actions ga-out-of-tree-images-oraclelinux-$GITHUB_SHA --size s-1vcpu-1gb --image ubuntu-22-04-x64 --wait
|
run: doctl compute droplet create --ssh-keys='b4:4c:66:7d:be:19:25:43:1c:e0:02:61:9f:49:12:94,37:46:77:a8:4a:96:3b:20:16:46:35:04:95:ca:0c:5c' --tag-name=github-actions ga-out-of-tree-images-oraclelinux-$GITHUB_SHA --size s-1vcpu-2gb --image ubuntu-22-04-x64 --wait
|
||||||
|
|
||||||
# TODO Move to common script
|
# TODO Move to common script
|
||||||
- name: generate images
|
- name: generate images
|
||||||
@ -40,8 +40,7 @@ jobs:
|
|||||||
sleep 1s
|
sleep 1s
|
||||||
done
|
done
|
||||||
|
|
||||||
sleep 5m
|
ssh root@$IP "cloud-init status --wait | grep done"
|
||||||
ssh root@$IP pkill apt-get || true
|
|
||||||
|
|
||||||
ssh root@$IP apt-get update
|
ssh root@$IP apt-get update
|
||||||
ssh root@$IP apt-get install -y git podman s3cmd
|
ssh root@$IP apt-get install -y git podman s3cmd
|
||||||
@ -57,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-oraclelinux-img/generate-images.sh' >> /etc/systemd/system/images-oraclelinux.service"
|
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-oraclelinux-img/generate-images.sh' >> /etc/systemd/system/images-oraclelinux.service"
|
||||||
|
|
||||||
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-oraclelinux-img/*.tar.gz s3://out-of-tree/1.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-oraclelinux.service'
|
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-oraclelinux-img/*.tar.gz s3://out-of-tree/3.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-oraclelinux.service'
|
||||||
|
|
||||||
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-oraclelinux.service"
|
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-oraclelinux.service"
|
||||||
|
|
||||||
@ -74,6 +73,13 @@ jobs:
|
|||||||
|
|
||||||
ssh root@$IP systemctl is-active images-oraclelinux
|
ssh root@$IP systemctl is-active images-oraclelinux
|
||||||
|
|
||||||
|
- name: Archive logs
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: images-oraclelinux-log
|
||||||
|
path: images-oraclelinux.log
|
||||||
|
|
||||||
- name: delete droplet
|
- name: delete droplet
|
||||||
if: always()
|
if: always()
|
||||||
run: doctl compute droplet delete -f ga-out-of-tree-images-oraclelinux-$GITHUB_SHA
|
run: doctl compute droplet delete -f ga-out-of-tree-images-oraclelinux-$GITHUB_SHA
|
||||||
|
2
.github/workflows/images-ubuntu.yml
vendored
2
.github/workflows/images-ubuntu.yml
vendored
@ -58,7 +58,7 @@ jobs:
|
|||||||
|
|
||||||
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-ubuntu-img/generate-images.py' >> /etc/systemd/system/images-ubuntu.service"
|
ssh root@$IP "echo 'ExecStart=/root/out-of-tree/tools/qemu-ubuntu-img/generate-images.py' >> /etc/systemd/system/images-ubuntu.service"
|
||||||
|
|
||||||
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-ubuntu-img/*.tar.gz s3://out-of-tree/1.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-ubuntu.service'
|
ssh root@$IP 'echo ExecStart=/bin/sh -c \"s3cmd put --acl-public /root/out-of-tree/tools/qemu-ubuntu-img/*.tar.gz s3://out-of-tree/3.0.0/ --host=\$HOST --host-bucket=\$HOST_BUCKET --access_key=\$ACCESS_KEY --secret_key=\$SECRET_KEY\" >> /etc/systemd/system/images-ubuntu.service'
|
||||||
|
|
||||||
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-ubuntu.service"
|
ssh root@$IP "echo TimeoutStopSec=1 >> /etc/systemd/system/images-ubuntu.service"
|
||||||
|
|
||||||
|
10
README.md
10
README.md
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
*out-of-tree* was created to reduce the complexity of the environment for developing, testing and debugging Linux kernel exploits and out-of-tree kernel modules (hence the name "out-of-tree").
|
*out-of-tree* was created to reduce the complexity of the environment for developing, testing and debugging Linux kernel exploits and out-of-tree kernel modules (hence the name "out-of-tree").
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### GNU/Linux (with [Nix](https://nixos.org/nix/))
|
### GNU/Linux (with [Nix](https://nixos.org/nix/))
|
||||||
@ -42,9 +40,9 @@ Read [documentation](https://out-of-tree.readthedocs.io) for further info.
|
|||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Generate all Ubuntu 22.04 kernels:
|
Download all Ubuntu 24.04 kernels:
|
||||||
|
|
||||||
$ out-of-tree kernel genall --distro=Ubuntu --ver=22.04
|
$ out-of-tree kernel genall --distro-id=Ubuntu --distro-release=24.04
|
||||||
|
|
||||||
Run tests based on .out-of-tree.toml definitions:
|
Run tests based on .out-of-tree.toml definitions:
|
||||||
|
|
||||||
@ -52,8 +50,8 @@ Run tests based on .out-of-tree.toml definitions:
|
|||||||
|
|
||||||
Test with a specific kernel:
|
Test with a specific kernel:
|
||||||
|
|
||||||
$ out-of-tree pew --kernel='Ubuntu:5.4.0-29-generic'
|
$ out-of-tree pew --realtime-output --distro-id=ubuntu --kernel-regex=6.8.0-41-generic
|
||||||
|
|
||||||
Run debug environment:
|
Run debug environment:
|
||||||
|
|
||||||
$ out-of-tree debug --kernel='Ubuntu:5.4.0-29-generic'
|
$ out-of-tree debug --distro-id=ubuntu --distro-release=24.04 --kernel-regex=6.8.0-41-generic
|
||||||
|
@ -338,7 +338,11 @@ func (ka Artifact) Process(slog zerolog.Logger, ki distro.KernelInfo,
|
|||||||
slog.Debug().Str("duration", time.Since(start).String()).
|
slog.Debug().Str("duration", time.Since(start).String()).
|
||||||
Msg("build done")
|
Msg("build done")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Error().Err(err).Msgf("build failure\n%v\n", result.Build.Output)
|
if !realtimeOutput {
|
||||||
|
slog.Error().Err(err).Msgf("build failure\n%v\n", result.Build.Output)
|
||||||
|
} else {
|
||||||
|
slog.Error().Err(err).Msg("build failure")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if outputOnSuccess && !realtimeOutput {
|
if outputOnSuccess && !realtimeOutput {
|
||||||
@ -367,6 +371,8 @@ func (ka Artifact) Process(slog zerolog.Logger, ki distro.KernelInfo,
|
|||||||
ka.Qemu.Timeout.Duration = time.Minute
|
ka.Qemu.Timeout.Duration = time.Minute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slog.Info().Msg("wait for vm initialisation")
|
||||||
|
|
||||||
err = q.WaitForSSH(ka.Qemu.Timeout.Duration)
|
err = q.WaitForSSH(ka.Qemu.Timeout.Duration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
result.InternalError = err
|
result.InternalError = err
|
||||||
@ -419,14 +425,15 @@ func (ka Artifact) Process(slog zerolog.Logger, ki distro.KernelInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
slog.Info().Msg("copy artifact and run test")
|
||||||
copyArtifactAndTest(slog, q, ka, &result, remoteTest, outputOnSuccess, realtimeOutput)
|
copyArtifactAndTest(slog, q, ka, &result, remoteTest, outputOnSuccess, realtimeOutput)
|
||||||
slog.Debug().Str("duration", time.Since(start).String()).
|
slog.Debug().Str("duration", time.Since(start).String()).
|
||||||
Msgf("test completed (success: %v)", result.Test.Ok)
|
Msgf("test completed (success: %v)", result.Test.Ok)
|
||||||
|
|
||||||
if result.Build.Ok {
|
if result.Build.Ok && !realtimeOutput {
|
||||||
if !result.Run.Ok || !result.Test.Ok {
|
if !result.Run.Ok || !result.Test.Ok {
|
||||||
slog.Error().Msgf("qemu output\n%v\n", qemuTestOutput)
|
slog.Error().Msgf("qemu output\n%v\n", qemuTestOutput)
|
||||||
} else if outputOnSuccess && !realtimeOutput {
|
} else if outputOnSuccess {
|
||||||
slog.Info().Msgf("qemu output\n%v\n", qemuTestOutput)
|
slog.Info().Msgf("qemu output\n%v\n", qemuTestOutput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,7 +352,11 @@ func copyArtifactAndTest(slog zerolog.Logger, q *qemu.System, ka Artifact,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil || !res.Test.Ok {
|
if err != nil || !res.Test.Ok {
|
||||||
slog.Error().Err(err).Msgf("test error\n%v\n", res.Test.Output)
|
if !realtimeOutput {
|
||||||
|
slog.Error().Err(err).Msgf("test failure\n%v\n", res.Test.Output)
|
||||||
|
} else {
|
||||||
|
slog.Error().Err(err).Msg("test failure")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,9 +198,11 @@ func (c Client) PushRepo(repo api.Repo) (err error) {
|
|||||||
remote := fmt.Sprintf("git://%s/%s", addr, repo.Name)
|
remote := fmt.Sprintf("git://%s/%s", addr, repo.Name)
|
||||||
log.Debug().Msgf("git proxy remote: %v", remote)
|
log.Debug().Msgf("git proxy remote: %v", remote)
|
||||||
|
|
||||||
raw, err := exec.Command("git", "--work-tree", repo.Path, "push", "--force", remote).
|
raw, err := exec.Command("git", "-c", "push.default=current",
|
||||||
|
"--work-tree", repo.Path, "push", "--force", remote).
|
||||||
CombinedOutput()
|
CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error().Msgf("push repo %v\n%v", repo, string(raw))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
cmd/log.go
16
cmd/log.go
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Mikhail Klementev. All rights reserved.
|
// Copyright 2024 Mikhail Klementev. All rights reserved.
|
||||||
// Use of this source code is governed by a AGPLv3 license
|
// Use of this source code is governed by a AGPLv3 license
|
||||||
// (or later) that can be found in the LICENSE file.
|
// (or later) that can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -212,7 +212,12 @@ func center(s string, w int) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genOkFailCentered(name string, ok bool) (aurv aurora.Value) {
|
func genOkFailCentered(name string, ok bool) (aurv aurora.Value) {
|
||||||
name = center(name, 10)
|
if ok {
|
||||||
|
name += " OK"
|
||||||
|
} else {
|
||||||
|
name += " FAIL"
|
||||||
|
}
|
||||||
|
name = center(name, 14)
|
||||||
if ok {
|
if ok {
|
||||||
aurv = aurora.BgGreen(aurora.Black(name))
|
aurv = aurora.BgGreen(aurora.Black(name))
|
||||||
} else {
|
} else {
|
||||||
@ -225,7 +230,7 @@ func logLogEntry(l logEntry) {
|
|||||||
distroInfo := fmt.Sprintf("%s-%s {%s}", l.Distro.ID,
|
distroInfo := fmt.Sprintf("%s-%s {%s}", l.Distro.ID,
|
||||||
l.Distro.Release, l.KernelRelease)
|
l.Distro.Release, l.KernelRelease)
|
||||||
|
|
||||||
artifactInfo := fmt.Sprintf("{[%s] %s}", l.Type, l.Name)
|
artifactInfo := fmt.Sprintf("%s", l.Name)
|
||||||
|
|
||||||
timestamp := l.Timestamp.Format("2006-01-02 15:04")
|
timestamp := l.Timestamp.Format("2006-01-02 15:04")
|
||||||
|
|
||||||
@ -257,7 +262,10 @@ func logLogEntry(l logEntry) {
|
|||||||
additional = "(timeout)"
|
additional = "(timeout)"
|
||||||
}
|
}
|
||||||
|
|
||||||
colored := aurora.Sprintf("[%4d %4s] [%s] %s %-70s: %s %s",
|
if len(distroInfo) > 40 {
|
||||||
|
distroInfo = distroInfo[:40]
|
||||||
|
}
|
||||||
|
colored := aurora.Sprintf("[%4d %4s] [%s] %s %-40s: %s %s",
|
||||||
l.ID, l.Tag, timestamp, artifactInfo, distroInfo, status,
|
l.ID, l.Tag, timestamp, artifactInfo, distroInfo, status,
|
||||||
additional)
|
additional)
|
||||||
|
|
||||||
|
155
cmd/pew.go
155
cmd/pew.go
@ -87,6 +87,7 @@ type PewCmd struct {
|
|||||||
|
|
||||||
Threshold float64 `help:"reliablity threshold for exit code" default:"1.00"`
|
Threshold float64 `help:"reliablity threshold for exit code" default:"1.00"`
|
||||||
IncludeInternalErrors bool `help:"count internal errors as part of the success rate"`
|
IncludeInternalErrors bool `help:"count internal errors as part of the success rate"`
|
||||||
|
InternalErrorsRetries int `help:"amount of retries on internal errors" default:"3"`
|
||||||
|
|
||||||
OutputOnSuccess bool `help:"show output on success"`
|
OutputOnSuccess bool `help:"show output on success"`
|
||||||
RealtimeOutput bool `help:"show realtime output"`
|
RealtimeOutput bool `help:"show realtime output"`
|
||||||
@ -167,6 +168,11 @@ func (cmd *PewCmd) Run(g *Globals) (err error) {
|
|||||||
cmd.useRemote = g.Remote
|
cmd.useRemote = g.Remote
|
||||||
cmd.remoteAddr = g.RemoteAddr
|
cmd.remoteAddr = g.RemoteAddr
|
||||||
|
|
||||||
|
if cmd.RealtimeOutput && cmd.Threads != 1 {
|
||||||
|
log.Warn().Msg("realtime output disables multithreading")
|
||||||
|
cmd.Threads = 1
|
||||||
|
}
|
||||||
|
|
||||||
if cmd.useRemote {
|
if cmd.useRemote {
|
||||||
c := client.Client{RemoteAddr: cmd.remoteAddr}
|
c := client.Client{RemoteAddr: cmd.remoteAddr}
|
||||||
cmd.Kcfg.Kernels, err = c.Kernels()
|
cmd.Kcfg.Kernels, err = c.Kernels()
|
||||||
@ -466,12 +472,33 @@ func (cmd PewCmd) testArtifact(swg *sizedwaitgroup.SizedWaitGroup,
|
|||||||
Str("kernel", ki.KernelRelease).
|
Str("kernel", ki.KernelRelease).
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
ka.Process(slog, ki, cmd.OutputOnSuccess, cmd.RealtimeOutput,
|
retriesLeft := cmd.InternalErrorsRetries
|
||||||
cmd.Endless, cmd.Binary, cmd.EndlessStress, cmd.EndlessTimeout,
|
var stop bool
|
||||||
func(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, result *artifact.Result) {
|
for !stop {
|
||||||
dumpResult(q, ka, ki, result, cmd.Dist, cmd.Tag, cmd.Binary, cmd.DB)
|
ka.Process(slog, ki, cmd.OutputOnSuccess, cmd.RealtimeOutput,
|
||||||
},
|
cmd.Endless, cmd.Binary, cmd.EndlessStress, cmd.EndlessTimeout,
|
||||||
)
|
func(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, res *artifact.Result) {
|
||||||
|
if res.InternalError == nil {
|
||||||
|
cmd.dumpResult(q, ka, ki, res)
|
||||||
|
stop = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
q.Log.Warn().Err(res.InternalError).
|
||||||
|
Str("panic", fmt.Sprintf("%v", q.KernelPanic)).
|
||||||
|
Str("timeout", fmt.Sprintf("%v", q.KilledByTimeout)).
|
||||||
|
Int("retries_left", retriesLeft).
|
||||||
|
Msg("internal")
|
||||||
|
|
||||||
|
if retriesLeft == 0 {
|
||||||
|
state.InternalErrors += 1
|
||||||
|
stop = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
retriesLeft -= 1
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func shuffleKernels(a []distro.KernelInfo) []distro.KernelInfo {
|
func shuffleKernels(a []distro.KernelInfo) []distro.KernelInfo {
|
||||||
@ -567,76 +594,70 @@ func genOkFail(name string, ok bool) (aurv aurora.Value) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpResult(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo,
|
func (cmd PewCmd) dumpResult(q *qemu.System, ka artifact.Artifact, ki distro.KernelInfo, res *artifact.Result) {
|
||||||
res *artifact.Result, dist, tag, binary string, db *sql.DB) {
|
state.Overall += 1
|
||||||
|
|
||||||
// TODO refactor
|
if res.Test.Ok {
|
||||||
|
state.Success += 1
|
||||||
|
}
|
||||||
|
|
||||||
if res.InternalError != nil {
|
colored := ""
|
||||||
q.Log.Warn().Err(res.InternalError).
|
switch ka.Type {
|
||||||
Str("panic", fmt.Sprintf("%v", q.KernelPanic)).
|
case artifact.KernelExploit:
|
||||||
Str("timeout", fmt.Sprintf("%v", q.KilledByTimeout)).
|
colored = aurora.Sprintf("%s %s",
|
||||||
Msg("internal")
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
res.InternalErrorString = res.InternalError.Error()
|
genOkFail("LPE", res.Test.Ok))
|
||||||
state.InternalErrors += 1
|
case artifact.KernelModule:
|
||||||
|
colored = aurora.Sprintf("%s %s %s",
|
||||||
|
genOkFail("BUILD", res.Build.Ok),
|
||||||
|
genOkFail("INSMOD", res.Run.Ok),
|
||||||
|
genOkFail("TEST", res.Test.Ok))
|
||||||
|
case artifact.Script:
|
||||||
|
colored = aurora.Sprintf("%s",
|
||||||
|
genOkFail("", res.Test.Ok))
|
||||||
|
}
|
||||||
|
|
||||||
|
additional := ""
|
||||||
|
if q.KernelPanic {
|
||||||
|
additional = "(panic)"
|
||||||
|
} else if q.KilledByTimeout {
|
||||||
|
additional = "(timeout)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if additional != "" {
|
||||||
|
q.Log.Info().Msgf("%v %v", colored, additional)
|
||||||
} else {
|
} else {
|
||||||
colored := ""
|
q.Log.Info().Msgf("%v", colored)
|
||||||
|
|
||||||
state.Overall += 1
|
|
||||||
|
|
||||||
if res.Test.Ok {
|
|
||||||
state.Success += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ka.Type {
|
|
||||||
case artifact.KernelExploit:
|
|
||||||
colored = aurora.Sprintf("%s %s",
|
|
||||||
genOkFail("BUILD", res.Build.Ok),
|
|
||||||
genOkFail("LPE", res.Test.Ok))
|
|
||||||
case artifact.KernelModule:
|
|
||||||
colored = aurora.Sprintf("%s %s %s",
|
|
||||||
genOkFail("BUILD", res.Build.Ok),
|
|
||||||
genOkFail("INSMOD", res.Run.Ok),
|
|
||||||
genOkFail("TEST", res.Test.Ok))
|
|
||||||
case artifact.Script:
|
|
||||||
colored = aurora.Sprintf("%s",
|
|
||||||
genOkFail("", res.Test.Ok))
|
|
||||||
}
|
|
||||||
|
|
||||||
additional := ""
|
|
||||||
if q.KernelPanic {
|
|
||||||
additional = "(panic)"
|
|
||||||
} else if q.KilledByTimeout {
|
|
||||||
additional = "(timeout)"
|
|
||||||
}
|
|
||||||
|
|
||||||
if additional != "" {
|
|
||||||
q.Log.Info().Msgf("%v %v", colored, additional)
|
|
||||||
} else {
|
|
||||||
q.Log.Info().Msgf("%v", colored)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := addToLog(db, q, ka, ki, res, tag)
|
err := addToLog(cmd.DB, q, ka, ki, res, cmd.Tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
q.Log.Warn().Err(err).Msgf("[db] addToLog (%v)", ka)
|
q.Log.Error().Err(err).Msgf("[db] addToLog (%v)", ka)
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary == "" && dist != pathDevNull {
|
if cmd.Binary != "" {
|
||||||
err = os.MkdirAll(dist, os.ModePerm)
|
return
|
||||||
if err != nil {
|
}
|
||||||
log.Warn().Err(err).Msgf("os.MkdirAll (%v)", ka)
|
|
||||||
}
|
|
||||||
|
|
||||||
path := fmt.Sprintf("%s/%s-%s-%s", dist, ki.Distro.ID,
|
if cmd.Dist == pathDevNull { // why?
|
||||||
ki.Distro.Release, ki.KernelRelease)
|
return
|
||||||
if ka.Type != artifact.KernelExploit {
|
}
|
||||||
path += ".ko"
|
|
||||||
}
|
|
||||||
|
|
||||||
err = artifact.CopyFile(res.BuildArtifact, path)
|
err = os.MkdirAll(cmd.Dist, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msgf("copy file (%v)", ka)
|
log.Error().Err(err).Msgf("os.MkdirAll (%v)", ka)
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("%s/%s-%s-%s", cmd.Dist, ki.Distro.ID,
|
||||||
|
ki.Distro.Release, ki.KernelRelease)
|
||||||
|
if ka.Type != artifact.KernelExploit {
|
||||||
|
path += ".ko"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = artifact.CopyFile(res.BuildArtifact, path)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("copy file (%v)", ka)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,9 @@ type Container struct {
|
|||||||
// Additional arguments
|
// Additional arguments
|
||||||
Args []string
|
Args []string
|
||||||
|
|
||||||
|
// Base of container is local-only
|
||||||
|
LocalBase bool
|
||||||
|
|
||||||
Log zerolog.Logger
|
Log zerolog.Logger
|
||||||
|
|
||||||
commandsOutput struct {
|
commandsOutput struct {
|
||||||
@ -428,7 +431,10 @@ func (c Container) build(imagePath string) (output string, err error) {
|
|||||||
|
|
||||||
args := []string{"build"}
|
args := []string{"build"}
|
||||||
if !UseCache {
|
if !UseCache {
|
||||||
args = append(args, "--pull", "--no-cache")
|
if !c.LocalBase {
|
||||||
|
args = append(args, "--pull")
|
||||||
|
}
|
||||||
|
args = append(args, "--no-cache")
|
||||||
}
|
}
|
||||||
args = append(args, "-t", c.name, imagePath)
|
args = append(args, "-t", c.name, imagePath)
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ func (suse OpenSUSE) Packages() (pkgs []string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.LocalBase = true
|
||||||
|
|
||||||
} else if strings.HasPrefix(suse.release, "13") {
|
} else if strings.HasPrefix(suse.release, "13") {
|
||||||
name = "opensuse:13"
|
name = "opensuse:13"
|
||||||
cnturl := cache.ContainerURL("openSUSE-13.2")
|
cnturl := cache.ContainerURL("openSUSE-13.2")
|
||||||
@ -64,6 +66,8 @@ func (suse OpenSUSE) Packages() (pkgs []string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
c.LocalBase = true
|
||||||
|
|
||||||
} else if strings.HasPrefix(suse.release, "42") {
|
} else if strings.HasPrefix(suse.release, "42") {
|
||||||
name = "opensuse/leap:42"
|
name = "opensuse/leap:42"
|
||||||
} else if strings.HasPrefix(suse.release, "15") {
|
} else if strings.HasPrefix(suse.release, "15") {
|
||||||
@ -83,7 +87,32 @@ func (suse OpenSUSE) Packages() (pkgs []string, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pkgs = append(pkgs, strings.Fields(output)...)
|
// TODO Find a way for non-interactive installation of
|
||||||
|
// retracted kernels
|
||||||
|
retracted := []string{
|
||||||
|
"5.14.21-150400.24.49.3",
|
||||||
|
"5.14.21-150400.24.84.1",
|
||||||
|
"5.14.21-150500.55.22.1",
|
||||||
|
"5.3.18-150300.59.81.1",
|
||||||
|
"5.3.18-59.30.1",
|
||||||
|
"5.3.18-lp152.98.1",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range strings.Fields(output) {
|
||||||
|
skip := false
|
||||||
|
for _, rk := range retracted {
|
||||||
|
if rk == k {
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
pkgs = append(pkgs, k)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ func (q *System) Start() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
scanner := bufio.NewScanner(q.pipe.stdout)
|
scanner := bufio.NewScanner(q.pipe.stdout)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := strings.TrimSpace(scanner.Text())
|
||||||
q.handleQemuOutput(m)
|
q.handleQemuOutput(m)
|
||||||
q.Stdout += m + "\n"
|
q.Stdout += m + "\n"
|
||||||
q.Log.Trace().Str("stdout", m).Msg("qemu")
|
q.Log.Trace().Str("stdout", m).Msg("qemu")
|
||||||
@ -407,7 +407,7 @@ func (q *System) Start() (err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
scanner := bufio.NewScanner(q.pipe.stderr)
|
scanner := bufio.NewScanner(q.pipe.stderr)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := strings.TrimSpace(scanner.Text())
|
||||||
q.handleQemuOutput(m)
|
q.handleQemuOutput(m)
|
||||||
q.Stderr += m + "\n"
|
q.Stderr += m + "\n"
|
||||||
q.Log.Trace().Str("stderr", m).Msg("qemu")
|
q.Log.Trace().Str("stderr", m).Msg("qemu")
|
||||||
@ -560,7 +560,7 @@ func (q System) Command(user, cmd string) (output string, err error) {
|
|||||||
|
|
||||||
scanner := bufio.NewScanner(stdout)
|
scanner := bufio.NewScanner(stdout)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := strings.TrimSpace(scanner.Text())
|
||||||
q.handleCommandsOutput(m)
|
q.handleCommandsOutput(m)
|
||||||
output += m + "\n"
|
output += m + "\n"
|
||||||
flog.Trace().Str("stdout", m).Msg("qemu command")
|
flog.Trace().Str("stdout", m).Msg("qemu command")
|
||||||
@ -574,7 +574,7 @@ func (q System) Command(user, cmd string) (output string, err error) {
|
|||||||
|
|
||||||
scanner := bufio.NewScanner(stderr)
|
scanner := bufio.NewScanner(stderr)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
m := scanner.Text()
|
m := strings.TrimSpace(scanner.Text())
|
||||||
q.handleCommandsOutput(m)
|
q.handleCommandsOutput(m)
|
||||||
output += m + "\n"
|
output += m + "\n"
|
||||||
// Note: it prints stderr as stdout
|
// Note: it prints stderr as stdout
|
||||||
|
@ -28,6 +28,8 @@ RUN sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
|
|||||||
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN sed -i '/UseDNS/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN echo UseDNS no >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
|
||||||
# network workaround
|
# network workaround
|
||||||
RUN chmod +x $TMPDIR/etc/rc.local
|
RUN chmod +x $TMPDIR/etc/rc.local
|
||||||
|
@ -4,6 +4,6 @@ set -eux
|
|||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
sudo docker build -t gen-centos6-image .
|
sudo podman build -t gen-centos6-image .
|
||||||
sudo docker run --privileged -v $(pwd):/shared -t gen-centos6-image
|
sudo podman run --privileged -v $(pwd):/shared -t gen-centos6-image
|
||||||
tar -Szcf out_of_tree_centos_6.img.tar.gz out_of_tree_centos_6.img
|
tar -Szcf out_of_tree_centos_6.img.tar.gz out_of_tree_centos_6.img
|
||||||
|
@ -13,6 +13,11 @@
|
|||||||
#
|
#
|
||||||
FROM centos:7
|
FROM centos:7
|
||||||
|
|
||||||
|
RUN sed -i 's/enabled=1/enabled=0/' /etc/yum.repos.d/* || true
|
||||||
|
RUN sed -i 's/name/enabled=0\nname/' /etc/yum.repos.d/* || true
|
||||||
|
RUN echo -e '[7.9.2009-os]\nbaseurl=https://vault.centos.org/7.9.2009/os/$basearch/\ngpgcheck=0' >> /etc/yum.repos.d/oot.repo
|
||||||
|
RUN echo -e '[7.9.2009-updates]\nbaseurl=https://vault.centos.org/7.9.2009/updates/$basearch/\ngpgcheck=0' >> /etc/yum.repos.d/oot.repo
|
||||||
|
|
||||||
RUN yum -y update
|
RUN yum -y update
|
||||||
RUN yum -y groupinstall "Development Tools"
|
RUN yum -y groupinstall "Development Tools"
|
||||||
RUN yum -y install qemu-img e2fsprogs
|
RUN yum -y install qemu-img e2fsprogs
|
||||||
@ -21,13 +26,13 @@ ENV TMPDIR=/tmp/centos
|
|||||||
|
|
||||||
RUN yum --installroot=$TMPDIR \
|
RUN yum --installroot=$TMPDIR \
|
||||||
--releasever=7 \
|
--releasever=7 \
|
||||||
--disablerepo='*' \
|
|
||||||
--enablerepo=base \
|
|
||||||
-y groupinstall Base
|
-y groupinstall Base
|
||||||
|
|
||||||
|
RUN rm $TMPDIR/etc/yum.repos.d/*
|
||||||
|
RUN cp /etc/yum.repos.d/* $TMPDIR/etc/yum.repos.d/
|
||||||
|
|
||||||
RUN yum --installroot=$TMPDIR \
|
RUN yum --installroot=$TMPDIR \
|
||||||
--releasever=7 \
|
--releasever=7 \
|
||||||
--disablerepo='*' \
|
|
||||||
--enablerepo=base \
|
|
||||||
-y install openssh-server openssh-clients
|
-y install openssh-server openssh-clients
|
||||||
|
|
||||||
RUN chroot $TMPDIR /bin/sh -c 'useradd -m user'
|
RUN chroot $TMPDIR /bin/sh -c 'useradd -m user'
|
||||||
@ -37,6 +42,8 @@ RUN sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
|
|||||||
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN sed -i '/UseDNS/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN echo UseDNS no >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
|
||||||
# network workaround
|
# network workaround
|
||||||
RUN chmod +x $TMPDIR/etc/rc.local
|
RUN chmod +x $TMPDIR/etc/rc.local
|
||||||
|
9
tools/qemu-centos-img/7/generate.sh
Executable file
9
tools/qemu-centos-img/7/generate.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
sudo podman build -t gen-centos7-image .
|
||||||
|
sudo podman run --privileged -v $(pwd):/shared -t gen-centos7-image
|
||||||
|
tar -Szcf out_of_tree_centos_7.img.tar.gz out_of_tree_centos_7.img
|
@ -28,6 +28,8 @@ RUN sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
|
|||||||
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN sed -i '/UseDNS/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN echo UseDNS no >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
|
||||||
# network workaround
|
# network workaround
|
||||||
RUN chmod +x $TMPDIR/etc/rc.local
|
RUN chmod +x $TMPDIR/etc/rc.local
|
||||||
|
@ -4,6 +4,6 @@ set -eux
|
|||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
sudo docker build -t gen-centos8-image .
|
sudo podman build -t gen-centos8-image .
|
||||||
sudo docker run --privileged -v $(pwd):/shared -t gen-centos8-image
|
sudo podman run --privileged -v $(pwd):/shared -t gen-centos8-image
|
||||||
tar -Szcf out_of_tree_centos_8.img.tar.gz out_of_tree_centos_8.img
|
tar -Szcf out_of_tree_centos_8.img.tar.gz out_of_tree_centos_8.img
|
||||||
|
@ -11,6 +11,8 @@ sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
|
|||||||
echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
sed -i '/UseDNS/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
|
echo UseDNS no >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
|
||||||
echo '#!/bin/sh' > $TMPDIR/etc/rc.local
|
echo '#!/bin/sh' > $TMPDIR/etc/rc.local
|
||||||
echo 'dhclient' >> $TMPDIR/etc/rc.local
|
echo 'dhclient' >> $TMPDIR/etc/rc.local
|
||||||
|
@ -13,6 +13,7 @@ RUN yum --installroot=$TMPDIR \
|
|||||||
--releasever=_VERSION_ \
|
--releasever=_VERSION_ \
|
||||||
--disablerepo='*' \
|
--disablerepo='*' \
|
||||||
--enablerepo=ol_VERSION__baseos_latest \
|
--enablerepo=ol_VERSION__baseos_latest \
|
||||||
|
--enablerepo=ol_VERSION__appstream \
|
||||||
-y groupinstall Base
|
-y groupinstall Base
|
||||||
|
|
||||||
RUN cp /etc/yum.repos.d/* $TMPDIR/etc/yum.repos.d/
|
RUN cp /etc/yum.repos.d/* $TMPDIR/etc/yum.repos.d/
|
||||||
@ -21,6 +22,7 @@ RUN yum --installroot=$TMPDIR \
|
|||||||
--releasever=_VERSION_ \
|
--releasever=_VERSION_ \
|
||||||
--disablerepo='*' \
|
--disablerepo='*' \
|
||||||
--enablerepo=ol_VERSION__baseos_latest \
|
--enablerepo=ol_VERSION__baseos_latest \
|
||||||
|
--enablerepo=ol_VERSION__appstream \
|
||||||
-y install openssh-server openssh-clients dhclient yum
|
-y install openssh-server openssh-clients dhclient yum
|
||||||
|
|
||||||
RUN chroot $TMPDIR /bin/sh -c 'useradd -m user'
|
RUN chroot $TMPDIR /bin/sh -c 'useradd -m user'
|
||||||
@ -30,6 +32,8 @@ RUN sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
|
|||||||
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
RUN sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
RUN echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN sed -i '/UseDNS/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
|
RUN echo UseDNS no >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
|
||||||
# network workaround
|
# network workaround
|
||||||
RUN chmod +x $TMPDIR/etc/rc.local
|
RUN chmod +x $TMPDIR/etc/rc.local
|
||||||
|
@ -11,9 +11,11 @@ for version in 6 7 8 9; do
|
|||||||
|
|
||||||
if [[ $version -eq 6 ]]; then
|
if [[ $version -eq 6 ]]; then
|
||||||
sed -i 's/baseos_latest/u10_base/' $version/Dockerfile
|
sed -i 's/baseos_latest/u10_base/' $version/Dockerfile
|
||||||
|
sed -i '/appstream/d' $version/Dockerfile
|
||||||
fi
|
fi
|
||||||
if [[ $version -eq 7 ]]; then
|
if [[ $version -eq 7 ]]; then
|
||||||
sed -i 's/baseos_latest/u9_base/' $version/Dockerfile
|
sed -i 's/baseos_latest/u9_base/' $version/Dockerfile
|
||||||
|
sed -i '/appstream/d' $version/Dockerfile
|
||||||
fi
|
fi
|
||||||
|
|
||||||
podman build -t gen-oraclelinux${version}-image $version
|
podman build -t gen-oraclelinux${version}-image $version
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
# 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
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/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
|
|
@ -7,27 +7,29 @@ script_dir = os.path.dirname(os.path.realpath(__file__))
|
|||||||
os.chdir(script_dir)
|
os.chdir(script_dir)
|
||||||
|
|
||||||
releases = [
|
releases = [
|
||||||
# ('12.04', 'precies'),
|
('12.04', 'precise', 'http://old-releases.ubuntu.com/ubuntu'),
|
||||||
# ('14.04', 'trusty'),
|
('14.04', 'trusty', 'http://archive.ubuntu.com/ubuntu'),
|
||||||
# ('16.04', 'xenial'),
|
('16.04', 'xenial', 'http://archive.ubuntu.com/ubuntu'),
|
||||||
# ('18.04', 'bionic'),
|
('18.04', 'bionic', 'http://archive.ubuntu.com/ubuntu'),
|
||||||
# ('20.04', 'focal'),
|
('20.04', 'focal', 'http://archive.ubuntu.com/ubuntu'),
|
||||||
# ('22.04', 'jammy'),
|
('22.04', 'jammy', 'http://archive.ubuntu.com/ubuntu'),
|
||||||
('24.04', 'noble'),
|
('24.04', 'noble', 'http://archive.ubuntu.com/ubuntu')
|
||||||
]
|
]
|
||||||
|
|
||||||
template = '''
|
template = '''
|
||||||
FROM ubuntu:{version}
|
FROM ubuntu:{version}
|
||||||
|
|
||||||
|
RUN sed -i 's;http://archive.ubuntu.com/ubuntu;{repository};' /etc/apt/sources.list
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
RUN apt update
|
RUN apt-get update
|
||||||
RUN apt install -y debootstrap qemu-utils
|
RUN apt-get install -y debootstrap qemu-utils
|
||||||
RUN apt install -y linux-image-generic
|
RUN apt-get install -y linux-image-generic
|
||||||
|
|
||||||
ENV TMPDIR=/tmp/ubuntu
|
ENV TMPDIR=/tmp/ubuntu
|
||||||
ENV IMAGEDIR=/tmp/image
|
ENV IMAGEDIR=/tmp/image
|
||||||
ENV IMAGE=/shared/out_of_tree_ubuntu_{img_version}.img
|
ENV IMAGE=/shared/out_of_tree_ubuntu_{img_version}.img
|
||||||
ENV REPOSITORY=http://archive.ubuntu.com/ubuntu
|
ENV REPOSITORY={repository}
|
||||||
ENV RELEASE={codename}
|
ENV RELEASE={codename}
|
||||||
|
|
||||||
RUN mkdir $IMAGEDIR
|
RUN mkdir $IMAGEDIR
|
||||||
@ -47,7 +49,7 @@ def run_cmd(cmd):
|
|||||||
print(f"+ {cmd}")
|
print(f"+ {cmd}")
|
||||||
subprocess.run(cmd, shell=True, check=True, executable='/bin/bash')
|
subprocess.run(cmd, shell=True, check=True, executable='/bin/bash')
|
||||||
|
|
||||||
for version, codename in releases:
|
for version, codename, repository in releases:
|
||||||
numeric_version = version.replace('.', '')
|
numeric_version = version.replace('.', '')
|
||||||
img_version=version.replace(".","__")
|
img_version=version.replace(".","__")
|
||||||
|
|
||||||
@ -55,6 +57,7 @@ for version, codename in releases:
|
|||||||
version=version,
|
version=version,
|
||||||
img_version=img_version,
|
img_version=img_version,
|
||||||
codename=codename,
|
codename=codename,
|
||||||
|
repository=repository,
|
||||||
numeric_version=numeric_version)
|
numeric_version=numeric_version)
|
||||||
|
|
||||||
os.makedirs(str(version), exist_ok=True)
|
os.makedirs(str(version), exist_ok=True)
|
||||||
|
@ -11,6 +11,8 @@ sed -i '/PermitEmptyPasswords/d' $TMPDIR/etc/ssh/sshd_config
|
|||||||
echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
echo PermitEmptyPasswords yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
sed -i '/PermitRootLogin/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
echo PermitRootLogin yes >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
sed -i '/UseDNS/d' $TMPDIR/etc/ssh/sshd_config
|
||||||
|
echo UseDNS no >> $TMPDIR/etc/ssh/sshd_config
|
||||||
|
|
||||||
echo '#!/bin/sh' > $TMPDIR/etc/rc.local
|
echo '#!/bin/sh' > $TMPDIR/etc/rc.local
|
||||||
echo 'dhclient || dhcpcd' >> $TMPDIR/etc/rc.local
|
echo 'dhclient || dhcpcd' >> $TMPDIR/etc/rc.local
|
||||||
|
Reference in New Issue
Block a user