remove go part; prettify c code
This commit is contained in:
parent
1fa11f66e3
commit
ebc4311c86
21 changed files with 86 additions and 742 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,4 +6,5 @@
|
||||||
/starter/starter
|
/starter/starter
|
||||||
/starter/minrootfs
|
/starter/minrootfs
|
||||||
/pkg/go/gen
|
/pkg/go/gen
|
||||||
|
/gen
|
||||||
/runs
|
/runs
|
||||||
|
|
38
Makefile
38
Makefile
|
@ -1,19 +1,19 @@
|
||||||
all:
|
.PHONY: all clean install uninstall
|
||||||
make init
|
|
||||||
make mkrootfs
|
PROTOBUF=/usr/include/
|
||||||
make compile
|
STARTER=starter
|
||||||
make generate
|
GEN=gen
|
||||||
init:
|
SRCS=$(STARTER)/cgroup_prepare.c $(STARTER)/ns_exec.c $(STARTER)/util.c $(STARTER)/starter.c
|
||||||
git clone https://github.com/alpinelinux/alpine-make-rootfs
|
|
||||||
rm -rf starter/minrootfs
|
all: proto $(STARTER)/alpine-make-rootfs $(STARTER)/minrootfs $(STARTER)/starter
|
||||||
mv alpine-make-rootfs starter/alpine-make-rootfs
|
proto: /usr/include/google/protobuf/empty.proto proto/runner/v1/runner.proto
|
||||||
mkrootfs:
|
mkdir -p $(GEN)
|
||||||
starter/create_rootfs.sh
|
protoc --c_out=$(GEN) runner/v1/runner.proto -I proto
|
||||||
gen:
|
protoc --c_out=$(GEN) google/protobuf/empty.proto -I $(PROTOBUF)
|
||||||
buf generate
|
$(STARTER)/alpine-make-rootfs:
|
||||||
compile:
|
git clone https://github.com/alpinelinux/alpine-make-rootfs starter/alpine-make-rootfs
|
||||||
go build -o ./run
|
$(STARTER)/minrootfs: $(STARTER)/create_rootfs.sh
|
||||||
gcc starter/starter.c -o starter/starter
|
$(STARTER)/create_rootfs.sh
|
||||||
dev:
|
$(STARTER)/starter: proto $(STARTER)/starter.c $(STARTER)/cgroup_prepare.c $(STARTER)/ns_exec.c Makefile
|
||||||
@make gen
|
$(CC) -o $(STARTER)/starter $(SRCS) -g -fsanitize=address -fsanitize=leak -fno-omit-frame-pointer -lrabbitmq -lprotobuf-c -I gen
|
||||||
@go run main.go
|
#$(CC) $(STARTER)/starter.c -o $(STARTER)/starter
|
||||||
|
|
13
buf.gen.yaml
13
buf.gen.yaml
|
@ -1,13 +0,0 @@
|
||||||
version: v1
|
|
||||||
managed:
|
|
||||||
enabled: true
|
|
||||||
go_package_prefix:
|
|
||||||
default: git.sch9.ru/new_gate/ms-runner/pkg/go/gen
|
|
||||||
plugins:
|
|
||||||
- name: go
|
|
||||||
out: pkg/go/gen
|
|
||||||
opt: paths=source_relative
|
|
||||||
- name: go-grpc
|
|
||||||
out: pkg/go/gen
|
|
||||||
opt: paths=source_relative
|
|
||||||
|
|
7
buf.yaml
7
buf.yaml
|
@ -1,7 +0,0 @@
|
||||||
version: v1
|
|
||||||
breaking:
|
|
||||||
use:
|
|
||||||
- FILE
|
|
||||||
lint:
|
|
||||||
use:
|
|
||||||
- DEFAULT
|
|
|
@ -1,9 +0,0 @@
|
||||||
package config
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Env string `env:"ENV" env-default:"prod"`
|
|
||||||
|
|
||||||
RabbitDSN string `env:"RABBIT_DSN" required:"true"`
|
|
||||||
InstanceName string `env:"INSTANCE_NAME" required:"true"`
|
|
||||||
TQueueName string `env:"T_QUEUE_NAME" required:"true"`
|
|
||||||
}
|
|
29
go.mod
29
go.mod
|
@ -1,29 +0,0 @@
|
||||||
module git.sch9.ru/new_gate/ms-runner
|
|
||||||
|
|
||||||
go 1.21.3
|
|
||||||
|
|
||||||
toolchain go1.23.0
|
|
||||||
|
|
||||||
require (
|
|
||||||
git.sch9.ru/new_gate/ms-tester v0.0.0
|
|
||||||
github.com/containerd/cgroups v1.1.0
|
|
||||||
github.com/golang/protobuf v1.5.4
|
|
||||||
github.com/ilyakaznacheev/cleanenv v1.5.0
|
|
||||||
github.com/rabbitmq/amqp091-go v1.10.0
|
|
||||||
google.golang.org/protobuf v1.34.2
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4 // indirect
|
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.2 // indirect
|
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
|
|
||||||
)
|
|
78
go.sum
78
go.sum
|
@ -1,78 +0,0 @@
|
||||||
git.sch9.ru/new_gate/ms-tester v0.0.0 h1:ZR5YkHCO9JAY/d1qqEgwu/Dtru6iR1p3sIBqp8tetnA=
|
|
||||||
git.sch9.ru/new_gate/ms-tester v0.0.0/go.mod h1:gqA96jkobHh1HM/bksygv2AnxM+GkCqVAdgmJyC0rE0=
|
|
||||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
|
||||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
|
||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
|
||||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
|
||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
|
|
||||||
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
|
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
|
|
||||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
|
||||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
|
||||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
|
||||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ=
|
|
||||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw=
|
|
|
@ -1 +0,0 @@
|
||||||
package runner
|
|
|
@ -1,140 +0,0 @@
|
||||||
package rabbitmq
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.sch9.ru/new_gate/ms-runner/internal/runner"
|
|
||||||
"git.sch9.ru/new_gate/ms-runner/internal/runner/usecase"
|
|
||||||
runnerv1 "git.sch9.ru/new_gate/ms-runner/pkg/go/gen/proto/runner/v1"
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
amqp "github.com/rabbitmq/amqp091-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewRunnerBuilderConsumer(ch *amqp.Channel, runnerUC runner.RunnerUseCase, queueName string, instanceName string) {
|
|
||||||
msgs, err := ch.Consume(
|
|
||||||
queueName,
|
|
||||||
instanceName,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
runnerUC.Lock()
|
|
||||||
if !runnerUC.Ready() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
runnerUC.Unlock()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case d := <-msgs:
|
|
||||||
var msg runnerv1.Instruction
|
|
||||||
|
|
||||||
err = proto.Unmarshal(d.Body, &msg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch msg.Instruction.(type) {
|
|
||||||
case *runnerv1.Instruction_Build:
|
|
||||||
err = runnerUC.Process(usecase.BuildInstruction{
|
|
||||||
SolutionId: msg.GetBuild().GetSolutionId(),
|
|
||||||
BindingKey: msg.GetBuild().GetBindingKey(),
|
|
||||||
Language: msg.GetBuild().GetLanguage(),
|
|
||||||
Solution: msg.GetBuild().GetSolution(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
err = d.Ack(false)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case *runnerv1.Instruction_Run:
|
|
||||||
err = runnerUC.Process(usecase.RunInstruction{
|
|
||||||
SolutionId: msg.GetRun().GetSolutionId(),
|
|
||||||
TestId: msg.GetRun().GetTestId(),
|
|
||||||
BindingKey: msg.GetRun().GetBindingKey(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
} else {
|
|
||||||
err = d.Ack(false)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Println("unknown instruction: ", msg.Instruction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRunnerBuilderProducer(ch *amqp.Channel, runnerUC runner.RunnerUseCase) {
|
|
||||||
go func() {
|
|
||||||
for res := range runnerUC.Results() {
|
|
||||||
var (
|
|
||||||
body []byte
|
|
||||||
err error
|
|
||||||
bindingKey string
|
|
||||||
)
|
|
||||||
|
|
||||||
switch result := res.(type) {
|
|
||||||
case usecase.BuildResult:
|
|
||||||
msg := &runnerv1.Result{
|
|
||||||
Result: &runnerv1.Result_Build{
|
|
||||||
Build: &runnerv1.BuildResult{
|
|
||||||
SolutionId: result.SolutionId,
|
|
||||||
Status: result.Status,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
body, err = proto.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
bindingKey = result.BindingKey
|
|
||||||
case usecase.RunResult:
|
|
||||||
msg := &runnerv1.Result{
|
|
||||||
Result: &runnerv1.Result_Run{
|
|
||||||
Run: &runnerv1.RunResult{
|
|
||||||
SolutionId: result.SolutionId,
|
|
||||||
TestId: result.TestId,
|
|
||||||
Status: result.Status,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
body, err = proto.Marshal(msg)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
bindingKey = result.BindingKey
|
|
||||||
default:
|
|
||||||
fmt.Println("unknown result: ", result)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("publishing: ", bindingKey)
|
|
||||||
err = ch.Publish(
|
|
||||||
"",
|
|
||||||
bindingKey,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
amqp.Publishing{
|
|
||||||
ContentType: "text/plain",
|
|
||||||
Body: body,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package runner
|
|
||||||
|
|
||||||
type RunnerUseCase interface {
|
|
||||||
Process(i interface{}) error
|
|
||||||
Results() <-chan interface{}
|
|
||||||
Ready() bool
|
|
||||||
Lock()
|
|
||||||
Unlock()
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
package usecase
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BuildInstruction struct {
|
|
||||||
SolutionId int32
|
|
||||||
BindingKey string
|
|
||||||
Language int32
|
|
||||||
Solution string
|
|
||||||
}
|
|
||||||
|
|
||||||
type BuildResult struct {
|
|
||||||
SolutionId int32
|
|
||||||
BindingKey string
|
|
||||||
Status int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type RunInstruction struct {
|
|
||||||
SolutionId int32
|
|
||||||
TestId int32
|
|
||||||
BindingKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
type RunResult struct {
|
|
||||||
SolutionId int32
|
|
||||||
TestId int32
|
|
||||||
BindingKey string
|
|
||||||
Status int32
|
|
||||||
}
|
|
||||||
|
|
||||||
type RunnerUseCase struct {
|
|
||||||
freeProcesses int32
|
|
||||||
mtx sync.RWMutex
|
|
||||||
results chan interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRunnerUseCase(limit int32) *RunnerUseCase {
|
|
||||||
return &RunnerUseCase{
|
|
||||||
freeProcesses: limit,
|
|
||||||
results: make(chan interface{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (uc *RunnerUseCase) Process(i interface{}) error {
|
|
||||||
uc.mtx.Lock()
|
|
||||||
defer uc.mtx.Unlock()
|
|
||||||
if uc.freeProcesses == 0 {
|
|
||||||
return errors.New("no free processes")
|
|
||||||
}
|
|
||||||
uc.freeProcesses--
|
|
||||||
|
|
||||||
go func(i interface{}) {
|
|
||||||
defer func() {
|
|
||||||
uc.mtx.Lock()
|
|
||||||
uc.freeProcesses++
|
|
||||||
uc.mtx.Unlock()
|
|
||||||
}()
|
|
||||||
|
|
||||||
switch instruction := i.(type) {
|
|
||||||
case RunInstruction:
|
|
||||||
fmt.Println("running: ", instruction.SolutionId, instruction.TestId)
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
uc.results <- RunResult{
|
|
||||||
SolutionId: instruction.SolutionId,
|
|
||||||
TestId: instruction.TestId,
|
|
||||||
BindingKey: instruction.BindingKey,
|
|
||||||
Status: 0,
|
|
||||||
}
|
|
||||||
case BuildInstruction:
|
|
||||||
fmt.Println("building:", instruction.Language, instruction.Solution)
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
uc.results <- BuildResult{
|
|
||||||
SolutionId: instruction.SolutionId,
|
|
||||||
BindingKey: instruction.BindingKey,
|
|
||||||
Status: -1,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Println("unknown instruction ignored")
|
|
||||||
}
|
|
||||||
}(i)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (uc *RunnerUseCase) Results() <-chan interface{} {
|
|
||||||
return uc.results
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ready is not thread safe!
|
|
||||||
func (uc *RunnerUseCase) Ready() bool {
|
|
||||||
return uc.freeProcesses > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (uc *RunnerUseCase) Lock() {
|
|
||||||
uc.mtx.Lock()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (uc *RunnerUseCase) Unlock() {
|
|
||||||
uc.mtx.Unlock()
|
|
||||||
}
|
|
49
main.go
49
main.go
|
@ -1,49 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.sch9.ru/new_gate/ms-runner/config"
|
|
||||||
runnerPubSub "git.sch9.ru/new_gate/ms-runner/internal/runner/delivery/rabbitmq"
|
|
||||||
runnerUseCase "git.sch9.ru/new_gate/ms-runner/internal/runner/usecase"
|
|
||||||
"git.sch9.ru/new_gate/ms-runner/pkg/external/rabbitmq"
|
|
||||||
"github.com/ilyakaznacheev/cleanenv"
|
|
||||||
"os"
|
|
||||||
"os/signal"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var cfg config.Config
|
|
||||||
err := cleanenv.ReadConfig(".env", &cfg)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("error reading config: %s", err.Error()))
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := rabbitmq.NewRabbitClient(cfg.RabbitDSN)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
ch, err := conn.Channel()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer ch.Close()
|
|
||||||
err = ch.Qos(
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
runnerUC := runnerUseCase.NewRunnerUseCase(10)
|
|
||||||
runnerPubSub.NewRunnerBuilderProducer(ch, runnerUC)
|
|
||||||
runnerPubSub.NewRunnerBuilderConsumer(ch, runnerUC, cfg.TQueueName, cfg.InstanceName)
|
|
||||||
|
|
||||||
stop := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)
|
|
||||||
|
|
||||||
<-stop
|
|
||||||
}
|
|
7
pkg/external/rabbitmq/client.go
vendored
7
pkg/external/rabbitmq/client.go
vendored
|
@ -1,7 +0,0 @@
|
||||||
package rabbitmq
|
|
||||||
|
|
||||||
import amqp "github.com/rabbitmq/amqp091-go"
|
|
||||||
|
|
||||||
func NewRabbitClient(dsn string) (*amqp.Connection, error) {
|
|
||||||
return amqp.Dial(dsn)
|
|
||||||
}
|
|
183
runner/runner.go
183
runner/runner.go
|
@ -1,183 +0,0 @@
|
||||||
//go:build wtf
|
|
||||||
// just use https://github.com/opencontainers/runc please
|
|
||||||
|
|
||||||
|
|
||||||
package runner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
exec "os/exec"
|
|
||||||
cgroups "github.com/containerd/cgroups"
|
|
||||||
rand "math/rand"
|
|
||||||
"time"
|
|
||||||
"git.sch9.ru/new_gate/ms-tester/pkg/models"
|
|
||||||
)
|
|
||||||
|
|
||||||
const runIdLength = 20
|
|
||||||
|
|
||||||
type Limits struct {
|
|
||||||
Processes int32
|
|
||||||
Core int32
|
|
||||||
Memory int32
|
|
||||||
Time int32
|
|
||||||
}
|
|
||||||
|
|
||||||
const Mib = 1024*1024;
|
|
||||||
const BuildMemory = 1024*Mib;
|
|
||||||
const BuildTime = 5000;
|
|
||||||
|
|
||||||
type RunnerService struct {
|
|
||||||
CoresIsolated []int32
|
|
||||||
CoreFreed chan int32
|
|
||||||
}
|
|
||||||
|
|
||||||
func genRunId() (runId string) {
|
|
||||||
for i := 0; i < runIdLength; i++ {
|
|
||||||
runId += string('a' + byte(rand.Int31n(26)))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func int32ToString(n int32) string {
|
|
||||||
return fmt.Sprintf("%d", n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyFile(src string,dst string) error {
|
|
||||||
srcFile,err := os.Open(src)
|
|
||||||
if(err!=nil) {return err}
|
|
||||||
defer srcFile.Close()
|
|
||||||
dstFile,err := os.Create(dst)
|
|
||||||
if(err!=nil) {return err}
|
|
||||||
defer dstFile.Close()
|
|
||||||
_,err = io.Copy(dstFile,srcFile)
|
|
||||||
if(err!=nil) {return err}
|
|
||||||
err = dstFile.Sync()
|
|
||||||
if(err!=nil) {return err}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRunFolder() (string,error) {
|
|
||||||
runId := genRunId()
|
|
||||||
err := os.Mkdir("runs/" + runId, 0777)
|
|
||||||
if(err!=nil) { return "",err }
|
|
||||||
err = os.Chmod("runs/" + runId, 0777)
|
|
||||||
if(err!=nil) { return "",err }
|
|
||||||
return runId,nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractNumbers(s string) (result []int32) {
|
|
||||||
lastNumber, isNumber := false,false
|
|
||||||
var curNumber int32 = 0
|
|
||||||
for _, char := range s {
|
|
||||||
isNumber = (char >= '0' && char <= '9')
|
|
||||||
if(isNumber) {
|
|
||||||
curNumber *= 10
|
|
||||||
curNumber += int32(char - '0')
|
|
||||||
}
|
|
||||||
if(!isNumber && lastNumber) {
|
|
||||||
result = append(result, curNumber)
|
|
||||||
curNumber = 0
|
|
||||||
}
|
|
||||||
lastNumber = isNumber
|
|
||||||
}
|
|
||||||
if(lastNumber) {
|
|
||||||
result = append(result, curNumber)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRunnerService() (*RunnerService, error) {
|
|
||||||
runnerService := RunnerService{make([]int32,0),make(chan int32)}
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
|
||||||
//croup initialisation:
|
|
||||||
if cgroups.Mode() == cgroups.Unified {
|
|
||||||
log.Println("cgroups v2 usage approved")
|
|
||||||
} else {
|
|
||||||
return nil,fmt.Errorf("cgroups v2 are not enabled")//TODO: trouble description
|
|
||||||
}
|
|
||||||
//isolated cores initialisation:
|
|
||||||
cmdlineBytes := make([]byte, 400)
|
|
||||||
cmdlineFile, _ := os.Open("/proc/cmdline");
|
|
||||||
countCmdlineBytes, _ := cmdlineFile.Read(cmdlineBytes);
|
|
||||||
cmdline := string(cmdlineBytes[:countCmdlineBytes])
|
|
||||||
kernelParams := strings.Split(cmdline," ")
|
|
||||||
for _, param := range kernelParams{
|
|
||||||
if(len(param) >= 9 && param[:9] == "isolcpus=") {
|
|
||||||
runnerService.CoresIsolated = append(runnerService.CoresIsolated, extractNumbers(param[9:])...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(len(runnerService.CoresIsolated) == 0) {
|
|
||||||
return nil,fmt.Errorf("no free cores available")//TODO: trouble description
|
|
||||||
}
|
|
||||||
go func() {
|
|
||||||
for _,core := range runnerService.CoresIsolated {
|
|
||||||
runnerService.CoreFreed <- core
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
log.Println("running on cores:", runnerService.CoresIsolated)
|
|
||||||
//runs directory
|
|
||||||
os.Mkdir("runs",0777)
|
|
||||||
os.Chmod("runs",0777)
|
|
||||||
//complete
|
|
||||||
log.Println("Runner initialisation successful!")
|
|
||||||
return &runnerService,nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (runnerService RunnerService) Build(languageId int32, filename string) {
|
|
||||||
core := <-runnerService.CoreFreed
|
|
||||||
runId,err := newRunFolder()
|
|
||||||
if(err!=nil) {log.Fatal
|
|
||||||
copyFile(filename,"runs/"+runId+"/src")
|
|
||||||
runnerService.IsolatedRun(models.Languages[languageId].CompileCmd,"../runs/"+runId,Limits{Processes: 10,Core:core,Memory:BuildMemory,Time:BuildTime});
|
|
||||||
copyFile("runs/"+runId+"/executable","executable")
|
|
||||||
os.RemoveAll("runs/" + runId)
|
|
||||||
go func() {
|
|
||||||
runnerService.CoreFreed <- core
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (runnerService RunnerService) RunTest(solutionLanguageId int32, solutionFilename string, inputFilename string, checkerLanguageId int32, checkerFilename string, limits Limits) (models.Result) {
|
|
||||||
core := <-runnerService.CoreFreed
|
|
||||||
testRunId,err := newRunFolder()
|
|
||||||
if(err!=nil) {log.Fatal
|
|
||||||
copyFile(solutionFilename,"runs/"+testRunId+"/executable")
|
|
||||||
copyFile(inputFilename,"runs/"+testRunId+"/in")
|
|
||||||
code,err = runnerService.IsolatedRun(models.Languages[languageId].RunCmd,"../runs/"+testRunId,limits);
|
|
||||||
defer os.RemoveAll("runs/" + testRunId)
|
|
||||||
if(err!=nil) {log.Fatal(err);}
|
|
||||||
if(code!=0) {return models.RuntimeError}
|
|
||||||
checkRunId,err := newRunFolder()
|
|
||||||
copyFile("runs/"+testRunId+"/out","runs/"+checkRunId+"/out")
|
|
||||||
err = runnerService.IsolatedRun(models.Languages[languageId].RunCmd,"../runs/"+checkRunId,Limits{Processes: 10,Core:core,Memory:BuildMemory,Time:BuildTime}); //FIXME add input/output/answer files options
|
|
||||||
defer os.RemoveAll("runs/" + checkRunId)
|
|
||||||
if(err!=nil) {log.Fatal(err);}
|
|
||||||
switch code {
|
|
||||||
case 0: return models.Accepted //FIXME add model constants
|
|
||||||
case 1: return models.WrongAnswer
|
|
||||||
case 2: return models.PresentationError
|
|
||||||
case 3: return models.SystemFailDuringTesting
|
|
||||||
}
|
|
||||||
return models.SystemFailDuringTesting //bad checker result is a system fail
|
|
||||||
go func() {
|
|
||||||
runnerService.CoreFreed <- core
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (runnerService RunnerService) IsolatedRun(command []string, sharedFolder string, limits Limits) (int32,error) {
|
|
||||||
args := []string{int32ToString(limits.Processes),int32ToString(limits.Core), int32ToString(limits.Memory), int32ToString(limits.Time), sharedFolder}
|
|
||||||
args = append(args, command...)
|
|
||||||
log.Println("running isolated process with command:",args)
|
|
||||||
cmd := exec.Command("starter/starter", args...)
|
|
||||||
err := cmd.Run();
|
|
||||||
if errors.Is(err,exec.ExitError) {
|
|
||||||
return err.ProcessState.ExitCode,nil
|
|
||||||
} else if(err!=nil) {
|
|
||||||
return 0,err
|
|
||||||
}
|
|
||||||
return 0,nil
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
//go:build wtf
|
|
||||||
|
|
||||||
package runner
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ENTestPair struct {
|
|
||||||
test string
|
|
||||||
result []int
|
|
||||||
}
|
|
||||||
|
|
||||||
var ENTests = []ENTestPair{
|
|
||||||
{"123", []int{123}},
|
|
||||||
{"abc123abc", []int{123}},
|
|
||||||
{"", []int{}},
|
|
||||||
{"0", []int{0}},
|
|
||||||
{"1a2a3a6", []int{1, 2, 3, 6}},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExtractNumbers(t *testing.T) {
|
|
||||||
for _, test := range ENTests {
|
|
||||||
result := extractNumbers(test.test)
|
|
||||||
if len(result) != len(test.result) {
|
|
||||||
t.Error("for", test.test, "expected", test.result, "got", result)
|
|
||||||
}
|
|
||||||
for i := 0; i < len(result); i++ {
|
|
||||||
if result[i] != test.result[i] {
|
|
||||||
t.Error("for", test.test, "expected", test.result, "got", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,4 @@
|
||||||
#include<sys/prctl.h>
|
#include "starter.h"
|
||||||
#include<sys/mount.h>
|
|
||||||
#include<sys/stat.h>
|
|
||||||
#include<unistd.h>
|
|
||||||
#include<linux/limits.h>
|
|
||||||
|
|
||||||
#define CGROUP_NAME_SIZE 20
|
#define CGROUP_NAME_SIZE 20
|
||||||
char cgroup_name[CGROUP_NAME_SIZE+1];
|
char cgroup_name[CGROUP_NAME_SIZE+1];
|
||||||
|
@ -74,3 +70,4 @@ void remove_cgroup() {
|
||||||
rmdir(cgroup_name);
|
rmdir(cgroup_name);
|
||||||
chdir(cwd);
|
chdir(cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,5 +13,4 @@ rm -rf $SCRIPT_DIR/$NAME
|
||||||
$SCRIPT_DIR/alpine-make-rootfs/alpine-make-rootfs --packages 'python3 gcc libc-dev' $SCRIPT_DIR/$NAME
|
$SCRIPT_DIR/alpine-make-rootfs/alpine-make-rootfs --packages 'python3 gcc libc-dev' $SCRIPT_DIR/$NAME
|
||||||
#chown -R nobody:nogroup $SCRIPT_DIR/$NAME
|
#chown -R nobody:nogroup $SCRIPT_DIR/$NAME
|
||||||
#rm -r ../$NAME
|
#rm -r ../$NAME
|
||||||
#mv $NAME ../$NAME
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include<sys/prctl.h>
|
#include "starter.h"
|
||||||
#include<sys/mount.h>
|
|
||||||
#include<sys/stat.h>
|
|
||||||
|
|
||||||
static void procfs_prepare()
|
void procfs_prepare()
|
||||||
{
|
{
|
||||||
if (mkdir("/proc", 0555) && errno != EEXIST) die("Failed to mkdir /proc: %m\n");
|
if (mkdir("/proc", 0555) && errno != EEXIST) die("Failed to mkdir /proc: %m\n");
|
||||||
if (mount("proc", "/proc", "proc", 0, "")) die("Failed to mount proc: %m\n");
|
if (mount("proc", "/proc", "proc", 0, "")) die("Failed to mount proc: %m\n");
|
||||||
|
@ -43,7 +41,7 @@ void await_setup(int pipe) { // wait for signal from parent
|
||||||
if (read(pipe, buf, 2) != 2) die("Failed to read from pipe: %m\n");
|
if (read(pipe, buf, 2) != 2) die("Failed to read from pipe: %m\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nsrun(void* arg) {
|
int nsrun(void* arg) {
|
||||||
//die when parent dies
|
//die when parent dies
|
||||||
if (prctl(PR_SET_PDEATHSIG, SIGKILL)) die("cannot PR_SET_PDEATHSIG for child process: %m\n");
|
if (prctl(PR_SET_PDEATHSIG, SIGKILL)) die("cannot PR_SET_PDEATHSIG for child process: %m\n");
|
||||||
struct params *params = (struct params*) arg;
|
struct params *params = (struct params*) arg;
|
||||||
|
|
|
@ -1,43 +1,4 @@
|
||||||
#define _GNU_SOURCE
|
#include "starter.h"
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
struct params {
|
|
||||||
char* shared_folder;
|
|
||||||
int fd[2];
|
|
||||||
int out_fd;
|
|
||||||
char **argv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct limits {
|
|
||||||
size_t memory;
|
|
||||||
int core;
|
|
||||||
int time;
|
|
||||||
int processes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct killparams{
|
|
||||||
int time;
|
|
||||||
int pid;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "ns_exec.c"
|
|
||||||
#include "cgroup_prepare.c"
|
|
||||||
|
|
||||||
uint64_t time_start;
|
uint64_t time_start;
|
||||||
|
|
||||||
|
@ -107,8 +68,8 @@ static void prepare_userns(int pid) {
|
||||||
write_file(path, line);
|
write_file(path, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_real_path(char* path) {
|
static void get_real_path(char* path, char* call_str) {
|
||||||
if (realpath (argv[0], path) == 0) die("unable to resolve real path: %m");// get absolute path to executable
|
if (realpath (call_str, path) == 0) die("unable to resolve real path: %m");// get absolute path to executable
|
||||||
for(int i = strlen(path); i > 0 && path[i] != '/';i--) path[i]=0;// cut filename to get directory name
|
for(int i = strlen(path); i > 0 && path[i] != '/';i--) path[i]=0;// cut filename to get directory name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +78,7 @@ int main(int argc,char** argv) {
|
||||||
if(setgid(0)) die("must be run as root");
|
if(setgid(0)) die("must be run as root");
|
||||||
// get binary path
|
// get binary path
|
||||||
char real_path[PATH_MAX];
|
char real_path[PATH_MAX];
|
||||||
get_real_path(real_path);
|
get_real_path(real_path, argv[0]);
|
||||||
if(chdir(real_path)) die("unable to chdir to binary path: %m");
|
if(chdir(real_path)) die("unable to chdir to binary path: %m");
|
||||||
// set random seed
|
// set random seed
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
53
starter/starter.h
Normal file
53
starter/starter.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#define die(...) {fprintf(stderr,"file %s,line %d\n",__FILE__,__LINE__);die_func(__VA_ARGS__);exit(1);}
|
||||||
|
void remove_cgroup();
|
||||||
|
|
||||||
|
struct params {
|
||||||
|
char* shared_folder;
|
||||||
|
int fd[2];
|
||||||
|
int out_fd;
|
||||||
|
char **argv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct limits {
|
||||||
|
size_t memory;
|
||||||
|
int core;
|
||||||
|
int time;
|
||||||
|
int processes;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct killparams{
|
||||||
|
int time;
|
||||||
|
int pid;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void prepare_cgroup(struct limits* limits);
|
||||||
|
extern void add_to_cgroup(int pid);
|
||||||
|
extern int check_mem();
|
||||||
|
extern void remove_cgroup();
|
||||||
|
extern void procfs_prepare();
|
||||||
|
extern void await_setup(int pipe);
|
||||||
|
extern int nsrun(void* arg);
|
||||||
|
extern void die_func(const char *fmt, ...);
|
||||||
|
extern void write_file(char* path, char* line);
|
|
@ -1,18 +1,17 @@
|
||||||
#define die(...) {fprintf(stderr,"file %s,line %d\n",__FILE__,__LINE__);die_func(__VA_ARGS__);}
|
#include "starter.h"
|
||||||
void remove_cgroup();
|
|
||||||
|
|
||||||
static void die_func(const char *fmt, ...)
|
void die_func(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list params;
|
va_list params;
|
||||||
va_start(params, fmt);
|
va_start(params, fmt);
|
||||||
vfprintf(stderr, fmt, params);
|
vfprintf(stderr, fmt, params);
|
||||||
puts("\n");
|
puts("\n");
|
||||||
va_end(params);
|
va_end(params);
|
||||||
remove_cgroup();
|
//remove_cgroup();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_file(char* path, char* line)
|
void write_file(char* path, char* line)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(path, "w");
|
FILE *f = fopen(path, "w");
|
||||||
if (f == NULL) {die("Failed to open file %s: %m\n", path);}
|
if (f == NULL) {die("Failed to open file %s: %m\n", path);}
|
Loading…
Reference in a new issue