Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
Coder deployment for INF110
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Théo Zimmermann
Coder deployment for INF110
Commits
bcc3b01e
Unverified
Commit
bcc3b01e
authored
3 months ago
by
Théo Zimmermann
Browse files
Options
Downloads
Patches
Plain Diff
Add a start all workspaces function.
parent
abbd8eed
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Coder-management.ipynb
+18
-0
18 additions, 0 deletions
Coder-management.ipynb
with
18 additions
and
0 deletions
Coder-management.ipynb
+
18
−
0
View file @
bcc3b01e
...
...
@@ -433,6 +433,24 @@
"start_workspaces_from_group(mitro)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fd82a694-ba4b-4dba-aab1-08d1d606f625",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"def start_all_workspaces():\n",
" workspaces = !https GET \"tp-inf110.r2.enst.fr/api/v2/workspaces\" \"Coder-Session-Token:{token}\" \"limit==150\" \"q==status:stopped\" -b | jq -cr '.workspaces | .[]'\n",
" workspaces = list(map(json.loads, workspaces))\n",
" for workspace in [workspace['id'] for workspace in workspaces]:\n",
" !https POST \"tp-inf110.r2.enst.fr/api/v2/workspaces/{workspace}/builds\" \"Coder-Session-Token:{token}\" \"transition=start\" \"template_version_id={template_version}\"\n",
"\n",
"start_all_workspaces()"
]
},
{
"cell_type": "markdown",
"id": "e8e88940-8c7c-4b3c-8923-aaf0b813f524",
...
...
%% Cell type:markdown id:6d924ae8-e462-4c47-86d9-8560ecedf78f tags:
# Coder management
%% Cell type:code id:bb33cb2d-8256-4d65-9442-153a5eb920a6 tags:
```
python
import
csv
import
json
import
requests
```
%% Cell type:code id:991fc1f2-61d2-443f-901b-df6acf094287 tags:
```
python
cluster_name
=
'
inf110
'
proxyJump
=
'
ubuntu@137.194.210.143
'
```
%% Cell type:code id:ae9a0955-2a17-499a-827b-8dfe8be56d65 tags:
```
python
token
,
=
!
source
openrc
&&
echo
$
CODER_TOKEN
```
%% Cell type:code id:904c792f-2229-44cb-a98b-7714af05e163 tags:
```
python
response
=
requests
.
get
(
"
https://tp-inf110.r2.enst.fr/api/v2/buildinfo
"
)
response
.
raise_for_status
()
buildinfo
=
response
.
json
()
print
(
f
"
Version:
{
buildinfo
[
'
version
'
]
}
"
)
print
(
f
"
URL:
{
buildinfo
[
'
dashboard_url
'
]
}
"
)
```
%% Cell type:markdown id:463b7432-7861-44f6-8a42-36f453bf0a24 tags:
To retrieve the ID of the default organization, we can list the organizations of the admin user.
%% Cell type:code id:3d2d2fe7-c20b-4e7d-a5da-e0c8021cb6f8 tags:
```
python
user
=
"
Zimmi48
"
response
=
requests
.
get
(
f
"
https://tp-inf110.r2.enst.fr/api/v2/users/
{
user
}
/organizations
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
})
response
.
raise_for_status
()
organizations
=
response
.
json
()
print
(
f
"
Organizations:
{
organizations
}
"
)
organization_id
=
organizations
[
0
][
'
id
'
]
```
%% Cell type:markdown id:19a552b0-8bf8-4cd8-86a1-135b7e2253ed tags:
## Create workspace template
If it doesn't exist yet. Otherwise, retrieve the template and template version IDs.
%% Cell type:code id:b4db687e-3e52-448d-b4d7-8c812cdaa2f7 tags:
```
python
# Test if template exists
response
=
requests
.
get
(
f
"
https://tp-inf110.r2.enst.fr/api/v2/organizations/
{
organization_id
}
/templates
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
})
response
.
raise_for_status
()
templates
=
response
.
json
()
if
len
(
templates
)
==
1
:
template_id
=
templates
[
0
][
'
id
'
]
template_version
=
templates
[
0
][
'
active_version_id
'
]
print
(
f
"
Template found:
{
template_id
}
(version
{
template_version
}
)
"
)
elif
len
(
templates
)
==
0
:
print
(
"
No template found. Creating one...
"
)
# Create zip file to upload
!
cd
inf110
-
workspace
&&
zip
"
template.zip
"
"
main.tf
"
"
README.md
"
# Upload template files
with
open
(
"
inf110-workspace/template.zip
"
,
"
rb
"
)
as
f
:
response
=
requests
.
post
(
"
https://tp-inf110.r2.enst.fr/api/v2/files
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
,
"
Content-Type
"
:
"
application/zip
"
},
data
=
f
)
response
.
raise_for_status
()
file_hash
=
response
.
json
()[
'
hash
'
]
# Create template version
version_name
=
'
INF110-2024
'
response
=
requests
.
post
(
f
"
https://tp-inf110.r2.enst.fr/api/v2/organizations/
{
organization_id
}
/templateversions
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
},
json
=
{
"
name
"
:
version_name
,
"
file_id
"
:
file_hash
,
"
storage_method
"
:
"
file
"
,
"
provisioner
"
:
"
terraform
"
}
)
response
.
raise_for_status
()
template_version
=
response
.
json
()[
'
id
'
]
# Create template
template_name
=
'
INF110
'
display_name
=
'
TP INF110
'
description
=
"
Espace de travail pour les TP d
'
INF110
"
response
=
requests
.
post
(
f
"
https://tp-inf110.r2.enst.fr/api/v2/organizations/
{
organization_id
}
/templates
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
},
json
=
{
"
name
"
:
template_name
,
"
display_name
"
:
display_name
,
"
description
"
:
description
,
"
icon
"
:
"
/emojis/1f4d0.png
"
,
"
template_version_id
"
:
template_version
}
)
response
.
raise_for_status
()
template_id
=
response
.
json
()[
'
id
'
]
print
(
f
"
Template created:
{
template_id
}
(version
{
template_version
}
)
"
)
else
:
raise
ValueError
(
"
Multiple templates found
"
)
```
%% Cell type:markdown id:e20dfefb-0359-421a-92c6-ab403de529dc tags:
The query below can be used to check that the template creation was successful.
%% Cell type:code id:1ae74b43-8065-4e5f-9976-e00a879d7c99 tags:
```
python
response
=
requests
.
get
(
f
"
https://tp-inf110.r2.enst.fr/api/v2/templateversions/
{
template_version
}
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
})
response
.
raise_for_status
()
template_version
=
response
.
json
()
print
(
f
"
Template version:
{
template_version
[
'
job
'
][
'
status
'
]
}
"
)
```
%% Cell type:markdown id:5d900272-a3ee-461c-9cdd-df08b17b1d2a tags:
## Create users
%% Cell type:code id:02384bfa tags:
```
python
def
create_users
():
with
open
(
"
users.csv
"
)
as
f
:
reader
=
csv
.
reader
(
f
)
for
email
,
username
,
password
in
reader
:
response
=
requests
.
post
(
"
https://tp-inf110.r2.enst.fr/api/v2/users
"
,
headers
=
{
"
Coder-Session-Token
"
:
token
},
json
=
{
"
email
"
:
email
,
"
login_type
"
:
"
password
"
,
"
password
"
:
password
,
"
username
"
:
username
}
)
response
.
raise_for_status
()
print
(
f
"
User
{
username
}
created
"
)
#create_users()
```
%% Cell type:code id:9f05d75f-c300-49ca-9faf-19a1a24dd6d8 tags:
```
python
def
create_user
(
email
,
username
):
passwords
=
!
pwgen
-
s
10
-
1
password
=
passwords
[
0
]
!
echo
"
{email},{username},{password}
"
>>
users
.
csv
&&
\
https
POST
"
tp-inf110.r2.enst.fr/api/v2/users
"
"
Coder-Session-Token:{token}
"
"
email={email}
"
"
login_type=password
"
"
password={password}
"
"
username={username}
"
#create_user("", "")
```
%% Cell type:code id:96595327-81a0-4a50-b090-a79d75a3134d tags:
```
python
def
create_student_accounts
(
csv_filename
):
with
open
(
"
students_2024-2025.csv
"
)
as
f
:
reader
=
csv
.
DictReader
(
f
,
delimiter
=
'
;
'
)
for
student
in
reader
:
create_user
(
student
[
'
mail
'
],
student
[
'
login
'
].
split
(
'
@
'
)[
0
])
#create_student_accounts('students_2024-2025.csv')
```
%% Cell type:markdown id:9868d906-ca8c-4fda-ad96-ec00bea5fadc tags:
## Delete users
(Requires having deleted their workspaces first.)
%% Cell type:code id:30a56dca-7f8f-4839-94e7-36340f5f199f tags:
```
python
def
delete_user
(
username
):
!
https
DELETE
"
tp-inf110.r2.enst.fr/api/v2/users/{username}
"
"
Coder-Session-Token:{token}
"
#delete_user("bbinder")
```
%% Cell type:markdown id:d6d20c1f-e231-488c-90ef-2daa811e89a2 tags:
## Create workspaces
%% Cell type:code id:80ff8f4e-fa5f-4308-a885-e3d382e2a171 tags:
```
python
def
create_workspace
(
username
,
name
=
'
tp
'
):
!
https
POST
"
tp-inf110.r2.enst.fr/api/v2/organizations/{organization_id}/members/{username}/workspaces
"
"
Coder-Session-Token:{token}
"
"
name={name}
"
"
template_id={template_id}
"
#create_workspace("Zimmi48")
```
%% Cell type:markdown id:d2cea793-4b57-4718-bd17-7cbda610d5bd tags:
Test auto-scaling by creating many workspaces at once.
%% Cell type:code id:e3d06f0c-3183-47e4-a63e-254a6c08612a tags:
```
python
#for i in range(0,99):
# create_workspace('Zimmi48', 'autoscaling-test-%d' % i)
```
%% Cell type:code id:11d58691-691b-41a8-bdbf-51d3b313b64f tags:
```
python
def
create_student_workspaces
(
csv_filename
):
with
open
(
csv_filename
,
mode
=
'
r
'
)
as
csv_file
:
csv_reader
=
csv
.
DictReader
(
csv_file
)
for
student
in
csv_reader
:
create_workspace
(
student
[
'
login
'
])
#create_student_workspaces('students_2024-2025.csv')
```
%% Cell type:code id:f26e86ea tags:
```
python
def
create_user_workspaces
():
with
open
(
"
users.csv
"
)
as
f
:
reader
=
csv
.
reader
(
f
)
for
_
,
username
,
_
in
reader
:
create_workspace
(
username
)
#create_user_workspaces()
```
%% Cell type:markdown id:1b405071-7dd5-4082-80f2-dbd60ea46262 tags:
## Start / stop all workspaces from a student group
%% Cell type:code id:e9be7a12-c858-4baf-9ac7-53827330798a tags:
```
python
def
get_student_username_list
(
csv_filename
):
students
=
[]
with
open
(
csv_filename
,
mode
=
'
r
'
)
as
csv_file
:
csv_reader
=
csv
.
DictReader
(
csv_file
)
for
student
in
csv_reader
:
students
+=
[
student
[
'
login
'
]]
return
students
#groupB = get_student_username_list('inf110-2023-B.csv')
#groupD = get_student_username_list('inf110-2023-D.csv')
```
%% Cell type:code id:1640ad41-d82c-4519-88d3-ef2c2cfc2950 tags:
```
python
len
(
groupB
)
```
%% Cell type:code id:6b0b126a-b7e4-43c5-9aab-2c27931ebf91 tags:
```
python
len
(
groupD
)
```
%% Cell type:code id:b495de0f-d085-4db6-a8a4-9a022f345251 tags:
```
python
def
stop_workspaces_from_group
(
group
):
workspaces
=
!
https
GET
"
tp-inf110.r2.enst.fr/api/v2/workspaces
"
"
Coder-Session-Token:{token}
"
"
limit==150
"
"
q==status:running
"
-
b
|
jq
-
cr
'
.workspaces | .[]
'
workspaces
=
list
(
map
(
json
.
loads
,
workspaces
))
for
workspace
in
[
workspace
[
'
id
'
]
for
workspace
in
workspaces
if
workspace
[
'
owner_name
'
]
in
group
]:
!
https
POST
"
tp-inf110.r2.enst.fr/api/v2/workspaces/{workspace}/builds
"
"
Coder-Session-Token:{token}
"
"
transition=stop
"
stop_workspaces_from_group
([
'
Zimmi48
'
])
```
%% Cell type:code id:13f05a6e-f591-4bcd-9857-63f5a21f1028 tags:
```
python
def
start_workspaces_from_group
(
group
):
workspaces
=
!
https
GET
"
tp-inf110.r2.enst.fr/api/v2/workspaces
"
"
Coder-Session-Token:{token}
"
"
limit==150
"
"
q==status:stopped
"
-
b
|
jq
-
cr
'
.workspaces | .[]
'
workspaces
=
list
(
map
(
json
.
loads
,
workspaces
))
for
workspace
in
[
workspace
[
'
id
'
]
for
workspace
in
workspaces
if
workspace
[
'
owner_name
'
]
in
group
]:
!
https
POST
"
tp-inf110.r2.enst.fr/api/v2/workspaces/{workspace}/builds
"
"
Coder-Session-Token:{token}
"
"
transition=start
"
"
template_version_id={template_version}
"
start_workspaces_from_group
(
mitro
)
```
%% Cell type:code id:fd82a694-ba4b-4dba-aab1-08d1d606f625 tags:
```
python
def
start_all_workspaces
():
workspaces
=
!
https
GET
"
tp-inf110.r2.enst.fr/api/v2/workspaces
"
"
Coder-Session-Token:{token}
"
"
limit==150
"
"
q==status:stopped
"
-
b
|
jq
-
cr
'
.workspaces | .[]
'
workspaces
=
list
(
map
(
json
.
loads
,
workspaces
))
for
workspace
in
[
workspace
[
'
id
'
]
for
workspace
in
workspaces
]:
!
https
POST
"
tp-inf110.r2.enst.fr/api/v2/workspaces/{workspace}/builds
"
"
Coder-Session-Token:{token}
"
"
transition=start
"
"
template_version_id={template_version}
"
start_all_workspaces
()
```
%% Cell type:markdown id:e8e88940-8c7c-4b3c-8923-aaf0b813f524 tags:
## Delete all workspaces and users from a student group
%% Cell type:code id:5c22d1b3-923f-45fd-ac04-9f404e5002b6 tags:
```
python
def
delete_workspaces_from_group
(
group
):
workspaces
=
!
https
GET
"
tp-inf110.r2.enst.fr/api/v2/workspaces
"
"
Coder-Session-Token:{token}
"
"
limit==150
"
"
q==status:stopped
"
-
b
|
jq
-
cr
'
.workspaces | .[]
'
workspaces
=
list
(
map
(
json
.
loads
,
workspaces
))
for
workspace
in
[
workspace
[
'
id
'
]
for
workspace
in
workspaces
if
workspace
[
'
owner_name
'
]
in
group
]:
!
https
POST
"
tp-inf110.r2.enst.fr/api/v2/workspaces/{workspace}/builds
"
"
Coder-Session-Token:{token}
"
"
transition=delete
"
delete_workspaces_from_group
([
'
Zimmi48
'
])
```
%% Cell type:code id:eafaba21-fdf9-46e9-ba8f-bc1f25de96a4 tags:
```
python
def
delete_students
(
group
):
for
student
in
group
:
delete_user
(
student
)
delete_students
(
groupD
)
```
%% Cell type:markdown id:12c57f21-23fe-4752-ad28-b05bd33ff08f tags:
## Stop all unhealthy workspaces
%% Cell type:code id:73ce34f9-b0ad-4434-b448-6e2fdcfed6bd tags:
```
python
def
stop_unhealthy_workspaces
():
workspaces
=
!
https
GET
"
tp-inf110.r2.enst.fr/api/v2/workspaces
"
"
Coder-Session-Token:{token}
"
"
limit==150
"
"
q==status:running
"
-
b
|
jq
-
cr
'
.workspaces | .[]
'
workspaces
=
list
(
map
(
json
.
loads
,
workspaces
))
for
workspace
in
[
workspace
for
workspace
in
workspaces
if
not
workspace
[
'
health
'
][
'
healthy
'
]]:
!
https
POST
"
tp-inf110.r2.enst.fr/api/v2/workspaces/{workspace[
'
id
'
]}/builds
"
"
Coder-Session-Token:{token}
"
"
transition=stop
"
stop_unhealthy_workspaces
()
```
%% Cell type:markdown id:acd9cb0e-9596-4091-ae35-82a34ff9f0b4 tags:
## Check health of running workspaces
%% Cell type:code id:6c4beb11-717a-4d89-b9a4-e9b033b3e6a4 tags:
```
python
servers
=
{}
```
%% Cell type:code id:9bcdc633-0b28-46e4-aa54-97dc20f7d091 tags:
```
python
healthy_workspaces
=
[]
unhealthy_workspaces
=
[]
workspaces
=
!
https
GET
"
tp-inf110.r2.enst.fr/api/v2/workspaces
"
"
Coder-Session-Token:{token}
"
"
limit==150
"
"
q==status:running
"
-
b
|
jq
-
cr
'
.workspaces | .[]
'
workspaces
=
list
(
map
(
json
.
loads
,
workspaces
))
for
workspace
in
workspaces
:
if
workspace
[
'
health
'
][
'
healthy
'
]:
healthy_workspaces
+=
[
workspace
[
'
owner_name
'
].
lower
()]
else
:
unhealthy_workspaces
+=
[
workspace
[
'
owner_name
'
].
lower
()]
```
%% Cell type:code id:ffb92e49-aa8b-4371-bade-a06104020e32 tags:
```
python
print
(
"
Healthy workspaces: %d
"
%
len
(
healthy_workspaces
))
print
(
"
Unhealthy workspaces: %d
"
%
len
(
unhealthy_workspaces
))
```
%% Cell type:code id:08d53bc7-fd70-4a7f-97d3-be5e737cdbaa tags:
```
python
volumes
=
!
source
openrc
&&
openstack
volume
list
--
long
-
f
json
|
jq
-
c
'
.[] | { id: .Name, name: .Properties.
"
csi.storage.k8s.io/pvc/name
"
, status: .Status, location: .Name, attached_to: .
"
Attached to
"
} | select(.name != null) | select(.name | startswith(
"
coder-pvc-
"
) and contains(
"
-tp-inf110
"
)) | { name: .id, username: .name | split(
"
coder-pvc-
"
) | .[1] | split(
"
-tp-inf110
"
) | .[0], status: .status, server_id: .attached_to[0].server_id, location: (
"
/var/lib/kubelet/plugins/kubernetes.io/csi/pv/
"
+ .location +
"
/globalmount
"
) }
'
volumes
=
list
(
map
(
json
.
loads
,
volumes
))
```
%% Cell type:code id:c183542f-6abf-4fbe-8b64-386da87a2c95 tags:
```
python
[
volume
for
volume
in
volumes
if
volume
[
'
server_id
'
]
is
not
None
and
not
volume
[
'
username
'
]
in
healthy_workspaces
]
```
%% Cell type:code id:db003235-11d9-4386-b8fe-944955e5e257 tags:
```
python
for
server
in
servers
:
servers
[
server
][
'
users
'
]
=
[]
for
volume
in
volumes
:
if
volume
[
'
server_id
'
]
is
not
None
:
if
not
volume
[
'
server_id
'
]
in
servers
:
ip
,
=
!
source
openrc
&&
openstack
server
show
"
{volume[
'
server_id
'
]}
"
-
f
json
|
jq
-
r
'
.addresses.
"
{cluster_name}
"
[0]
'
servers
[
volume
[
'
server_id
'
]]
=
{
'
ip
'
:
ip
,
'
users
'
:
[
volume
[
'
username
'
]]
}
else
:
servers
[
volume
[
'
server_id
'
]][
'
users
'
]
+=
[
volume
[
'
username
'
]]
```
%% Cell type:code id:8cee7a31-4e22-4ff4-9b06-5c6b014ddea8 tags:
```
python
for
server
in
servers
:
print
(
"
Server:
"
+
servers
[
server
][
'
ip
'
])
for
user
in
servers
[
server
][
'
users
'
]:
print
(
'
User:
'
+
user
,
end
=
''
)
if
user
in
healthy_workspaces
:
print
(
'
(healthy)
'
)
elif
user
in
unhealthy_workspaces
:
print
(
'
(unhealthy)
'
)
else
:
print
(
'
(unknown)
'
)
print
()
print
()
```
%% Cell type:markdown id:79725809-695a-4ab4-9e58-79bb747b8b05 tags:
## Clean workspaces
%% Cell type:markdown id:a5032d9b-aff8-459d-91fb-1b49709c232b tags:
Note that the
`StrictHostKeyChecking=no`
below does not apply to the proxy jump. Make sure you connected at least once to the proxy jump before running the following cells.
%% Cell type:code id:1a29e39d-2abb-4b2a-b663-3455f956b46d tags:
```
python
def
remove_lost_found
():
for
volume
in
volumes
:
if
volume
[
'
server_id
'
]
is
not
None
:
machine_ip
=
servers
[
volume
[
'
server_id
'
]][
'
ip
'
]
lost_found
=
volume
[
'
location
'
]
+
"
/lost+found
"
command
=
"
set -xe;
"
command
+=
"
if [ -d
"
+
lost_found
+
"
]; then rmdir -v
"
+
lost_found
+
"
; else echo
'
No lost+found to remove
'
; fi;
"
!
ssh
-
o
StrictHostKeyChecking
=
no
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
sh
-
c
"
\"
{command}
\"
"
remove_lost_found
()
```
%% Cell type:markdown id:75661986-3bb2-42b0-abe6-1a5f18ea9615 tags:
## Copy / update files in workspace
%% Cell type:code id:13d7c970-4863-4fac-bb58-722bb9c27f34 tags:
```
python
past_versions
=
{
'
tp1.ipynb
'
:
[
'
e6f11284e2ba7d4a01350a1f2c0ab208
'
,
'
c208201a6aaf72f102fbd2cf46b62e5b
'
,
],
'
tp2.mv
'
:
[
'
b3b2a3e7a8dde6ed8848300158d89e5d
'
,
'
60a26b6a7d07579f63f6054c24b87ea2
'
,
'
190845731e26037dcbc7e3a74d239b1b
'
,
'
d010ae9ab0188b4cc77a3d5a45df2f1a
'
,
],
'
tp3.mv
'
:
[
'
91621d47a84e460e567dc51dfe1fcf45
'
,
],
'
tp4.mv
'
:
[
'
a819a3d31373750cfcb8473a27cd5c3f
'
,
],
'
tp5.mv
'
:
[],
'
settings.json
'
:
[
'
aca81e70023acea605dd44e829d04339
'
,
# Autogenerated by coq-lsp
'
7378b13908523bfde3692518f61939cf
'
,
'
2c2178abd6661d10ae492bf6fdc0454b
'
,
'
350ac51d8fea466958d9986c96c84842
'
,
'
ded5f984f385aa61ef30e01fef43f3e4
'
,
'
8f3c325edd4f635fdaee9175701216df
'
,
],
"
_CoqProject
"
:
[],
}
location
=
"
inf110-workspace-contents/
"
```
%% Cell type:code id:876c1a46-9dd4-4f4c-8a4e-185dc361d5a1 tags:
```
python
current_version
=
{
'
tp1.ipynb
'
:
'
009c42561f1853af966f95e9dcee9c24
'
,
'
tp2.mv
'
:
'
78139922e6b6a531e7e70acc98c1019c
'
,
'
tp3.mv
'
:
'
0a0253e4825146da6f08eff073b10444
'
,
'
tp4.mv
'
:
'
203ce16afa53d60cfd8390fb3fb7d898
'
,
'
tp5.mv
'
:
'
3ec8626aa544cb075af1f78719a1fb48
'
,
'
settings.json
'
:
'
3ddc1036917034cec13503b74d3b051e
'
,
'
_CoqProject
'
:
'
b1d60da8dd98106e00006d99428d1403
'
,
}
```
%% Cell type:code id:a8f0c5e5-f995-43bd-9cb8-08099e6ea8fa tags:
```
python
def
copy_update_file
(
filename
):
file_hash
,
=
!
md5sum
{
location
+
filename
}
|
cut
-
f1
-
d
'
'
if
file_hash
!=
current_version
[
filename
]:
print
(
"
Hash of
"
+
filename
+
"
has changed. Please update past_versions and current_version. New hash is
"
+
file_hash
)
return
for
server
in
servers
:
!
scp
-
o
StrictHostKeyChecking
=
no
-
J
{
proxyJump
}
{
location
+
filename
}
core
@
{
servers
[
server
][
'
ip
'
]}:
/
tmp
for
volume
in
volumes
:
if
volume
[
'
server_id
'
]
is
not
None
:
machine_ip
=
servers
[
volume
[
'
server_id
'
]][
'
ip
'
]
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
cp
-
nv
/
tmp
/
{
filename
}
{
volume
[
'
location
'
]}
file_hash
,
=
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
md5sum
{
volume
[
'
location
'
]
+
"
/
"
+
filename
}
|
cut
-
f1
-
d
'
'
if
file_hash
in
past_versions
[
filename
]:
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
cp
-
v
/
tmp
/
{
filename
}
{
volume
[
'
location
'
]}
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
chmod
go
+
rw
{
volume
[
'
location
'
]
+
"
/
"
+
filename
}
copy_update_file
(
"
tp1.ipynb
"
)
copy_update_file
(
"
_CoqProject
"
)
copy_update_file
(
"
tp2.mv
"
)
copy_update_file
(
"
tp3.mv
"
)
copy_update_file
(
"
tp4.mv
"
)
copy_update_file
(
"
tp5.mv
"
)
```
%% Cell type:code id:13608dc8-78f6-41d3-9cc3-f96c603a9437 tags:
```
python
def
copy_read_only_file
(
filename
):
for
server
in
servers
:
!
scp
-
J
{
proxyJump
}
{
location
+
filename
}
core
@
{
servers
[
server
][
'
ip
'
]}:
/
tmp
for
volume
in
volumes
:
if
volume
[
'
server_id
'
]
is
not
None
:
machine_ip
=
servers
[
volume
[
'
server_id
'
]][
'
ip
'
]
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
cp
-
v
/
tmp
/
{
filename
}
{
volume
[
'
location
'
]}
copy_read_only_file
(
'
README.md
'
)
copy_read_only_file
(
"
tp1-mysterious-tm.png
"
)
```
%% Cell type:code id:4cc929db-08fe-4b7b-9293-d86b7124f7cf tags:
```
python
def
copy_vscode_settings
():
file_hash
,
=
!
md5sum
{
location
+
"
settings.json
"
}
|
cut
-
f1
-
d
'
'
if
file_hash
!=
current_version
[
'
settings.json
'
]:
print
(
"
Hash of settings.json has changed. Please update past_versions and current_version. New hash is
"
+
file_hash
)
return
for
server
in
servers
:
!
scp
-
J
{
proxyJump
}
-
o
StrictHostKeyChecking
=
no
{
location
+
"
settings.json
"
}
core
@
{
servers
[
server
][
'
ip
'
]}:
/
tmp
for
volume
in
volumes
:
if
volume
[
'
server_id
'
]
is
not
None
:
machine_ip
=
servers
[
volume
[
'
server_id
'
]][
'
ip
'
]
vscode
=
volume
[
'
location
'
]
+
"
/.vscode
"
command
=
"
set -xe;
"
command
+=
"
if [ ! -d
"
+
vscode
+
"
]; then mkdir
"
+
vscode
+
"
; fi;
"
command
+=
"
cp -nv /tmp/settings.json
"
+
vscode
+
"
/settings.json;
"
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
sh
-
c
"
\"
{command}
\"
"
file_hash
,
=
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
md5sum
{
vscode
+
"
/settings.json
"
}
|
cut
-
f1
-
d
'
'
if
file_hash
in
past_versions
[
'
settings.json
'
]:
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
cp
-
v
/
tmp
/
settings
.
json
{
vscode
}
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
chmod
go
+
rw
{
vscode
+
"
/settings.json
"
}
copy_vscode_settings
()
```
%% Cell type:markdown id:55bd39c3-794e-43f2-8bf0-342361d61b64 tags:
## Save snapshots of modified files
%% Cell type:code id:db436f12-abb7-4b48-9e66-2f6ada19bdff tags:
```
python
def
snapshot
(
filename
,
snapshot_name
):
!
mkdir
-
p
{
snapshot_name
}
for
volume
in
volumes
:
if
volume
[
'
server_id
'
]
is
not
None
:
machine_ip
=
servers
[
volume
[
'
server_id
'
]][
'
ip
'
]
file_hash
,
=
!
ssh
-
o
StrictHostKeyChecking
=
no
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
md5sum
{
volume
[
'
location
'
]
+
"
/
"
+
filename
}
|
cut
-
f1
-
d
'
'
if
not
file_hash
==
current_version
[
filename
]
and
not
file_hash
in
past_versions
[
filename
]:
snapshot_filename
=
"
/tmp/
"
+
volume
[
'
username
'
]
+
"
-
"
+
snapshot_name
+
"
-
"
+
filename
!
ssh
-
J
{
proxyJump
}
core
@
{
machine_ip
}
sudo
cp
{
volume
[
'
location
'
]
+
"
/
"
+
filename
}
{
snapshot_filename
}
!
scp
-
J
{
proxyJump
}
core
@
{
machine_ip
}:{
snapshot_filename
}
{
snapshot_name
+
"
/
"
+
volume
[
'
username
'
]
+
"
_
"
+
filename
}
#snapshot('tp1.ipynb', '2023-12-04-post-tp')
#snapshot('tp2.mv', '2023-12-13-post-tp')
#snapshot('tp3.mv', '2023-12-13-post-tp')
#snapshot('tp4.mv', '2024-01-12-post-tp')
#snapshot('tp5.mv', '2024-01-22-post-tp')
```
%% Cell type:code id:35af9e82-e79c-4ad9-a843-3ebaab9f4d62 tags:
```
python
```
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment