Ship the scimesh wheel in releases; wizard and serve install it version-locked
coordinator / test (push) Canceled after 0s
python / test (push) Canceled after 0s
release / binaries (amd64, darwin) (push) Canceled after 0s
release / binaries (amd64, linux) (push) Canceled after 0s
release / binaries (amd64, windows) (push) Canceled after 0s
release / binaries (arm64, darwin) (push) Canceled after 0s
release / binaries (arm64, linux) (push) Canceled after 0s
release / binaries (arm64, windows) (push) Canceled after 0s
release / wheel (push) Canceled after 0s
release / image (push) Canceled after 0s
users / test (push) Canceled after 0s
release / release (push) Canceled after 0s
coordinator / test (push) Canceled after 0s
python / test (push) Canceled after 0s
release / binaries (amd64, darwin) (push) Canceled after 0s
release / binaries (amd64, linux) (push) Canceled after 0s
release / binaries (amd64, windows) (push) Canceled after 0s
release / binaries (arm64, darwin) (push) Canceled after 0s
release / binaries (arm64, linux) (push) Canceled after 0s
release / binaries (arm64, windows) (push) Canceled after 0s
release / wheel (push) Canceled after 0s
release / image (push) Canceled after 0s
users / test (push) Canceled after 0s
release / release (push) Canceled after 0s
This commit is contained in:
@@ -176,14 +176,15 @@ func (s *PIDSupervisor) Stop() error {
|
||||
|
||||
// Server is the wizard HTTP server, bound to the loopback interface only.
|
||||
type Server struct {
|
||||
log *slog.Logger
|
||||
cfgPath string
|
||||
logPath string
|
||||
dir string
|
||||
sup Supervisor
|
||||
openBrowser func(string)
|
||||
port int
|
||||
install func(ctx context.Context, venvPython, pkg string) error
|
||||
log *slog.Logger
|
||||
cfgPath string
|
||||
logPath string
|
||||
dir string
|
||||
sup Supervisor
|
||||
openBrowser func(string)
|
||||
port int
|
||||
install func(ctx context.Context, venvPython, pkg string) error
|
||||
downloadWheel func(ctx context.Context, url, dir string) (string, error)
|
||||
}
|
||||
|
||||
// Options customises the wizard for tests and embedding.
|
||||
@@ -196,6 +197,9 @@ type Options struct {
|
||||
// InstallScimesh overrides the pip step of the runtime installer (tests
|
||||
// substitute a fake); nil uses the real pip inside the managed venv.
|
||||
InstallScimesh func(ctx context.Context, venvPython, pkg string) error
|
||||
// DownloadWheel overrides the release-wheel download (tests substitute a
|
||||
// fake); nil downloads from the GitHub release matching the agent version.
|
||||
DownloadWheel func(ctx context.Context, url, dir string) (string, error)
|
||||
}
|
||||
|
||||
func New(log *slog.Logger, opts Options) *Server {
|
||||
@@ -223,7 +227,11 @@ func New(log *slog.Logger, opts Options) *Server {
|
||||
if install == nil {
|
||||
install = installScimeshWithPip
|
||||
}
|
||||
return &Server{log: log, cfgPath: cfgPath, logPath: filepath.Join(dir, logFileName), dir: dir, sup: sup, openBrowser: open, port: port, install: install}
|
||||
downloadWheel := opts.DownloadWheel
|
||||
if downloadWheel == nil {
|
||||
downloadWheel = agent.DownloadWheel
|
||||
}
|
||||
return &Server{log: log, cfgPath: cfgPath, logPath: filepath.Join(dir, logFileName), dir: dir, sup: sup, openBrowser: open, port: port, install: install, downloadWheel: downloadWheel}
|
||||
}
|
||||
|
||||
// Listen binds the loopback listener and returns it; Serve runs the server on
|
||||
@@ -451,12 +459,24 @@ func (s *Server) handleInstallRuntime(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
if pkg == "" {
|
||||
// No PyPI default on purpose: the PyPI name "scimesh" belongs to an
|
||||
// unrelated project, so a silent `pip install scimesh` would install
|
||||
// the wrong software.
|
||||
writeJSON(w, http.StatusConflict, map[string]string{
|
||||
"error": "no scimesh source configured: set SCIMESH_PIP_PACKAGE to your wheel, checkout or index, then retry",
|
||||
})
|
||||
return
|
||||
// unrelated project. Instead we ship the wheel in our own GitHub
|
||||
// release, version-locked to this binary, and download it from there.
|
||||
url, _, err := agent.ReleaseWheelURL(agent.Version)
|
||||
if err != nil {
|
||||
writeJSON(w, http.StatusConflict, map[string]string{
|
||||
"error": "no scimesh source configured: set SCIMESH_PIP_PACKAGE to your wheel, checkout or index, then retry",
|
||||
})
|
||||
return
|
||||
}
|
||||
local, err := s.downloadWheel(r.Context(), url, s.dir)
|
||||
if err != nil {
|
||||
s.log.Error("download release wheel", "err", err, "url", url)
|
||||
writeJSON(w, http.StatusConflict, map[string]string{
|
||||
"error": "could not download the scimesh wheel for this release: " + err.Error() + ". Set SCIMESH_PIP_PACKAGE to your wheel, checkout or index and retry.",
|
||||
})
|
||||
return
|
||||
}
|
||||
pkg = local
|
||||
}
|
||||
|
||||
python3, err := exec.LookPath("python3")
|
||||
|
||||
@@ -29,6 +29,11 @@ func newTestServer(t *testing.T, sup Supervisor) (*Server, string) {
|
||||
}
|
||||
|
||||
func newTestServerWithInstall(t *testing.T, sup Supervisor, install func(ctx context.Context, venvPython, pkg string) error) (*Server, string) {
|
||||
t.Helper()
|
||||
return newTestServerWithInstallAndWheel(t, sup, install, nil)
|
||||
}
|
||||
|
||||
func newTestServerWithInstallAndWheel(t *testing.T, sup Supervisor, install func(ctx context.Context, venvPython, pkg string) error, wheel func(ctx context.Context, url, dir string) (string, error)) (*Server, string) {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
server := New(testLogger(), Options{
|
||||
@@ -41,6 +46,7 @@ func newTestServerWithInstall(t *testing.T, sup Supervisor, install func(ctx con
|
||||
Supervisor: sup,
|
||||
OpenBrowser: func(string) {},
|
||||
InstallScimesh: install,
|
||||
DownloadWheel: wheel,
|
||||
})
|
||||
listener, err := server.Listen()
|
||||
if err != nil {
|
||||
@@ -353,3 +359,53 @@ func TestInstallRuntimeFailureIsExplained(t *testing.T) {
|
||||
t.Errorf("error = %v, want a hint about SCIMESH_PIP_PACKAGE", data["error"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallRuntimeDownloadsReleaseWheelWhenNoSource(t *testing.T) {
|
||||
oldVersion := agent.Version
|
||||
agent.Version = "1.1.0-alpha.10"
|
||||
t.Cleanup(func() { agent.Version = oldVersion })
|
||||
|
||||
var downloadedURL, installedPkg string
|
||||
sup := &fakeSup{}
|
||||
_, base := newTestServerWithInstallAndWheel(t, sup,
|
||||
func(ctx context.Context, venvPython, pkg string) error {
|
||||
installedPkg = pkg
|
||||
return nil
|
||||
},
|
||||
func(ctx context.Context, url, dir string) (string, error) {
|
||||
downloadedURL = url
|
||||
return filepath.Join(dir, "scimesh-1.1.0a10-py3-none-any.whl"), nil
|
||||
})
|
||||
|
||||
rec, data := postJSON(t, base, "/api/runtime/install", map[string]any{})
|
||||
if rec.Code != http.StatusOK || data["ok"] != true {
|
||||
t.Fatalf("install: got %d %v, want 200 ok", rec.Code, data)
|
||||
}
|
||||
if !strings.Contains(downloadedURL, "releases/download/v1.1.0-alpha.10/scimesh-1.1.0a10-py3-none-any.whl") {
|
||||
t.Errorf("download url = %q, want the release wheel of this version", downloadedURL)
|
||||
}
|
||||
if !strings.HasSuffix(installedPkg, "scimesh-1.1.0a10-py3-none-any.whl") {
|
||||
t.Errorf("pip received %q, want the downloaded wheel", installedPkg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallRuntimeWheelDownloadFailureIsExplained(t *testing.T) {
|
||||
oldVersion := agent.Version
|
||||
agent.Version = "1.1.0-alpha.10"
|
||||
t.Cleanup(func() { agent.Version = oldVersion })
|
||||
|
||||
sup := &fakeSup{}
|
||||
_, base := newTestServerWithInstallAndWheel(t, sup,
|
||||
func(ctx context.Context, venvPython, pkg string) error { t.Fatal("pip must not run"); return nil },
|
||||
func(ctx context.Context, url, dir string) (string, error) {
|
||||
return "", errors.New("HTTP 404")
|
||||
})
|
||||
|
||||
rec, data := postJSON(t, base, "/api/runtime/install", map[string]any{})
|
||||
if rec.Code != http.StatusConflict {
|
||||
t.Fatalf("got %d, want 409", rec.Code)
|
||||
}
|
||||
if !strings.Contains(data["error"].(string), "SCIMESH_PIP_PACKAGE") {
|
||||
t.Errorf("error = %v, want a SCIMESH_PIP_PACKAGE hint", data["error"])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user