Skip to content

Commit 7a3da33

Browse files
committed
Merge remote-tracking branch 'origin/master' into sso-exclusive-all
2 parents d9e8ec5 + 8cd1e7c commit 7a3da33

File tree

154 files changed

+3151
-3233
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+3151
-3233
lines changed

src/compute/compute/dev/4-startup-script.sh

+8-4
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@
1717

1818
set -v
1919

20-
export api_server=`cat conf/api_server`
21-
20+
. env.sh
2221

2322
function setState {
24-
id=`cat conf/compute_server_id`
23+
id=$COMPUTE_SERVER_ID
2524
name=$1
2625
state=${2:-'ready'}
2726
extra=${3:-''}
2827
timeout=${4:-0}
2928
progress=${5:-100}
29+
project_id=$PROJECT_ID
3030

3131
echo "$name is $state"
32-
curl -sk -u `cat conf/api_key`: -H 'Content-Type: application/json' -d "{\"id\":$id,\"name\":\"$name\",\"state\":\"$state\",\"extra\":\"$extra\",\"timeout\":$timeout,\"progress\":$progress}" $api_server/api/v2/compute/set-detailed-state
32+
PAYLOAD="{\"id\":$id,\"name\":\"$name\",\"state\":\"$state\",\"extra\":\"$extra\",\"timeout\":$timeout,\"progress\":$progress,\"project_id\":\"$project_id\"}"
33+
echo $PAYLOAD
34+
curl -sk -u $API_KEY: -H 'Content-Type: application/json' -d $PAYLOAD $API_SERVER/api/v2/compute/set-detailed-state
3335
}
3436

3537

@@ -53,6 +55,8 @@ setState vm start '' 60 60
5355
sleep 0.1
5456

5557
while true; do
58+
setState compute ready '' 35 100
59+
setState filesystem-sync ready '' 35 100
5660
setState vm ready '' 35 100
5761
sleep 30
5862
done

src/compute/compute/dev/README.md

+26-10
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@ The scripts here are helpful for developing the compute\-server manager, which i
22

33
1. Create the directory /tmp/user and make sure you can read it. Maybe even mount it from the target project.
44

5-
2. Make the conf/ directory here, with the same files as on /cocalc/conf in an actual compute\-server, except:
6-
- replace api_server by something like `http://localhost:5000/6659c2e3-ff5e-4bb4-9a43-8830aa951282/port/5000`, where the port is what you're using for your dev server and the project id is of your dev server. The point is that we're going to connect directly without going through some external server.
7-
- api_key: the one from an actual server will get deleted when you turn that server off, so make a different project level api key.
5+
2. The conf/ directory here has the same files as on /cocalc/conf in an actual compute\-server, except:
6+
- replace api_server by something like `http://127.0.0.1:5000/6659c2e3-ff5e-4bb4-9a43-8830aa951282/port/5000`, where the port is what you're using for your dev server and the project id is of your dev server. The point is that we're going to connect directly without going through some external server.
7+
- api_key: the one from an actual server will get deleted when you turn that server off, so make a different project level api key.
88

9-
This is obviously very confusing, and when developing this it was 10x worse... Maybe you'll be confused for 2 hours instead of 2 days.
9+
Type `tar xvf conf.tar` to get a template for the conf directory.
10+
You will need to change the contents of all the files you get, as
11+
mentioned above! Also, regarding the api_server, be especially careful
12+
about ipv4 versus ipv6, e.g., use 127.0.0.1 instead of localhost to
13+
nail down the protocol.
14+
15+
This is potentially confusing, and when developing this it was 10x worse... Maybe you'll be confused for 2 hours instead of 2 days.
1016

1117
3. Run each of the following four shell scripts in different terminals, in order.
1218

