Compare commits
10 Commits
6ae0267df2
...
9a9519186b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a9519186b | ||
|
|
5675dbb2eb | ||
|
|
ab29b81133 | ||
|
|
19d09ffb32 | ||
|
|
8143336564 | ||
|
|
2979dc9b26 | ||
|
|
ab76ef531d | ||
|
|
2e390edb12 | ||
|
|
d145a5b689 | ||
|
|
a0558bc6a0 |
19
.github/workflows/push.yml
vendored
19
.github/workflows/push.yml
vendored
@@ -7,8 +7,14 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build:
|
build:
|
||||||
name: build-and-test
|
name: CI
|
||||||
runs-on: ubuntu-latest
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- macos-latest
|
||||||
|
- ubuntu-latest
|
||||||
|
- windows-latest
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
@@ -21,14 +27,19 @@ jobs:
|
|||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Ensure all files were formatted as per gofmt
|
- name: Ensure all files were formatted as per gofmt
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
[ "$(gofmt -l $(find . -name '*.go') 2>&1)" = "" ]
|
[ "$(gofmt -l $(find . -name '*.go') 2>&1)" = "" ]
|
||||||
|
|
||||||
- name: Build and run tests
|
- name: Build
|
||||||
|
run: |
|
||||||
|
go install -mod=mod ./cmd/...
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
# TestRelativeParentDir verifies breakglass.authorized_keys
|
# TestRelativeParentDir verifies breakglass.authorized_keys
|
||||||
# is correctly included, and the gok CLI only creates that
|
# is correctly included, and the gok CLI only creates that
|
||||||
# file when it finds SSH keys.
|
# file when it finds SSH keys.
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.ssh && echo dummy > ~/.ssh/id_ed25519.pub
|
mkdir -p ~/.ssh && echo dummy > ~/.ssh/id_ed25519.pub
|
||||||
go install -mod=mod ./cmd/...
|
|
||||||
go test -mod=mod -v ./...
|
go test -mod=mod -v ./...
|
||||||
|
|||||||
22
go.mod
22
go.mod
@@ -1,24 +1,26 @@
|
|||||||
module github.com/gokrazy/tools
|
module github.com/gokrazy/tools
|
||||||
|
|
||||||
go 1.24
|
go 1.24.0
|
||||||
|
|
||||||
|
toolchain go1.24.6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/breml/rootcerts v0.2.20
|
|
||||||
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0
|
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0
|
||||||
github.com/gokrazy/gokapi v0.0.0-20250222080418-e140e9c461d8
|
github.com/gokrazy/gokapi v0.0.0-20250222080418-e140e9c461d8
|
||||||
github.com/gokrazy/internal v0.0.0-20250520205945-c2e4e2b4f611
|
github.com/gokrazy/internal v0.0.0-20250526201501-559979153369
|
||||||
github.com/gokrazy/updater v0.0.0-20230215172637-813ccc7f21e2
|
github.com/gokrazy/updater v0.0.0-20250705135802-db129c40879c
|
||||||
github.com/google/renameio/v2 v2.0.0
|
github.com/google/renameio/v2 v2.0.0
|
||||||
github.com/mattn/go-isatty v0.0.20
|
github.com/mattn/go-isatty v0.0.20
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.6
|
||||||
golang.org/x/mod v0.23.0
|
golang.org/x/crypto/x509roots/fallback v0.0.0-20250911151450-96dc232fbd79
|
||||||
golang.org/x/sync v0.1.0
|
golang.org/x/mod v0.24.0
|
||||||
golang.org/x/sys v0.28.0
|
golang.org/x/sync v0.14.0
|
||||||
|
golang.org/x/sys v0.33.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/antihax/optional v1.0.0 // indirect
|
github.com/antihax/optional v1.0.0 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
golang.org/x/oauth2 v0.23.0 // indirect
|
golang.org/x/oauth2 v0.27.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
39
go.sum
39
go.sum
@@ -1,38 +1,37 @@
|
|||||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
github.com/breml/rootcerts v0.2.20 h1:koth1lShwiiDp3VOX6/4qKEZ87S7HgDKsnDr47XEIq0=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/breml/rootcerts v0.2.20/go.mod h1:S/PKh+4d1HUn4HQovEB8hPJZO6pUZYrIhmXBhsegfXw=
|
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
|
||||||
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao=
|
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 h1:C7t6eeMaEQVy6e8CarIhscYQlNmw5e3G36y7l7Y21Ao=
|
||||||
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw=
|
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw=
|
||||||
github.com/gokrazy/gokapi v0.0.0-20250222080418-e140e9c461d8 h1:BvyzTtbpz1GCGD35Z3G/ZR0nK0j3Fh+dRCCso+w3RKE=
|
github.com/gokrazy/gokapi v0.0.0-20250222080418-e140e9c461d8 h1:BvyzTtbpz1GCGD35Z3G/ZR0nK0j3Fh+dRCCso+w3RKE=
|
||||||
github.com/gokrazy/gokapi v0.0.0-20250222080418-e140e9c461d8/go.mod h1:rVItujrJo0NpYZhFR5dYdzLDqMoMCtjEZkdxoCRDo+o=
|
github.com/gokrazy/gokapi v0.0.0-20250222080418-e140e9c461d8/go.mod h1:rVItujrJo0NpYZhFR5dYdzLDqMoMCtjEZkdxoCRDo+o=
|
||||||
github.com/gokrazy/internal v0.0.0-20250520205945-c2e4e2b4f611 h1:BcmhkIKeIsw5xGheRGOCj97zjevG+VImWiP2/XGF2Gg=
|
github.com/gokrazy/internal v0.0.0-20250526201501-559979153369 h1:aNni2iPwJbowfHW1SFapKLfY+ZPUIcBfFrJvYPAh3p4=
|
||||||
github.com/gokrazy/internal v0.0.0-20250520205945-c2e4e2b4f611/go.mod h1:dQY4EMkD4L5ZjYJ0SPtpgYbV7MIUMCxNIXiOfnZ6jP4=
|
github.com/gokrazy/internal v0.0.0-20250526201501-559979153369/go.mod h1:dQY4EMkD4L5ZjYJ0SPtpgYbV7MIUMCxNIXiOfnZ6jP4=
|
||||||
github.com/gokrazy/updater v0.0.0-20230215172637-813ccc7f21e2 h1:kBY5R1tSf+EYZ+QaSrofLaVJtBqYsVNVBWkdMq3Smcg=
|
github.com/gokrazy/updater v0.0.0-20250705135802-db129c40879c h1:j4/v9FR/cOy6nog5rmXUtauBsOU3mm+rTPn5IENUbmg=
|
||||||
github.com/gokrazy/updater v0.0.0-20230215172637-813ccc7f21e2/go.mod h1:PYOvzGOL4nlBmuxu7IyKQTFLaxr61+WPRNRzVtuYOHw=
|
github.com/gokrazy/updater v0.0.0-20250705135802-db129c40879c/go.mod h1:EtAn+BPibqnAHnYGj3FW5e284xNsiOOMOL2dJiwu7H4=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
||||||
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
||||||
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
golang.org/x/crypto/x509roots/fallback v0.0.0-20250911151450-96dc232fbd79 h1:WZWglxfb13JCTbJyKY1pk0V94spHxJzMAQW29INytRQ=
|
||||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
golang.org/x/crypto/x509roots/fallback v0.0.0-20250911151450-96dc232fbd79/go.mod h1:MEIPiCnxvQEjA4astfaKItNwEVZA5Ki+3+nyGbJ5N18=
|
||||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||||
|
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||||
|
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
197
integration/gokupdate/gokupdate_test.go
Normal file
197
integration/gokupdate/gokupdate_test.go
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
package gokupdate_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"hash/crc32"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gokrazy/internal/config"
|
||||||
|
"github.com/gokrazy/tools/gok"
|
||||||
|
"github.com/gokrazy/tools/internal/packer"
|
||||||
|
)
|
||||||
|
|
||||||
|
type gokrazyTestInstance struct {
|
||||||
|
configDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (inst *gokrazyTestInstance) writeConfig(t *testing.T, basename, content string) {
|
||||||
|
t.Helper()
|
||||||
|
fn := filepath.Join(inst.configDir, basename)
|
||||||
|
if err := os.WriteFile(fn, []byte(content), 0600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeGokrazyInstance(t *testing.T) *gokrazyTestInstance {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
// Redirect os.UserConfigDir() to a temporary directory under our
|
||||||
|
// control. gokrazy always uses a path under os.UserConfigDir().
|
||||||
|
var configDir string
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "linux":
|
||||||
|
configHomeDir := t.TempDir()
|
||||||
|
os.Setenv("XDG_CONFIG_HOME", configHomeDir)
|
||||||
|
// where linux looks:
|
||||||
|
configDir = filepath.Join(configHomeDir, "gokrazy")
|
||||||
|
|
||||||
|
case "darwin":
|
||||||
|
homeDir := t.TempDir()
|
||||||
|
os.Setenv("HOME", homeDir)
|
||||||
|
// where darwin looks:
|
||||||
|
configDir = filepath.Join(homeDir, "Library", "Application Support", "gokrazy")
|
||||||
|
|
||||||
|
default:
|
||||||
|
t.Fatalf("GOOS=%s unsupported", runtime.GOOS)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(configDir, 0755); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &gokrazyTestInstance{
|
||||||
|
configDir: configDir,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGokUpdate(t *testing.T) {
|
||||||
|
// Run this whole test in a throw-away temporary directory to not litter the
|
||||||
|
// gokrazy/tools repository working copy.
|
||||||
|
t.Chdir(t.TempDir())
|
||||||
|
|
||||||
|
_ = writeGokrazyInstance(t)
|
||||||
|
|
||||||
|
// TODO: run the gokrazy instance in a VM instead of providing a fake
|
||||||
|
// implementation of the update protocol.
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
mux.HandleFunc("/update/features", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
http.Error(w, "not found", http.StatusNotFound)
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/update/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// accept whatever for now.
|
||||||
|
var hash hash.Hash
|
||||||
|
switch r.Header.Get("X-Gokrazy-Update-Hash") {
|
||||||
|
case "crc32":
|
||||||
|
hash = crc32.NewIEEE()
|
||||||
|
default:
|
||||||
|
hash = sha256.New()
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(hash, r.Body); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "%x", hash.Sum(nil))
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/reboot", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// you got it, boss!
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/uploadtemp/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("[HTTP] uploadtemp: %s", r.URL.Path)
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/divert", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("[HTTP] divert: %s to %s",
|
||||||
|
r.FormValue("path"),
|
||||||
|
r.FormValue("diversion"))
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/log", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("[HTTP] log: %s", r.FormValue("path"))
|
||||||
|
w.Header().Set("Content-type", "text/event-stream")
|
||||||
|
if r.FormValue("stream") == "stdout" {
|
||||||
|
const text = "Hello Sun"
|
||||||
|
line := fmt.Sprintf("data: %s\n", text)
|
||||||
|
if _, err := fmt.Fprintln(w, line); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f, ok := w.(http.Flusher); ok {
|
||||||
|
f.Flush()
|
||||||
|
}
|
||||||
|
select {}
|
||||||
|
})
|
||||||
|
fakeBuildTimestamp := "fake-" + time.Now().Format(time.RFC3339)
|
||||||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if strings.Contains(strings.ToLower(r.Header.Get("Accept")), "application/json") {
|
||||||
|
status := struct {
|
||||||
|
BuildTimestamp string `json:"BuildTimestamp"`
|
||||||
|
}{
|
||||||
|
BuildTimestamp: fakeBuildTimestamp,
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(&status)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.Write(b)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, "handler not implemented", http.StatusNotImplemented)
|
||||||
|
})
|
||||||
|
srv := httptest.NewServer(mux)
|
||||||
|
u, err := url.Parse(srv.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a new instance
|
||||||
|
c := gok.Context{
|
||||||
|
Args: []string{
|
||||||
|
"--parent_dir", "gokrazy",
|
||||||
|
"-i", "hello",
|
||||||
|
"new",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.Logf("running %q", append([]string{"<gok>"}, c.Args...))
|
||||||
|
if err := c.Execute(context.Background()); err != nil {
|
||||||
|
t.Fatalf("%v: %v", c.Args, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the instance config to speak to the test server
|
||||||
|
const configPath = "gokrazy/hello/config.json"
|
||||||
|
b, err := os.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var cfg config.Struct
|
||||||
|
if err := json.Unmarshal(b, &cfg); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cfg.Update.Hostname = "localhost"
|
||||||
|
cfg.Update.HTTPPort = u.Port()
|
||||||
|
t.Logf("Updated cfg.Update = %+v", cfg.Update)
|
||||||
|
b, err = cfg.FormatForFile()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(configPath, b, 0644); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// verify overwrite works (i.e. locates extrafiles)
|
||||||
|
ctx := context.WithValue(context.Background(), packer.BuildTimestampOverride, fakeBuildTimestamp)
|
||||||
|
c = gok.Context{
|
||||||
|
Args: []string{
|
||||||
|
"--parent_dir", "gokrazy",
|
||||||
|
"-i", "hello",
|
||||||
|
"update",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.Logf("running %q", append([]string{"<gok>"}, c.Args...))
|
||||||
|
if err := c.Execute(ctx); err != nil {
|
||||||
|
t.Fatalf("%v: %v", c.Args, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,9 +15,10 @@ import (
|
|||||||
func TestNonModuleFiles(t *testing.T) {
|
func TestNonModuleFiles(t *testing.T) {
|
||||||
// Run this whole test in a throw-away temporary directory to not litter the
|
// Run this whole test in a throw-away temporary directory to not litter the
|
||||||
// gokrazy/tools repository working copy.
|
// gokrazy/tools repository working copy.
|
||||||
parent := t.TempDir()
|
t.Chdir(t.TempDir())
|
||||||
|
|
||||||
// create a new instance
|
// create a new instance
|
||||||
|
parent := t.TempDir()
|
||||||
c := gok.Context{
|
c := gok.Context{
|
||||||
Args: []string{
|
Args: []string{
|
||||||
"--parent_dir=" + parent,
|
"--parent_dir=" + parent,
|
||||||
|
|||||||
@@ -13,22 +13,7 @@ import (
|
|||||||
func TestRelativeParentDir(t *testing.T) {
|
func TestRelativeParentDir(t *testing.T) {
|
||||||
// Run this whole test in a throw-away temporary directory to not litter the
|
// Run this whole test in a throw-away temporary directory to not litter the
|
||||||
// gokrazy/tools repository working copy.
|
// gokrazy/tools repository working copy.
|
||||||
|
t.Chdir(t.TempDir())
|
||||||
// TODO(go1.24): use t.Chdir()
|
|
||||||
oldwd, err := os.Open(".")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := os.Chdir(t.TempDir()); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Cleanup(func() {
|
|
||||||
err := oldwd.Chdir()
|
|
||||||
oldwd.Close()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// create a new instance
|
// create a new instance
|
||||||
c := gok.Context{
|
c := gok.Context{
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ func (r *overwriteImplConfig) run(ctx context.Context, args []string, stdout, st
|
|||||||
Output: &output,
|
Output: &output,
|
||||||
}
|
}
|
||||||
|
|
||||||
pack.Main("gokrazy gok")
|
pack.Main(ctx, "gokrazy gok")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ func (r *runImplConfig) run(ctx context.Context, args []string, stdout, stderr i
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
target, err := updater.NewTarget(updateBaseUrl.String(), httpClient)
|
target, err := updater.NewTarget(ctx, updateBaseUrl.String(), httpClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("checking target partuuid support: %v", err)
|
return fmt.Errorf("checking target partuuid support: %v", err)
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ func (r *runImplConfig) run(ctx context.Context, args []string, stdout, stderr i
|
|||||||
|
|
||||||
{
|
{
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
err := target.Put("uploadtemp/gok-run/"+basename, io.TeeReader(f, &progress.Writer{}))
|
err := target.Put(ctx, "uploadtemp/gok-run/"+basename, io.TeeReader(f, &progress.Writer{}))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("uploading temporary binary: %v", err)
|
return fmt.Errorf("uploading temporary binary: %v", err)
|
||||||
}
|
}
|
||||||
@@ -171,6 +171,7 @@ func (r *runImplConfig) run(ctx context.Context, args []string, stdout, stderr i
|
|||||||
// /user/<basename>. Includes an automatic service restart.
|
// /user/<basename>. Includes an automatic service restart.
|
||||||
{
|
{
|
||||||
err := target.Divert(
|
err := target.Divert(
|
||||||
|
ctx,
|
||||||
"/user/"+basename,
|
"/user/"+basename,
|
||||||
"gok-run/"+basename,
|
"gok-run/"+basename,
|
||||||
cfg.PackageConfig[importPath].CommandLineFlags,
|
cfg.PackageConfig[importPath].CommandLineFlags,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func (r *sbomConfig) run(ctx context.Context, args []string, stdout, stderr io.W
|
|||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
sbomMarshaled, sbomWithHash, err := pack.GenerateSBOM()
|
sbomMarshaled, sbomWithHash, err := pack.GenerateSBOM(ctx)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
// Common case, handle with a good error message
|
// Common case, handle with a good error message
|
||||||
os.Stderr.WriteString("\n")
|
os.Stderr.WriteString("\n")
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ func (r *updateImplConfig) run(ctx context.Context, args []string, stdout, stder
|
|||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
pack.Main("gokrazy gok")
|
pack.Main(ctx, "gokrazy gok")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,11 +76,7 @@ func init() {
|
|||||||
instanceflag.RegisterPflags(vmRunCmd.Flags())
|
instanceflag.RegisterPflags(vmRunCmd.Flags())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *vmRunConfig) buildFullDiskImage(ctx context.Context, dest string) error {
|
func (r *vmRunConfig) buildFullDiskImage(ctx context.Context, dest string, fileCfg *config.Struct) error {
|
||||||
fileCfg, err := config.ApplyInstanceFlag()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.arch != "" {
|
if r.arch != "" {
|
||||||
os.Setenv("GOARCH", r.arch)
|
os.Setenv("GOARCH", r.arch)
|
||||||
@@ -137,7 +133,7 @@ func (r *vmRunConfig) buildFullDiskImage(ctx context.Context, dest string) error
|
|||||||
Output: &output,
|
Output: &output,
|
||||||
}
|
}
|
||||||
|
|
||||||
pack.Main("gokrazy gok")
|
pack.Main(ctx, "gokrazy gok")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -231,6 +227,22 @@ func (r *vmRunConfig) runQEMU(ctx context.Context, fullDiskImage string, extraAr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *vmRunConfig) run(ctx context.Context, args []string, stdout, stderr io.Writer) error {
|
func (r *vmRunConfig) run(ctx context.Context, args []string, stdout, stderr io.Writer) error {
|
||||||
|
fileCfg, err := config.ApplyInstanceFlag()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileCfg.SerialConsole == "disabled" {
|
||||||
|
// The serial console is disabled by default:
|
||||||
|
// https://gokrazy.org/userguide/instance-config/#serialconsole
|
||||||
|
// 'gok vm run' currently launches QEMU such that
|
||||||
|
// there is a serial0 monitor available, but no HDMI.
|
||||||
|
// Hence, print a tip for how to get the serial console to work.
|
||||||
|
log.Printf("")
|
||||||
|
log.Printf(` Tip: Your config.json disables the serial console. Set "SerialConsole": "ttyAMA0,115200", then select View -> serial0 in QEMU to access an interactive shell for debugging.`)
|
||||||
|
log.Printf("")
|
||||||
|
}
|
||||||
|
|
||||||
f, err := os.CreateTemp("", "gokrazy-vm")
|
f, err := os.CreateTemp("", "gokrazy-vm")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -241,7 +253,7 @@ func (r *vmRunConfig) run(ctx context.Context, args []string, stdout, stderr io.
|
|||||||
fdi := f.Name()
|
fdi := f.Name()
|
||||||
log.Printf("building disk image")
|
log.Printf("building disk image")
|
||||||
if !r.dry {
|
if !r.dry {
|
||||||
if err := r.buildFullDiskImage(ctx, fdi); err != nil {
|
if err := r.buildFullDiskImage(ctx, fdi, fileCfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package packer
|
package packer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/pem"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/breml/rootcerts/embedded"
|
"golang.org/x/crypto/x509roots/fallback/bundle"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pack *Pack) findSystemCertsPEM() (string, error) {
|
func (pack *Pack) findSystemCertsPEM() (string, error) {
|
||||||
@@ -14,6 +15,7 @@ func (pack *Pack) findSystemCertsPEM() (string, error) {
|
|||||||
defer func() {
|
defer func() {
|
||||||
log.Printf("Loading system CA certificates from %s", source)
|
log.Printf("Loading system CA certificates from %s", source)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// On Linux, we can copy the operating system’s certificate store.
|
// On Linux, we can copy the operating system’s certificate store.
|
||||||
// certFiles is defined in cacerts_linux.go (or defined as empty in
|
// certFiles is defined in cacerts_linux.go (or defined as empty in
|
||||||
// cacertsstub.go on non-Linux):
|
// cacertsstub.go on non-Linux):
|
||||||
@@ -37,7 +39,18 @@ func (pack *Pack) findSystemCertsPEM() (string, error) {
|
|||||||
return string(b), nil
|
return string(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fall back to github.com/breml/rootcerts, i.e. the bundled Mozilla CA list:
|
// Fall back to the x/crypto fallback bundle root certificates:
|
||||||
source = "bundled Mozilla CA list"
|
source = "bundled x509roots/fallback/bundle"
|
||||||
return embedded.MozillaCACertificatesPEM(), nil
|
return xrf(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func xrf() string {
|
||||||
|
var certs []byte
|
||||||
|
for c := range bundle.Roots() {
|
||||||
|
certs = append(certs, pem.EncodeToMemory(&pem.Block{
|
||||||
|
Type: "CERTIFICATE",
|
||||||
|
Bytes: c.Certificate,
|
||||||
|
})...)
|
||||||
|
}
|
||||||
|
return string(certs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ import (
|
|||||||
"github.com/gokrazy/updater"
|
"github.com/gokrazy/updater"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type contextKey int
|
||||||
|
|
||||||
|
var BuildTimestampOverride contextKey
|
||||||
|
|
||||||
const MB = 1024 * 1024
|
const MB = 1024 * 1024
|
||||||
|
|
||||||
type filePathAndModTime struct {
|
type filePathAndModTime struct {
|
||||||
@@ -1099,7 +1103,7 @@ func filterGoEnv(env []string) []string {
|
|||||||
return relevant
|
return relevant
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pack *Pack) logicPrepare(programName string, sbomHook func(marshaled []byte, withHash SBOMWithHash)) error {
|
func (pack *Pack) logicPrepare(ctx context.Context, programName string, sbomHook func(marshaled []byte, withHash SBOMWithHash)) error {
|
||||||
log := pack.Env.Logger()
|
log := pack.Env.Logger()
|
||||||
cfg := pack.Cfg
|
cfg := pack.Cfg
|
||||||
updateflag.SetUpdate(cfg.InternalCompatibilityFlags.Update)
|
updateflag.SetUpdate(cfg.InternalCompatibilityFlags.Update)
|
||||||
@@ -1178,6 +1182,9 @@ func (pack *Pack) logicPrepare(programName string, sbomHook func(marshaled []byt
|
|||||||
log.Printf("Build target: %s", strings.Join(filterGoEnv(packer.Env()), " "))
|
log.Printf("Build target: %s", strings.Join(filterGoEnv(packer.Env()), " "))
|
||||||
|
|
||||||
pack.buildTimestamp = time.Now().Format(time.RFC3339)
|
pack.buildTimestamp = time.Now().Format(time.RFC3339)
|
||||||
|
if ts, ok := ctx.Value(BuildTimestampOverride).(string); ok {
|
||||||
|
pack.buildTimestamp = ts
|
||||||
|
}
|
||||||
log.Printf("Build timestamp: %s", pack.buildTimestamp)
|
log.Printf("Build timestamp: %s", pack.buildTimestamp)
|
||||||
|
|
||||||
systemCertsPEM, err := pack.findSystemCertsPEM()
|
systemCertsPEM, err := pack.findSystemCertsPEM()
|
||||||
@@ -1630,7 +1637,7 @@ func (pack *Pack) logicBuild(programName string, sbomHook func(marshaled []byte,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pack *Pack) logic(programName string, sbomHook func(marshaled []byte, withHash SBOMWithHash)) error {
|
func (pack *Pack) logic(ctx context.Context, programName string, sbomHook func(marshaled []byte, withHash SBOMWithHash)) error {
|
||||||
dnsCheck := make(chan error)
|
dnsCheck := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(dnsCheck)
|
defer close(dnsCheck)
|
||||||
@@ -1646,7 +1653,7 @@ func (pack *Pack) logic(programName string, sbomHook func(marshaled []byte, with
|
|||||||
dnsCheck <- nil
|
dnsCheck <- nil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := pack.logicPrepare(programName, sbomHook); err != nil {
|
if err := pack.logicPrepare(ctx, programName, sbomHook); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1669,6 +1676,7 @@ func (pack *Pack) logic(programName string, sbomHook func(marshaled []byte, with
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pack *Pack) logicWrite(programName string, sbomHook func(marshaled []byte, withHash SBOMWithHash), bindir string, dnsCheck chan error) error {
|
func (pack *Pack) logicWrite(programName string, sbomHook func(marshaled []byte, withHash SBOMWithHash), bindir string, dnsCheck chan error) error {
|
||||||
|
ctx := context.Background()
|
||||||
log := pack.Env.Logger()
|
log := pack.Env.Logger()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -1718,7 +1726,7 @@ func (pack *Pack) logicWrite(programName string, sbomHook func(marshaled []byte,
|
|||||||
}
|
}
|
||||||
updateBaseUrl.Path = "/"
|
updateBaseUrl.Path = "/"
|
||||||
|
|
||||||
target, err = updater.NewTarget(updateBaseUrl.String(), updateHttpClient)
|
target, err = updater.NewTarget(ctx, updateBaseUrl.String(), updateHttpClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("checking target partuuid support: %v", err)
|
return fmt.Errorf("checking target partuuid support: %v", err)
|
||||||
}
|
}
|
||||||
@@ -2035,7 +2043,7 @@ func (pack *Pack) logicWrite(programName string, sbomHook func(marshaled []byte,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := target.StreamTo("mbr", mbrReader); err != nil {
|
if err := target.StreamTo(ctx, "mbr", mbrReader); err != nil {
|
||||||
if err == updater.ErrUpdateHandlerNotImplemented {
|
if err == updater.ErrUpdateHandlerNotImplemented {
|
||||||
log.Printf("target does not support updating MBR yet, ignoring")
|
log.Printf("target does not support updating MBR yet, ignoring")
|
||||||
} else {
|
} else {
|
||||||
@@ -2044,11 +2052,11 @@ func (pack *Pack) logicWrite(programName string, sbomHook func(marshaled []byte,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cfg.InternalCompatibilityFlags.Testboot {
|
if cfg.InternalCompatibilityFlags.Testboot {
|
||||||
if err := target.Testboot(); err != nil {
|
if err := target.Testboot(ctx); err != nil {
|
||||||
return fmt.Errorf("enable testboot of non-active partition: %v", err)
|
return fmt.Errorf("enable testboot of non-active partition: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := target.Switch(); err != nil {
|
if err := target.Switch(ctx); err != nil {
|
||||||
return fmt.Errorf("switching to non-active partition: %v", err)
|
return fmt.Errorf("switching to non-active partition: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2057,7 +2065,7 @@ func (pack *Pack) logicWrite(programName string, sbomHook func(marshaled []byte,
|
|||||||
canc()
|
canc()
|
||||||
|
|
||||||
log.Printf("Triggering reboot")
|
log.Printf("Triggering reboot")
|
||||||
if err := target.Reboot(); err != nil {
|
if err := target.Reboot(ctx); err != nil {
|
||||||
if errors.Is(err, syscall.ECONNRESET) {
|
if errors.Is(err, syscall.ECONNRESET) {
|
||||||
log.Printf("ignoring reboot error: %v", err)
|
log.Printf("ignoring reboot error: %v", err)
|
||||||
} else {
|
} else {
|
||||||
@@ -2159,6 +2167,7 @@ func (pack *Pack) validateTargetArchMatchesKernel() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pack *Pack) updateWithProgress(prog *progress.Reporter, reader io.Reader, target *updater.Target, logStr string, stream string) error {
|
func (pack *Pack) updateWithProgress(prog *progress.Reporter, reader io.Reader, target *updater.Target, logStr string, stream string) error {
|
||||||
|
ctx := context.Background()
|
||||||
log := pack.Env.Logger()
|
log := pack.Env.Logger()
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
@@ -2170,7 +2179,7 @@ func (pack *Pack) updateWithProgress(prog *progress.Reporter, reader io.Reader,
|
|||||||
prog.SetTotal(uint64(st.Size()))
|
prog.SetTotal(uint64(st.Size()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := target.StreamTo(stream, io.TeeReader(reader, &progress.Writer{})); err != nil {
|
if err := target.StreamTo(ctx, stream, io.TeeReader(reader, &progress.Writer{})); err != nil {
|
||||||
return fmt.Errorf("updating %s: %w", logStr, err)
|
return fmt.Errorf("updating %s: %w", logStr, err)
|
||||||
}
|
}
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
@@ -2184,17 +2193,17 @@ func (pack *Pack) updateWithProgress(prog *progress.Reporter, reader io.Reader,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pack *Pack) Main(programName string) {
|
func (pack *Pack) Main(ctx context.Context, programName string) {
|
||||||
if err := pack.logic(programName, nil); err != nil {
|
if err := pack.logic(ctx, programName, nil); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "ERROR:\n %s\n", err)
|
fmt.Fprintf(os.Stderr, "ERROR:\n %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pack *Pack) GenerateSBOM() ([]byte, SBOMWithHash, error) {
|
func (pack *Pack) GenerateSBOM(ctx context.Context) ([]byte, SBOMWithHash, error) {
|
||||||
var sbom []byte
|
var sbom []byte
|
||||||
var sbomWithHash SBOMWithHash
|
var sbomWithHash SBOMWithHash
|
||||||
if err := pack.logic("gokrazy gok", func(b []byte, wh SBOMWithHash) {
|
if err := pack.logic(ctx, "gokrazy gok", func(b []byte, wh SBOMWithHash) {
|
||||||
sbom = b
|
sbom = b
|
||||||
sbomWithHash = wh
|
sbomWithHash = wh
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func pollUpdated1(ctx context.Context, updateHttpClient *http.Client, updateBase
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Accept", "application/json")
|
||||||
resp, err := updateHttpClient.Do(req)
|
resp, err := updateHttpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user