forked from vieter-v/vieter
				
			Working build example!!
							parent
							
								
									5515e2dca5
								
							
						
					
					
						commit
						4f705f5fb5
					
				
							
								
								
									
										60
									
								
								src/build.v
								
								
								
								
							
							
						
						
									
										60
									
								
								src/build.v
								
								
								
								
							|  | @ -1,8 +1,66 @@ | |||
| module main | ||||
| 
 | ||||
| import docker | ||||
| import encoding.base64 | ||||
| import rand | ||||
| 
 | ||||
| const container_build_dir = '/build' | ||||
| 
 | ||||
| struct GitRepo { | ||||
| 	url string [required] | ||||
| 	branch string [required] | ||||
| } | ||||
| 
 | ||||
| fn build() { | ||||
| 	println(docker.pull('nginx', 'latest') or { panic('yeetus') }) | ||||
| 	// println(docker.pull('nginx', 'latest') or { panic('yeetus') }) | ||||
| 	// println(docker.containers() or { panic('heet') }) | ||||
| 	repos := [ | ||||
| 		GitRepo{'https://git.rustybever.be/Chewing_Bever/st', 'master'} | ||||
| 		GitRepo{'https://aur.archlinux.org/libxft-bgra.git', 'master'} | ||||
| 	] | ||||
| 	mut uuids := []string{} | ||||
| 
 | ||||
| 	mut commands := [ | ||||
| 		// Update repos & install required packages | ||||
| 		'pacman -Syu --needed --noconfirm base-devel git' | ||||
| 		// Add a non-root user to run makepkg | ||||
| 		'groupadd -g 1000 builder' | ||||
| 		'useradd -mg builder builder' | ||||
| 		// Make sure they can use sudo without a password | ||||
| 		"echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers" | ||||
| 		// Create the directory for the builds & make it writeable for the | ||||
| 		// build user | ||||
| 		'mkdir /build' | ||||
| 		'chown -R builder:builder /build' | ||||
| 		// "su builder -c 'git clone https://git.rustybever.be/Chewing_Bever/st /build/st'" | ||||
| 		// 'su builder -c \'cd /build/st && makepkg -s --noconfirm --needed && for pkg in \$(ls -1 *.pkg*); do curl -XPOST -T "\${pkg}" -H "X-API-KEY: \$API_KEY" https://arch.r8r.be/publish; done\'' | ||||
| 	] | ||||
| 
 | ||||
| 	for repo in repos { | ||||
| 		mut uuid := rand.uuid_v4() | ||||
| 
 | ||||
| 		// Just to be sure we don't have any collisions | ||||
| 		for uuids.contains(uuid) { | ||||
| 			uuid = rand.uuid_v4() | ||||
| 		} | ||||
| 
 | ||||
| 		uuids << uuid | ||||
| 
 | ||||
| 		commands << "su builder -c 'git clone --single-branch --depth 1 --branch $repo.branch $repo.url /build/$uuid'" | ||||
| 		commands << 'su builder -c \'cd /build/$uuid && makepkg -s --noconfirm --needed && for pkg in \$(ls -1 *.pkg*); do curl -XPOST -T "\${pkg}" -H "X-API-KEY: \$API_KEY" https://arch.r8r.be/publish; done\'' | ||||
| 	} | ||||
| 	println(commands) | ||||
| 
 | ||||
| 	// We convert the list of commands into a base64 string | ||||
| 	cmds_str := base64.encode_str(commands.join('\n')) | ||||
| 
 | ||||
| 	c := docker.NewContainer{ | ||||
| 		image: 'archlinux:latest' | ||||
| 		env: ['BUILD_SCRIPT=$cmds_str'] | ||||
| 		entrypoint: ['/bin/sh', '-c'] | ||||
| 		cmd: ['echo \$BUILD_SCRIPT | base64 -d | /bin/sh -e'] | ||||
| 	} | ||||
| 
 | ||||
| 	id := docker.create_container(c) or { panic('aaaahh') } | ||||
| 	print(docker.start_container(id) or { panic('yikes') }) | ||||
| } | ||||
|  |  | |||
|  | @ -9,7 +9,35 @@ struct Container { | |||
| } | ||||
| 
 | ||||
| pub fn containers() ?[]Container { | ||||
| 	res := get(urllib.parse('/containers/json') ?) ? | ||||
| 	res := request('GET', urllib.parse('/containers/json') ?) ? | ||||
| 
 | ||||
| 	return json.decode([]Container, res.text) or {} | ||||
| } | ||||
| 
 | ||||
| pub struct NewContainer { | ||||
| 	image string [json: Image] | ||||
| 	entrypoint []string [json: Entrypoint] | ||||
| 	cmd []string [json: Cmd] | ||||
| 	env []string [json: Env] | ||||
| } | ||||
| 
 | ||||
| struct CreatedContainer { | ||||
| 	id string [json: Id] | ||||
| } | ||||
| 
 | ||||
| pub fn create_container(c &NewContainer) ?string { | ||||
| 	res := request_with_json('POST', urllib.parse('/containers/create') ?, c) ? | ||||
| 
 | ||||
| 	if res.status_code != 201 { | ||||
| 		return error('Failed to create container.') | ||||
| 	} | ||||
| 
 | ||||
| 	return json.decode(CreatedContainer, res.text) ?.id | ||||
| } | ||||
| 
 | ||||
| pub fn start_container(id string) ?bool { | ||||
| 	res := request('POST', urllib.parse('/containers/$id/start') ?) ? | ||||
| 	println(res) | ||||
| 
 | ||||
| 	return res.status_code == 204 | ||||
| } | ||||
|  |  | |||
|  | @ -64,8 +64,8 @@ fn send(req &string) ?http.Response { | |||
| 	return http.parse_response(res.bytestr()) | ||||
| } | ||||
| 
 | ||||
| fn request_with_body(method string, url urllib.URL, body &string) ?http.Response { | ||||
| 	req := '$method $url.request_uri() HTTP/1.1\nHost: localhost\nContent-Length: $body.len\n$body\n' | ||||
| fn request_with_body(method string, url urllib.URL, content_type string, body string) ?http.Response { | ||||
| 	req := '$method $url.request_uri() HTTP/1.1\nHost: localhost\nContent-Type: ${content_type}\nContent-Length: $body.len\n\n$body\n\n' | ||||
| 
 | ||||
| 	return send(req) | ||||
| } | ||||
|  | @ -76,19 +76,10 @@ fn request(method string, url urllib.URL) ?http.Response { | |||
| 	return send(req) | ||||
| } | ||||
| 
 | ||||
| pub fn request_with_json<T>(method string, url urllib.URL, data T) ?http.Response { | ||||
| pub fn request_with_json<T>(method string, url urllib.URL, data &T) ?http.Response { | ||||
| 	body := json.encode(data) | ||||
| 
 | ||||
| 	return request_with_body(method, url, body) | ||||
| } | ||||
| 
 | ||||
| fn get(url urllib.URL) ?http.Response { | ||||
| 	return request('GET', url) | ||||
| } | ||||
| 
 | ||||
| struct ImagePull { | ||||
| 	from_image string [json: fromImage] | ||||
| 	tag        string | ||||
| 	return request_with_body(method, url, 'application/json', body) | ||||
| } | ||||
| 
 | ||||
| pub fn pull(image string, tag string) ?http.Response { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue