sync new and updated containers to cluster store, no deletion yet

This commit is contained in:
Pavel Sviderski
2024-11-19 16:06:16 +10:00
parent bf10b21da5
commit b4c2ec3a2a
8 changed files with 107 additions and 22 deletions
+23
View File
@@ -0,0 +1,23 @@
package store
import (
"time"
"uncloud/internal/machine/docker/container"
)
const (
// SyncStatusSynced indicates that a container record is synchronised with the Docker daemon. The record may
// become outdated even when the status is "synced" if the machine crashes or a network partition occurs.
// The cluster membership state of the machine should also be checked to determine if the record can be trusted.
SyncStatusSynced = "synced"
// SyncStatusOutdated indicates that a container record may be outdated, for example, due to being unable
// to retrieve the container's state from the Docker daemon or when the machine is being stopped or restarted.
SyncStatusOutdated = "outdated"
)
type ContainerRecord struct {
Container *container.Container
MachineID string
SyncStatus string
UpdatedAt time.Time
}
Binary file not shown.
+1
View File
@@ -12,6 +12,7 @@ CREATE TABLE machines
name TEXT AS (json_extract(info, '$.name')),
-- info is a JSON-serialized MachineInfo protobuf message.
info TEXT NOT NULL DEFAULT '{}' CHECK (json_valid(info))
-- TODO: add created_at and updated_at fields to track machine age and last update time.
);
-- containers table stores the Uncloud-managed Docker containers created in the cluster.
+31
View File
@@ -3,12 +3,14 @@ package store
import (
"context"
_ "embed"
"encoding/json"
"errors"
"fmt"
"google.golang.org/protobuf/encoding/protojson"
"log/slog"
"uncloud/internal/corrosion"
"uncloud/internal/machine/api/pb"
"uncloud/internal/machine/docker/container"
)
var (
@@ -129,3 +131,32 @@ func (s *Store) SubscribeMachines(ctx context.Context) ([]*pb.MachineInfo, <-cha
return machines, changes, nil
}
// CreateOrUpdateContainer creates a new container record or updates an existing one in the store database.
// The container is associated with the given machine ID that indicates which machine the container is running on.
func (s *Store) CreateOrUpdateContainer(ctx context.Context, c *container.Container, machineID string) error {
cJSON, err := json.Marshal(c)
if err != nil {
return fmt.Errorf("marshal container: %w", err)
}
// Insert or update the container record if the container or machine ID has changed.
res, err := s.corro.ExecContext(ctx, `
INSERT INTO containers (id, container, machine_id, sync_status, updated_at)
VALUES (?, ?, ?, ?, datetime('now'))
ON CONFLICT (id) DO UPDATE SET container = excluded.container,
machine_id = excluded.machine_id,
sync_status = excluded.sync_status,
updated_at = excluded.updated_at
WHERE containers.container != excluded.container
OR containers.machine_id != excluded.machine_id`,
c.ID, string(cJSON), machineID, SyncStatusSynced)
if err != nil {
return fmt.Errorf("upsert query: %w", err)
}
if res.RowsAffected > 0 {
slog.Debug("Container record updated in store DB.", "id", c.ID, "machine_id", machineID)
}
return nil
}