Port envd from e2b with internalized shared packages and Connect RPC
- Copy envd source from e2b-dev/infra, internalize shared dependencies
into envd/internal/shared/ (keys, filesystem, id, smap, utils)
- Switch from gRPC to Connect RPC for all envd services
- Update module paths to git.omukk.dev/wrenn/{sandbox,sandbox/envd}
- Add proto specs (process, filesystem) with buf-based code generation
- Implement full envd: process exec, filesystem ops, port forwarding,
cgroup management, MMDS integration, and HTTP API
- Update main module dependencies (firecracker SDK, pgx, goose, etc.)
- Remove placeholder .gitkeep files replaced by real implementations
This commit is contained in:
93
envd/internal/api/store.go
Normal file
93
envd/internal/api/store.go
Normal file
@ -0,0 +1,93 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"git.omukk.dev/wrenn/sandbox/envd/internal/execcontext"
|
||||
"git.omukk.dev/wrenn/sandbox/envd/internal/host"
|
||||
"git.omukk.dev/wrenn/sandbox/envd/internal/utils"
|
||||
)
|
||||
|
||||
// MMDSClient provides access to MMDS metadata.
|
||||
type MMDSClient interface {
|
||||
GetAccessTokenHash(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
// DefaultMMDSClient is the production implementation that calls the real MMDS endpoint.
|
||||
type DefaultMMDSClient struct{}
|
||||
|
||||
func (c *DefaultMMDSClient) GetAccessTokenHash(ctx context.Context) (string, error) {
|
||||
return host.GetAccessTokenHashFromMMDS(ctx)
|
||||
}
|
||||
|
||||
type API struct {
|
||||
isNotFC bool
|
||||
logger *zerolog.Logger
|
||||
accessToken *SecureToken
|
||||
defaults *execcontext.Defaults
|
||||
|
||||
mmdsChan chan *host.MMDSOpts
|
||||
hyperloopLock sync.Mutex
|
||||
mmdsClient MMDSClient
|
||||
|
||||
lastSetTime *utils.AtomicMax
|
||||
initLock sync.Mutex
|
||||
}
|
||||
|
||||
func New(l *zerolog.Logger, defaults *execcontext.Defaults, mmdsChan chan *host.MMDSOpts, isNotFC bool) *API {
|
||||
return &API{
|
||||
logger: l,
|
||||
defaults: defaults,
|
||||
mmdsChan: mmdsChan,
|
||||
isNotFC: isNotFC,
|
||||
mmdsClient: &DefaultMMDSClient{},
|
||||
lastSetTime: utils.NewAtomicMax(),
|
||||
accessToken: &SecureToken{},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) GetHealth(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
a.logger.Trace().Msg("Health check")
|
||||
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
w.Header().Set("Content-Type", "")
|
||||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func (a *API) GetMetrics(w http.ResponseWriter, r *http.Request) {
|
||||
defer r.Body.Close()
|
||||
|
||||
a.logger.Trace().Msg("Get metrics")
|
||||
|
||||
w.Header().Set("Cache-Control", "no-store")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
metrics, err := host.GetMetrics()
|
||||
if err != nil {
|
||||
a.logger.Error().Err(err).Msg("Failed to get metrics")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if err := json.NewEncoder(w).Encode(metrics); err != nil {
|
||||
a.logger.Error().Err(err).Msg("Failed to encode metrics")
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) getLogger(err error) *zerolog.Event {
|
||||
if err != nil {
|
||||
return a.logger.Error().Err(err) //nolint:zerologlint // this is only prep
|
||||
}
|
||||
|
||||
return a.logger.Info() //nolint:zerologlint // this is only prep
|
||||
}
|
||||
Reference in New Issue
Block a user