@@ -17,17 +23,27 @@ This is obviously very confusing, and when developing this it was 10x worse... M
1723
4-startup-script.sh
1824
```
1925

20-
However, a bunch of things are likely to go wrong. The scripts `1-websocketfs.sh` and `2-syncfs.sh` will definitely fail if support for FUSE isn't enabled for normal users where you are working! Test bindfs locally. You probably have to add `user_allow_other` to `/etc/fuse.conf`. For `2-syncfs.sh`, you must also install unionfs-fuse via `sudo apt install unionfs-fuse` . Also, you need to do the following so that testing of tmp being a "fast local data directory that isn't sync"'d can be done:
26+
However, a bunch of things are likely to go wrong.
2127

22-
```
23-
~/cocalc/src/compute/compute/dev$ sudo mkdir /data/tmp
24-
~/cocalc/src/compute/compute/dev$ sudo chown `whoami`:`whoami` /data/tmp
28+
**Problem:** Regarding the id of the compute server in the file [conf/compute\_server\_id](./conf/compute_server_id), create a self\-hosted compute server in the project on your dev server, then find the record in the postgresql database by querying the `compute_servers` table, and copy the id field from that. Note that the displayed id in the UI starts from 1 for each project, but `compute_server_id` must be the id in the database.
29+
30+
**Problem:** Get the [conf/api_key](./conf/api_key) by clicking start on the self\-hosted compute server, inspect the URL, and copy it from there. If you stop the server explicitly, then the api key is deleted from the project, so you need to make it again.
31+
32+
**Problem:** The scripts `1-websocketfs.sh` and `2-syncfs.sh` will definitely fail if support for FUSE isn't enabled for normal users where you are working! Test bindfs locally.
33+
34+
**Problem:** For `2-syncfs.sh`, you must also install unionfs\-fuse via `sudo apt install unionfs-fuse,` since the cocalc package @cocalc/sync\-fs assumes unionfs\-fuse is installed.
35+
36+
**Problem:** You need to do the following so that you can fully test the scratch functionality \(see [conf/exclude_from_sync](./conf/exclude_from_sync)\):
37+
38+
```sh
39+
sudo mkdir -p /data/scratch && sudo chown -R `whoami`:`whoami` /data
2540
```
2641

27-
Once you get the 4 scripts above to run, the net result is basically the same as using a compute server, but you can run it all locally, and debugging is massively easier. Without something like this, development is impossible, and even figuring out what configuration goes where could cost me days of confusion (even though I wrote it all!). It's complicated.
42+
Once you get the 4 scripts above to run, the net result is basically the same as using a compute server, but you can run it all locally, and development and debugging is ~~massively easier~~ possible! Without something like this, development is impossible, and even figuring out what configuration goes where could cost me days of confusion \(even though I wrote it all!\). It's complicated.
2843

2944
For debugging set the DEBUG env variable to different things according to the debug npm module. E.g.,
3045

3146
```sh
32-
DEBUG=* 2-syncfs.sh
47+
DEBUG_CONSOLE=yes DEBUG=* ./2-syncfs.sh
3348
```
49+

src/compute/compute/dev/conf.tar

10 KB
Binary file not shown.

src/compute/compute/dev/start-filesystem.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ async function main() {
4747
exports.fs = await mountProject({
4848
project_id: process.env.PROJECT_ID,
4949
path: PROJECT_HOME,
50-
options: { mountOptions: { allowOther: true, nonEmpty: true } },
50+
// NOTE: allowOther is disabled by default on Ubuntu and we do not need it.
51+
options: { mountOptions: { allowOther: false, nonEmpty: true } },
5152
unionfs,
5253
readTrackingFile: process.env.READ_TRACKING_FILE,
5354
exclude,
@@ -58,8 +59,9 @@ async function main() {
5859
});
5960
unmount = exports.fs.unmount;
6061
} catch (err) {
61-
console.log("something went wrong ", err);
62+
console.trace("something went wrong ", err);
6263
exitHandler();
64+
return;
6365
}
6466

6567
const info = () => {

src/compute/compute/lib/filesystem.ts

+24-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { mount } from "websocketfs";
1111
import getLogger from "@cocalc/backend/logger";
1212
import { project } from "@cocalc/api-client";
1313
import { serialize } from "cookie";
14-
import { join } from "path";
1514
import { API_COOKIE_NAME } from "@cocalc/backend/auth/cookie-names";
1615
import syncFS from "@cocalc/sync-fs";
1716
import {
@@ -100,7 +99,7 @@ export async function mountProject({
10099
// Ping to start project so it's possible to mount.
101100
await pingProjectUntilSuccess(project_id);
102101

103-
const remote = join(getProjectWebsocketUrl(project_id), "websocketfs");
102+
const remote = getProjectWebsocketUrl(project_id) + "/websocketfs";
104103
log("connecting to ", remote);
105104
const headers = { Cookie: serialize(API_COOKIE_NAME, apiKey) };
106105
// SECURITY: DO NOT log headers and connectOptions, obviously!
@@ -139,7 +138,7 @@ export async function mountProject({
139138
progress: 30,
140139
});
141140

142-
({ unmount } = await mount({
141+
const websocketfsMountOptions = {
143142
remote,
144143
path: homeMountPoint,
145144
...options,
@@ -149,9 +148,9 @@ export async function mountProject({
149148
...options.connectOptions,
150149
},
151150
mountOptions: {
152-
allowOther: true,
153-
nonEmpty: true,
154151
...options.mountOptions,
152+
allowOther: true, // this is critical to allow for fast bind mounts of scratch etc. as root.
153+
nonEmpty: true,
155154
},
156155
cacheTimeout,
157156
hidePath: "/.unionfs",
@@ -163,7 +162,26 @@ export async function mountProject({
163162
readTrackingExclude: exclude,
164163
// metadata file
165164
metadataFile,
166-
}));
165+
};
166+
167+
log("websocketfs -- mount options", websocketfsMountOptions);
168+
169+
try {
170+
({ unmount } = await mount(websocketfsMountOptions));
171+
} catch (err) {
172+
log("failed trying to mount -- ", err);
173+
log(
174+
"try again without allowOther, since some versions of FUSE do not support this option",
175+
);
176+
websocketfsMountOptions.mountOptions.allowOther = false;
177+
({ unmount } = await mount(websocketfsMountOptions));
178+
179+
// This worked so the problem is allow_other.
180+
throw Error(
181+
"fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf\n\n\nFix this:\n\n sudo sed -i 's/#user_allow_other/user_allow_other/g' /etc/fuse.conf\n\n\n",
182+
);
183+
}
184+
167185
pingInterval = setInterval(async () => {
168186
try {
169187
await project.ping({ project_id });

src/packages/database/postgres-server-queries.coffee

+6-24
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,12 @@ exports.extend_PostgreSQL = (ext) -> class PostgreSQL extends ext
338338
return await update_account_and_passport(@, opts)
339339

340340
###
341-
Account creation, deletion, existence
341+
Creating an account using SSO only.
342+
This needs to be rewritten in @cocalc/server like
343+
all the other account creation. This is horrible
344+
because
342345
###
343-
create_account: (opts={}) =>
346+
create_sso_account: (opts={}) =>
344347
opts = defaults opts,
345348
first_name : undefined
346349
last_name : undefined
@@ -357,7 +360,7 @@ exports.extend_PostgreSQL = (ext) -> class PostgreSQL extends ext
357360
usage_intent : undefined
358361
cb : required # cb(err, account_id)
359362

360-
dbg = @_dbg("create_account(#{opts.first_name}, #{opts.last_name}, #{opts.lti_id}, #{opts.email_address}, #{opts.passport_strategy}, #{opts.passport_id}), #{opts.usage_intent}")
363+
dbg = @_dbg("create_sso_account(#{opts.first_name}, #{opts.last_name}, #{opts.lti_id}, #{opts.email_address}, #{opts.passport_strategy}, #{opts.passport_id}), #{opts.usage_intent}")
361364
dbg()
362365

363366
for name in ['first_name', 'last_name']
@@ -974,27 +977,6 @@ exports.extend_PostgreSQL = (ext) -> class PostgreSQL extends ext
974977
@record_file_use(project_id:opts.project_id, path:opts.path, action:opts.action, account_id:opts.account_id, cb:cb)
975978
], (err)->opts.cb?(err))
976979

977-
###
978-
Rememberme cookie functionality
979-
###
980-
# Save remember me info in the database
981-
save_remember_me: (opts) =>
982-
opts = defaults opts,
983-
account_id : required
984-
hash : required
985-
value : required
986-
ttl : required
987-
cb : required
988-
if not @_validate_opts(opts) then return
989-
@_query
990-
query : 'INSERT INTO remember_me'
991-
values :
992-
'hash :: TEXT ' : opts.hash.slice(0,127)
993-
'value :: JSONB ' : opts.value
994-
'expire :: TIMESTAMP ' : expire_time(opts.ttl)
995-
'account_id :: UUID ' : opts.account_id
996-
conflict : 'hash'
997-
cb : opts.cb
998980

999981
# Invalidate all outstanding remember me cookies for the given account by
1000982
# deleting them from the remember_me key:value store.

src/packages/database/postgres/types.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,15 @@ export interface PostgreSQL extends EventEmitter {
191191
set_server_setting(opts: { name: string; value: string; cb: CB }): void;
192192
server_settings_synctable(): any; // returns a table
193193

194-
create_account(opts: {
194+
create_sso_account(opts: {
195195
first_name?: string; // invalid name will throw Error
196196
last_name?: string; // invalid name will throw Error
197197
created_by?: string;
198198
email_address?: string;
199199
password_hash?: string;
200-
passport_strategy?: any;
201-
passport_id?: string;
202-
passport_profile?: any;
200+
passport_strategy: any;
201+
passport_id: string;
202+
passport_profile: any;
203203
usage_intent?: string;
204204
cb: CB;
205205
}): void;
@@ -224,14 +224,6 @@ export interface PostgreSQL extends EventEmitter {
224224

225225
get_remember_me(opts: { hash: string; cb: CB });
226226

227-
save_remember_me(opts: {
228-
account_id: string;
229-
hash: string;
230-
value: string;
231-
ttl: number;
232-
cb: CB;
233-
});
234-
235227
passport_exists(opts: PassportExistsOpts): Promise<string | undefined>;
236228

237229
create_passport(opts: CreatePassportOpts): Promise<string>;

src/packages/database/settings/auth-sso-types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export interface PassportLoginOpts {
3131
update_on_login: boolean; // passed down from StrategyConf, default false
3232
cookie_ttl_s?: number; // how long the remember_me cookied lasts (default is a month or so)
3333
host: string;
34+
site_url: string;
3435
cb?: (err) => void;
3536
}
3637

src/packages/frontend/account.html

-6
This file was deleted.

src/packages/frontend/account/account-button.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ export const DefaultAccountDropDownLinks: React.FC<LinksProps> = ({
175175
className={"cocalc-account-button"}
176176
href=""
177177
>
178-
xSign out...
178+
Sign out...
179179
</a>
180180
</Popconfirm>
181181
</li>

src/packages/frontend/account/editor-settings/checkboxes.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ import { Rendered } from "@cocalc/frontend/app-framework";
99
import { IntlMessage, isIntlMessage } from "@cocalc/frontend/i18n";
1010
import { capitalize, keys } from "@cocalc/util/misc";
1111

12-
const EDITOR_SETTINGS_CHECKBOXES: {
13-
[setting: string]: IntlMessage | Rendered;
14-
} = {
12+
const EDITOR_SETTINGS_CHECKBOXES = {
1513
extra_button_bar: defineMessage({
1614
id: "account.editor-setting.checkbox.extra_button_bar",
1715
defaultMessage:
@@ -85,6 +83,7 @@ const EDITOR_SETTINGS_CHECKBOXES: {
8583
id: "account.editor-setting.checkbox.ask_jupyter_kernel",
8684
defaultMessage: "ask which kernel to use for a new Jupyter Notebook",
8785
}),
86+
show_my_other_cursors: "when editing the same file in multiple browsers",
8887
disable_jupyter_virtualization: defineMessage({
8988
id: "account.editor-setting.checkbox.disable_jupyter_virtualization",
9089
defaultMessage:

src/packages/frontend/account/licenses/licenses-page.tsx

+8-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
* License: MS-RSL – see LICENSE.md for details
44
*/
55

6-
import { React } from "@cocalc/frontend/app-framework";
76
import { Footer } from "@cocalc/frontend/customize";
87
import { BuyLicenseForProject } from "@cocalc/frontend/site-licenses/purchase/buy-license-for-project";
98
import { DOC_LICENSE_URL } from "../../billing/data";
@@ -12,20 +11,23 @@ import { ProjectsWithLicenses } from "./projects-with-licenses";
1211
import Next from "@cocalc/frontend/components/next";
1312
import { A } from "@cocalc/frontend/components/A";
1413

15-
export const LicensesPage: React.FC = () => {
14+
export function LicensesPage() {
1615
return (
17-
<div>
16+
<div style={{ maxWidth: "1000px", margin: "auto" }}>
1817
<div style={{ fontSize: "12pt" }}>
1918
<h3>About</h3>
2019
<A href={DOC_LICENSE_URL}>Licenses</A> allow you to automatically
2120
upgrade projects whenever they start up, so that they have more memory,
22-
better hosting, run faster, etc.
21+
run faster, etc.
2322
</div>
2423
<br />
2524
<div>
26-
<BuyLicenseForProject />
25+
<BuyLicenseForProject noVoucher />
2726
</div>
27+
<ManagedLicenses />
28+
<ProjectsWithLicenses />
2829
<div>
30+
{/* kind of outdated */}
2931
<h3>Links</h3>
3032
<ul style={{ fontSize: "12pt" }}>
3133
<li>
@@ -45,12 +47,7 @@ export const LicensesPage: React.FC = () => {
4547
</li>
4648
</ul>
4749
</div>
48-
<br />
49-
<ManagedLicenses />
50-
<br />
51-
<ProjectsWithLicenses />
52-
<br />
5350
<Footer />
5451
</div>
5552
);
56-
};
53+
}

src/packages/frontend/account/licenses/managed-licenses.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export const ManagedLicenses: React.FC = () => {
120120
return (
121121
<>
122122
<Title level={3}>
123-
Licenses that you manage {render_count()}
123+
Licenses You Manage {render_count()}
124124
<div style={{ float: "right" }}>{render_show_all()}</div>
125125
{loading && <Spin />}
126126
</Title>
@@ -148,7 +148,8 @@ function CancelSubscriptionBanner() {
148148
visit the Subscription tab above
149149
</a>
150150
. To edit a license <i>that you purchased</i> expand the license
151-
below, then click on the "Edit License..." button.
151+
below, then click on the "Edit License..." button. To apply a license
152+
to a project, select the project under Projects below.
152153
</>
153154
}
154155
/>

0 commit comments

Comments
 (0)