add packer ubuntu board generator
This commit is contained in:
parent
a3403b0fc3
commit
6943facc81
|
@ -1 +1,6 @@
|
|||
packer/build
|
||||
packer/build
|
||||
bazel-bin
|
||||
bazel-bladerunner
|
||||
bazel-out
|
||||
.gitignore
|
||||
bazel-testlogs
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
|
||||
# gazelle:prefix git.wntrmute.dev/kyle/bladerunner
|
||||
gazelle(name = "gazelle")
|
42
WORKSPACE
42
WORKSPACE
|
@ -1,9 +1,43 @@
|
|||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
## C++ dependencies
|
||||
# http_archive(
|
||||
# name = "gtest",
|
||||
# url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
|
||||
# sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
|
||||
# build_file = "@//:gtest.BUILD",
|
||||
# )
|
||||
|
||||
http_archive(
|
||||
name = "gtest",
|
||||
url = "https://github.com/google/googletest/archive/release-1.10.0.zip",
|
||||
sha256 = "94c634d499558a76fa649edb13721dce6e98fb1e7018dfaeba3cd7a083945e91",
|
||||
build_file = "@//:gtest.BUILD",
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "6b65cb7917b4d1709f9410ffe00ecf3e160edf674b78c54a894471320862184f",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.39.0/rules_go-v0.39.0.zip",
|
||||
],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_gazelle",
|
||||
sha256 = "ecba0f04f96b4960a5b250c8e8eeec42281035970aa8852dda73098274d14a1d",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.29.0/bazel-gazelle-v0.29.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
|
||||
|
||||
############################################################
|
||||
# Define your own dependencies here using go_repository.
|
||||
# Else, dependencies declared by rules_go/gazelle will be used.
|
||||
# The first declaration of an external repository "wins".
|
||||
############################################################
|
||||
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(version = "1.20.3")
|
||||
|
||||
gazelle_dependencies()
|
|
@ -0,0 +1,8 @@
|
|||
module git.wntrmute.dev/kyle/bladerunner
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
git.sr.ht/~kisom/goutils v1.5.3
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
|
@ -0,0 +1,94 @@
|
|||
bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4=
|
||||
git.sr.ht/~kisom/goutils v1.5.3 h1:Q0BI2Q8/gs5uYdi2e2op4uRt9hTLt5zgH9HdGDcx4pM=
|
||||
git.sr.ht/~kisom/goutils v1.5.3/go.mod h1:azq1B7nq8lmva1FWeuw+tZ6xdJZCtJIlFskB3N2v9E4=
|
||||
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
|
||||
github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4=
|
||||
github.com/cloudflare/backoff v0.0.0-20161212185259-647f3cdfc87a/go.mod h1:rzgs2ZOiguV6/NpiDgADjRLPNyZlApIWxKpkT+X8SdY=
|
||||
github.com/cloudflare/cfssl v1.5.0/go.mod h1:sPPkBS5L8l8sRc/IOO1jG51Xb34u+TYhL6P//JdODMQ=
|
||||
github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4=
|
||||
github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/getsentry/raven-go v0.0.0-20180121060056-563b81fc02b7/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jmhodges/clock v0.0.0-20160418191101-880ee4c33548/go.mod h1:hGT6jSUVzF6no3QaDSMLGLEHtHSBSefs+MgcDWnmhmo=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
|
||||
github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/go-gypsy v0.0.0-20160905020020-08cad365cd28/go.mod h1:T/T7jsxVqf9k/zYOqbgNAsANsjxTd1Yq3htjDhQ1H0c=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8=
|
||||
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.12.0/go.mod h1:fUqqXB5vEgVCZ131L+9say31RAri6aF6KDViawhxKK8=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/weppos/publicsuffix-go v0.4.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
|
||||
github.com/weppos/publicsuffix-go v0.13.0/go.mod h1:z3LCPQ38eedDQSwmsSRW4Y7t2L8Ln16JPQ02lHAdn5k=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
|
||||
github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is=
|
||||
github.com/zmap/zcrypto v0.0.0-20200513165325-16679db567ff/go.mod h1:TxpejqcVKQjQaVVmMGfzx5HnmFMdIU+vLtaCyPBfGI4=
|
||||
github.com/zmap/zcrypto v0.0.0-20200911161511-43ff0ea04f21/go.mod h1:TxpejqcVKQjQaVVmMGfzx5HnmFMdIU+vLtaCyPBfGI4=
|
||||
github.com/zmap/zlint/v2 v2.2.1/go.mod h1:ixPWsdq8qLxYRpNUTbcKig3R7WgmspsHGLhCCs6rFAM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200124225646-8b5121be2f68/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
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-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -11,7 +11,7 @@ errmsg () {
|
|||
|
||||
preflight () {
|
||||
case "${IMAGE_TYPE}" in
|
||||
ubuntu) PACKER_BUILD_FILE="boards/raspberry-pi-4/ubuntu_server_20.04_arm64.json" ;;
|
||||
ubuntu) PACKER_BUILD_FILE="boards/pi-cm4-ubuntu-22.04.2.json" ;;
|
||||
raspbian) PACKER_BUILD_FILE="boards/raspberry-pi/raspios-lite-arm.json" ;;
|
||||
custom)
|
||||
PACKER_BUILD_FILE="${2:-}"
|
||||
|
@ -33,7 +33,6 @@ preflight () {
|
|||
}
|
||||
|
||||
build_image () {
|
||||
cd build/packer-builder-arm
|
||||
sudo packer build ${PACKER_BUILD_FILE}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
echo "==> Setting nameserver"
|
||||
echo 'nameserver 8.8.8.8' > /etc/resolv.conf
|
||||
|
||||
echo "==> installing base updates"
|
||||
apt-get -y update
|
||||
apt-get -y install ansible apt-transport-https ca-certificates
|
||||
apt-get -y clean
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
IMAGE_TYPE="${1:-ubuntu}"
|
||||
|
||||
select_image () {
|
||||
case "${IMAGE_TYPE}" in
|
||||
ubuntu)
|
||||
PACKER_BUILD_FILE="boards/pi-cm4-ubuntu-22.04.2.json" ;;
|
||||
REMOTE_IMAGE_URL="$(jq '.builders[0].file_urls' boards/pi-cm4-ubuntu-22.04.2.json | grep https | tr -d ' \"')"
|
||||
|
||||
raspbian) PACKER_BUILD_FILE="boards/raspberry-pi/raspios-lite-arm.json" ;;
|
||||
PACKER_BUILD_FILE="boards/pi-cm4-ubuntu-22.04.2.json" ;;
|
||||
REMOTE_IMAGE_URL="$(jq '.builders[0].file_urls' boards/pi-cm4-ubuntu-22.04.2.json | grep https | tr -d ' \"')"
|
||||
|
||||
custom)
|
||||
PACKER_BUILD_FILE="${2:-}"
|
||||
if [ -z "${PACKER_BUILD_FILE}" ]
|
||||
then
|
||||
errmsg "[!] custom board requires a board file path"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
errmsg "[!] invalid image type ${IMAGE_TYPE}."
|
||||
errmsg "[!] valid image types are"
|
||||
errmsg " - raspbian"
|
||||
errmsg " - ubuntu"
|
||||
errmsg " - custom path/to/board/file"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "ubuntu-board-gen_lib",
|
||||
srcs = ["main.go"],
|
||||
importpath = "git.wntrmute.dev/kyle/bladerunner/src/cmd/ubuntu-board-gen",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//src/packer",
|
||||
"@ht_sr_git_kisom_goutils//die:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "ubuntu-board-gen",
|
||||
embed = [":ubuntu-board-gen_lib"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"git.sr.ht/~kisom/goutils/die"
|
||||
"git.wntrmute.dev/kyle/bladerunner/src/packer"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var specFile, outputDir string
|
||||
|
||||
flag.StringVar(&specFile, "f", "ubuntu-boards.yml", "`path` to Ubuntu board spec file")
|
||||
flag.StringVar(&outputDir, "o", "", "`directory` to store Ubuntu boards")
|
||||
flag.Parse()
|
||||
|
||||
boardSpecs, err := packer.LoadUbuntuSpecs(specFile)
|
||||
die.If(err)
|
||||
|
||||
err = boardSpecs.WriteBoards(outputDir)
|
||||
die.If(err)
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "packer",
|
||||
srcs = [
|
||||
"board.go",
|
||||
"builder.go",
|
||||
"packer.go",
|
||||
"provisioner.go",
|
||||
"ubuntu.go",
|
||||
],
|
||||
importpath = "git.wntrmute.dev/kyle/bladerunner/src/packer",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@in_gopkg_yaml_v2//:go_default_library"],
|
||||
)
|
|
@ -0,0 +1,8 @@
|
|||
package packer
|
||||
|
||||
type Board struct {
|
||||
Variables interface{} `json:"variables"`
|
||||
Builders []Builder `json:"builders"`
|
||||
Provisioners []Provisioner `json:"provisioners"`
|
||||
PostProcessors []string `json:"post-processors"`
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package packer
|
||||
|
||||
// RootPartitionSizes describes how big a single root partition should
|
||||
// be given a standard 256M boot partition. This should cover standard
|
||||
// install media sizes.
|
||||
var RootPartitionSizes = map[string]string{
|
||||
"4G": "3.7G",
|
||||
"8G": "7.7G",
|
||||
"16G": "15.7G",
|
||||
"32G": "31.7G",
|
||||
}
|
||||
|
||||
// Safe defaults that can be used when a custom option isn't needed.
|
||||
const (
|
||||
QemuDefaultPath = "/usr/bin/qemu-aarch64-static"
|
||||
RootPartitionSafeDefault = "2.8G"
|
||||
StandardPath = "PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin"
|
||||
)
|
||||
|
||||
// Partition describes a partition in the generated image.
|
||||
type Partition struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
StartSector int `json:"start_sector"` // should be a uint64, except JSON
|
||||
Size string `json:"size"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
}
|
||||
|
||||
// Builder specifically refers to an Arm builder as used for the images
|
||||
// generated for a computeblade.
|
||||
type Builder struct {
|
||||
Type string `json:"type"`
|
||||
FileURLs []string `json:"file_urls"`
|
||||
FileChecksumURL string `json:"file_checksum_url"`
|
||||
FileChecksumType string `json:"file_checksum_type"`
|
||||
FileTargetExtension string `json:"file_target_extension"`
|
||||
FileUnarchiveCommand []string `json:"file_unarchive_cmd"`
|
||||
ImageBuildMethod string `json:"image_build_method"`
|
||||
ImagePath string `json:"image_path"`
|
||||
ImageSize string `json:"image_size"`
|
||||
ImageType string `json:"image_type"`
|
||||
ImagePartitions []Partition `json:"image_partitions"`
|
||||
ImageChrootEnviron []string `json:"image_chroot_env"`
|
||||
QemuBinarySourcePath string `json:"qemu_binary_source_path"`
|
||||
QemuBinaryDestinationPath string `json:"qemu_binary_destination_path"`
|
||||
}
|
||||
|
||||
func NewBuilder(fileURLs []string) Builder {
|
||||
return Builder{
|
||||
Type: "arm",
|
||||
FileURLs: fileURLs,
|
||||
}
|
||||
}
|
||||
|
||||
// With256MBootPartition returns a standard 256M boot partition.
|
||||
func (b Builder) With256MBootPartition() Builder {
|
||||
p := Partition{
|
||||
Name: "boot",
|
||||
Type: "c",
|
||||
StartSector: 2048,
|
||||
Size: "256M",
|
||||
Mountpoint: "/boot/firmware",
|
||||
}
|
||||
|
||||
b.ImagePartitions = append(b.ImagePartitions, p)
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSingleRootPartition should be called after With256MBootPartition,
|
||||
// as it assumes a root partition immediately following the boot.
|
||||
func (b Builder) WithSingleRootPartition(size string) Builder {
|
||||
p := Partition{
|
||||
Name: "root",
|
||||
Type: "83",
|
||||
StartSector: 526336,
|
||||
Size: size,
|
||||
Mountpoint: "/",
|
||||
}
|
||||
|
||||
b.ImagePartitions = append(b.ImagePartitions, p)
|
||||
return b
|
||||
}
|
||||
|
||||
// WithStandardImage generates a standard image with a boot and root partition.
|
||||
func (b Builder) WithStandardImage(size string, outputPath string) Builder {
|
||||
b.ImageBuildMethod = "reuse"
|
||||
b.ImagePath = outputPath
|
||||
b.ImageSize = size
|
||||
b.ImageType = "dos"
|
||||
|
||||
rootPartitionSize := RootPartitionSizes[size]
|
||||
if rootPartitionSize == "" {
|
||||
rootPartitionSize = RootPartitionSafeDefault
|
||||
}
|
||||
|
||||
b = b.With256MBootPartition()
|
||||
b = b.WithSingleRootPartition(rootPartitionSize)
|
||||
|
||||
// Append a standard PATH environment.
|
||||
b.ImageChrootEnviron = append(b.ImageChrootEnviron, StandardPath)
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// WithStandard32GImage adds a standard 32G image spec to the Builder.
|
||||
func (b Builder) WithStandard32GImage(outputPath string) Builder {
|
||||
return b.WithStandardImage("32G", outputPath)
|
||||
}
|
||||
|
||||
// WithQemuDefaults sets the standard qemu path in the builder.
|
||||
func (b Builder) WithQemuDefaults() Builder {
|
||||
b.QemuBinarySourcePath = QemuDefaultPath
|
||||
b.QemuBinaryDestinationPath = QemuDefaultPath
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSHA256Checksum sets a SHA256 checksum URL.
|
||||
func (b Builder) WithSHA256Checksum(url string) Builder {
|
||||
b.FileChecksumURL = url
|
||||
b.FileChecksumType = "sha256"
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) withXZ() Builder {
|
||||
b.FileTargetExtension = "xz"
|
||||
b.FileUnarchiveCommand = []string{
|
||||
"xz",
|
||||
"--decompress",
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) withUnzip() Builder {
|
||||
b.FileTargetExtension = "zip"
|
||||
b.FileUnarchiveCommand = []string{
|
||||
"unzip",
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) withTGZ() Builder {
|
||||
b.FileTargetExtension = "tgz"
|
||||
b.FileUnarchiveCommand = []string{
|
||||
"tar",
|
||||
"xzf",
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) withTarGZ() Builder {
|
||||
b.FileTargetExtension = "tar.gz"
|
||||
b.FileUnarchiveCommand = []string{
|
||||
"tar",
|
||||
"xzf",
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) withGZ() Builder {
|
||||
b.FileTargetExtension = "gz"
|
||||
b.FileUnarchiveCommand = []string{
|
||||
"gunzip",
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// WithUnarchiver fills in the appropriate unarchiver command given the
|
||||
// archive extension.
|
||||
func (b Builder) WithUnarchiver(extension string) Builder {
|
||||
switch extension {
|
||||
case "xz":
|
||||
b = b.withXZ()
|
||||
case "zip":
|
||||
b = b.withUnzip()
|
||||
case "tgz":
|
||||
b = b.withTGZ()
|
||||
case "tar.gz":
|
||||
b = b.withTarGZ()
|
||||
case "gz":
|
||||
b = b.withGZ()
|
||||
}
|
||||
|
||||
b.FileUnarchiveCommand = append(b.FileUnarchiveCommand, "$ARCHIVE_PATH")
|
||||
return b
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
// Package packer contains utilities for interacting with Packer
|
||||
// in the context of building images for the computeblade cluster.
|
||||
package packer
|
|
@ -0,0 +1,78 @@
|
|||
package packer
|
||||
|
||||
type Provisioner map[string]interface{}
|
||||
|
||||
// ShellProvisioner provisions machines built by Packer using shell scripts.
|
||||
func ShellProvisioner(scripts ...string) Provisioner {
|
||||
return map[string]interface{}{
|
||||
"type": "shell",
|
||||
"scripts": scripts,
|
||||
}
|
||||
}
|
||||
|
||||
// ShellLocalProvisioner will run a shell script of your choosing on the
|
||||
// machine where Packer is being run - in other words, shell-local will run
|
||||
// the shell script on your build server, or your desktop, etc., rather than
|
||||
// the remote/guest machine being provisioned by Packer.
|
||||
func ShellLocalProvisioner(scripts ...string) Provisioner {
|
||||
return map[string]interface{}{
|
||||
"type": "shell-local",
|
||||
"scripts": scripts,
|
||||
}
|
||||
}
|
||||
|
||||
// uploads files to machines built by Packer. The recommended usage of the file
|
||||
// provisioner is to use it to upload files, and then use shell provisioner to
|
||||
// move them to the proper place, set permissions, etc.
|
||||
func FileProvisioner(src, dest string) Provisioner {
|
||||
return map[string]interface{}{
|
||||
"type": "file",
|
||||
"source": src,
|
||||
"destination": dest,
|
||||
}
|
||||
}
|
||||
|
||||
// BreakpointProvisioner pauses until the user presses "enter" to resume the build.
|
||||
func BreakpointProvisioner(note string) Provisioner {
|
||||
return map[string]interface{}{
|
||||
"type": "breakpoint",
|
||||
"disable": false,
|
||||
"note": note,
|
||||
}
|
||||
}
|
||||
|
||||
func (b Board) WithShellProvisioner(scripts ...string) Board {
|
||||
b.Provisioners = append(b.Provisioners, ShellProvisioner(scripts...))
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Board) WithShellLocalProvisioner(scripts ...string) Board {
|
||||
b.Provisioners = append(b.Provisioners, ShellLocalProvisioner(scripts...))
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Board) WithFileProvisioner(src, dest string) Board {
|
||||
b.Provisioners = append(b.Provisioners, FileProvisioner(src, dest))
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Board) WithBreakpointProvisioner(note string) Board {
|
||||
b.Provisioners = append(b.Provisioners, BreakpointProvisioner(note))
|
||||
return b
|
||||
}
|
||||
|
||||
type FileSet struct {
|
||||
Source string `yaml:"source"`
|
||||
Destination string `yaml:"destination"`
|
||||
}
|
||||
|
||||
func (fs FileSet) Provisioner() Provisioner {
|
||||
return FileProvisioner(fs.Source, fs.Destination)
|
||||
}
|
||||
|
||||
func (b Board) WithFileSetsProvisioner(fileSets []FileSet) Board {
|
||||
for _, fs := range fileSets {
|
||||
b.Provisioners = append(b.Provisioners, fs.Provisioner())
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package packer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type urlSet struct {
|
||||
FileURLs []string
|
||||
ChecksumURL string
|
||||
}
|
||||
|
||||
// ubuntuImage returns a local cache path and a remote fetch path for an
|
||||
// Ubuntu image for a given version.
|
||||
func ubuntuImage(version string) urlSet {
|
||||
imageBase := fmt.Sprintf("ubuntu-%s-preinstalled-server-arm64+raspi.img.xz", version)
|
||||
imageDir := fmt.Sprintf("https://cdimage.ubuntu.com/releases/%s/release/", version)
|
||||
checksumURL := fmt.Sprintf("http://cdimage.ubuntu.com/releases/%s/release/SHA256SUMS", version)
|
||||
|
||||
localImage := "build/" + imageBase
|
||||
remoteImage := imageDir + imageBase
|
||||
|
||||
return urlSet{
|
||||
FileURLs: []string{
|
||||
localImage,
|
||||
remoteImage,
|
||||
},
|
||||
ChecksumURL: checksumURL,
|
||||
}
|
||||
}
|
||||
|
||||
func UbuntuBuilder(version, size, outputPath string) Builder {
|
||||
urlSet := ubuntuImage(version)
|
||||
outputPath = "build/" + outputPath
|
||||
|
||||
b := NewBuilder(urlSet.FileURLs)
|
||||
return b.
|
||||
WithSHA256Checksum(urlSet.ChecksumURL).
|
||||
WithUnarchiver("xz").
|
||||
WithStandardImage(size, outputPath).
|
||||
WithQemuDefaults()
|
||||
}
|
||||
|
||||
type UbuntuBoardSpec struct {
|
||||
Version string `yaml:"version"`
|
||||
Size string `yaml:"size"`
|
||||
ImageName string `yaml:"name"`
|
||||
LocalScripts []string `yaml:"local-scripts"`
|
||||
Files []FileSet `yaml:"files"`
|
||||
Scripts []string `yaml:"scripts"`
|
||||
}
|
||||
|
||||
func (spec UbuntuBoardSpec) JSONPath(base string) string {
|
||||
dest := spec.ImageName
|
||||
ext := filepath.Ext(dest)
|
||||
if ext != "" {
|
||||
ext = "." + ext
|
||||
dest = strings.TrimSuffix(dest, ext)
|
||||
}
|
||||
|
||||
dest += ".json"
|
||||
if base != "" {
|
||||
dest = filepath.Join(base, dest)
|
||||
}
|
||||
return dest
|
||||
}
|
||||
|
||||
func (spec UbuntuBoardSpec) Board() Board {
|
||||
board := Board{
|
||||
Variables: []string{},
|
||||
Builders: []Builder{
|
||||
UbuntuBuilder(spec.Version, spec.Size, spec.ImageName),
|
||||
},
|
||||
}
|
||||
|
||||
if len(spec.LocalScripts) != 0 {
|
||||
board = board.WithShellLocalProvisioner(spec.LocalScripts...)
|
||||
}
|
||||
|
||||
if len(spec.Files) != 0 {
|
||||
board = board.WithFileSetsProvisioner(spec.Files)
|
||||
}
|
||||
|
||||
if len(spec.Scripts) != 0 {
|
||||
board = board.WithShellProvisioner(spec.Scripts...)
|
||||
}
|
||||
|
||||
return board
|
||||
}
|
||||
|
||||
func LoadUbuntuSpecs(path string) (specFile UbuntuBoardSpecFile, err error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &specFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return specFile, nil
|
||||
}
|
||||
|
||||
// UbuntuBoardSpecFile describes a set of specifications for Ubuntu boards.
|
||||
//
|
||||
// In the future, this may include additional data.
|
||||
type UbuntuBoardSpecFile struct {
|
||||
Boards []UbuntuBoardSpec `yaml:"boards"`
|
||||
}
|
||||
|
||||
func (specFile UbuntuBoardSpecFile) WriteBoards(outputDir string) error {
|
||||
for _, spec := range specFile.Boards {
|
||||
board := spec.Board()
|
||||
dest := spec.JSONPath(outputDir)
|
||||
|
||||
contents, err := json.Marshal(board)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(dest, contents, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue