(_ func())
| 31 | ) |
| 32 | |
| 33 | func (r *RootCmd) Server(_ func()) *serpent.Command { |
| 34 | cmd := r.RootCmd.Server(func(ctx context.Context, options *agplcoderd.Options) (*agplcoderd.API, io.Closer, error) { |
| 35 | if options.DeploymentValues.DERP.Server.RelayURL.String() != "" { |
| 36 | _, err := url.Parse(options.DeploymentValues.DERP.Server.RelayURL.String()) |
| 37 | if err != nil { |
| 38 | return nil, nil, xerrors.Errorf("derp-server-relay-address must be a valid HTTP URL: %w", err) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | // Always generate a mesh key, even if the built-in DERP server is |
| 43 | // disabled. This mesh key is still used by workspace proxies running |
| 44 | // HA. |
| 45 | var meshKey string |
| 46 | err := options.Database.InTx(func(tx database.Store) error { |
| 47 | // This will block until the lock is acquired, and will be |
| 48 | // automatically released when the transaction ends. |
| 49 | err := tx.AcquireLock(ctx, database.LockIDEnterpriseDeploymentSetup) |
| 50 | if err != nil { |
| 51 | return xerrors.Errorf("acquire lock: %w", err) |
| 52 | } |
| 53 | |
| 54 | meshKey, err = tx.GetDERPMeshKey(ctx) |
| 55 | if err == nil { |
| 56 | return nil |
| 57 | } |
| 58 | if !errors.Is(err, sql.ErrNoRows) { |
| 59 | return xerrors.Errorf("get DERP mesh key: %w", err) |
| 60 | } |
| 61 | meshKey, err = cryptorand.String(32) |
| 62 | if err != nil { |
| 63 | return xerrors.Errorf("generate DERP mesh key: %w", err) |
| 64 | } |
| 65 | err = tx.InsertDERPMeshKey(ctx, meshKey) |
| 66 | if err != nil { |
| 67 | return xerrors.Errorf("insert DERP mesh key: %w", err) |
| 68 | } |
| 69 | return nil |
| 70 | }, nil) |
| 71 | if err != nil { |
| 72 | return nil, nil, err |
| 73 | } |
| 74 | if meshKey == "" { |
| 75 | return nil, nil, xerrors.New("mesh key is empty") |
| 76 | } |
| 77 | |
| 78 | if options.DeploymentValues.DERP.Server.Enable { |
| 79 | options.DERPServer = derp.NewServer(key.NewNode(), tailnet.Logger(options.Logger.Named("derp"))) |
| 80 | options.DERPServer.SetMeshKey(meshKey) |
| 81 | } |
| 82 | |
| 83 | options.Auditor = audit.NewAuditor( |
| 84 | options.Database, |
| 85 | audit.DefaultFilter, |
| 86 | backends.NewPostgres(options.Database, true), |
| 87 | backends.NewSlog(options.Logger), |
| 88 | ) |
| 89 | |
| 90 | options.TrialGenerator = trialer.New(options.Database, "https://v2-licensor.coder.com/trial", coderd.Keys) |
no test coverage detected