# timOhjeet

TIM-järjestelmän ylläpito

Ellei toisin ole mainittu, tässä dokumentissa esitettyjä toimintoja voivat käyttää vain TIMin ylläpitäjät.

Alla olevat ohjeet kuvaavat TIM CLI -komentorivityökalun toimintoa.

Komentorivityökalu voi ajaa kahdella tavalla:

  1. Menemällä TIM-kansioon (/opt/tim) ja ajamalla ./tim
  2. Ajamalla suoraan /opt/tim/tim

Voit myös tehdä bashiin alias ajamalla

alias tim="/bin/bash /opt/tim/tim" >> ~/.bashrc

jolloin olloin TIM CLI:tä voi käyttää globaalisti komennolla tim.

Tässä ohjeessa käytetään ./tim-muotoa (eli tapa 2).

1 Komponenttien alustus

Alustuksia joita pitää välillä tehdä (aukeavat automaattisesti toiseen tabiin):

2 Järjestelmän käynnistys ja päivitys

  • Käynnistä kaikki palvelut nykyisillä asetuksilla (katso tim.conf-asetustiedosto):

    ./tim up
  • Käynnistä tietty palvelu uudelleen ilman asetuksien päivvittämistä (esim. .py-tiedostoja on muutettu)

    ./tim restart palvelu

Pelkästään TIM-palvelimen saa käynnistettyä uudelleen osoitteesta

joka on parempi tapa kuin ./tim restart tim, koska tällä tavalla yhtäkään pyyntöä ei hukata. URL-tapa ei toimi, jos:

  • TIM-imagen sisältö (Dockerfile) on muuttunut, koska silloin tietenkin täytyy käynnistää palvelu uudelleen (./tim up)
  • tim.conf-tiedostoa muuttaa.
  • Tietokannan rakennetta päivittää.

2.1 Järjestelmän päivittäminen

TIM-koodi päivitetään ensin pullaamalla uusin koodi TIMin git-reposta ja valitsemalla haluttu commit.

Tämän jälkeen tarpeen mukaan pullataan Docker-imaget, pullataan NPM-pakkaukset, käännetään JavaScriptit, ajetaan tietokantamigraatiot ja käynnistetään palvelut uudelleen. Jokaiselle vaiheelle on valmiit komennot, mutta yleisimmät päivitykset saa hoidettua ./tim update-komennolla.

Alla oln lista yleisistä tilanteista ja sopivista ./tim update-komennoista:

Jos rupeaa ./tim up -komennon jälkeen buildaamaan jotain konttia, tämä voi kestää hyvin kauan. Silloin auttaa kun lopettaa buildaamisen ja antaa komennon

./tim dc pull

2.2 JS-kirjastojen päivittäminen ja kääntäminen

Jos lokaalissa koneessa muuttaa jsrunner hakemiston tools.js, niin (tuotannossa riittää ./tim js tai ./tim update front):

  • aja \tim\timApp\modules\jsrunner\server hakemistossa npm run buildtools
  • ./tim restart jsrunner
  • mahdollisestä käynnistä myös itse tim uudelleen jos tulee server erroria

Jos muuttaa muuta .ts tiedostoa tuolla, niin

  • ./tim restart jsrunner

Eli se workflow JS-kirjastojen päivittämisessä on:

  1. aja päivityskomento (npm install jotakin)
  2. npm muuttaa tiedostoja package.json ja package-lock.json
  3. commitoi muutokset gittiin ja puske
  4. käske muiden ajaa npm install hakemistossa timApp

timApp/static/xxx-hakemisto vastaa tim.jyu.fi/static/xxx -osoitetta.

2.3 Jypeli/NUnit päivittäminen

./tim dc exec csplugin bash
touch /cs_data/dotnet/refresh && cd /cs/dotnet && ./gen_deps.py /cs_data/dotnet

3 Konfiguraatio

# tim-conf

3.1 tim.conf

TIMin pääkonfiguraatio löytyy tiedostosta /opt/tim/tim.conf. Oletusarvot sekä alkuperäiset dokumentaatiot löytyvät tiedostosta default_config.py.

3.2 Flaskin konfiguraatio

Oletusarvot ovat tiedostossa timApp/defaultconfig.py. Tiedostossa timApp/prodconfig.py olevat arvot korvaavat oletusarvot. Tilanteesta riippuu, kannattaako muutoksia commitoida gittiin.

4 devs-koneen Caddyn käynnistäminen

Caddy on web-palvelin, joka ottaa vastaan tulevat HTTP-kutsut ja reitittää ne eteenpäin oikeisiin tim-instansseihin.

Käynistäminen devs-koneessa:

  • kirjaudu ssh:lla timdevs01.it.jyu.fi

  • anna komennot

    sudo systemctl restart caddy-tim

5 Sähköpostipalvelimen konfigurointi CentOS:ssa

Tiedostoon /etc/postfix/main.cf seuraavat muutokset:

myhostname = <koneen nimi>.it.jyu.fi
mydomain = it.jyu.fi

6 Globaali ilmoitus käyttäjille

Globaalit ilmoitukset poistuvat automaattisesti, kun koko TIM-kontti käynnistetään uudelleen (esim. ./dc stop tim tai ./restart.sh). Nämä ilmoitukset ovat erittäin kevyet ja nopeat eivätkä vaadi tietokantamerkintöjä. Käytä globaaleja ilmoituksia ilmoittamaan tulevista katkoista/uudelleenkäynnistyksistä.

Viestit eivät häviä tavallisen https://tim.jyu.fi/restart-polun kautta.

Tekstissä toimii markdown.

Viesti

Please to interact with this component.

{}

Please to interact with this component.

7 Globaali TIM-viesti

TIM-viesti soveltuu ilmoittamaan esimerkiksi tärkeistä TIM-päivityksistä. TIM-viestit ja niiden lukumerkinnät tallenetaan tietokantaan. Käyttäjät voivat piilottaa heille tulleet globaalit TIM-viestit.

TIM-viestit voi muokata jälkikäteen viestidokumentissa.
Kaikki globaalit TIM-viestit ovat messages/tim-messages/global-kansiossa.

Lisää uusi globaali TIM-viesti:

8 Ryhmät ja käyttäjät

8.1 TIM-ryhmät

Jotta voi luoda ryhmiä, pitää kuulua ryhmään:

8.2 Henkilön lisääminen GitLab-ryhmään

Avaa sivu TIMin kehitys ja valitse vasemmalta Members.

8.3 Henkilön lisääminen Korppi-postilistalle

8.4 Henkilön lisääminen SSH-ryhmään

Hakemistossa /root/bin on newuser-skripti. Skriptin ajaminen ilman komentorivin argumentteja tulostaa helpin. Jos etu- ja sukunimi on tiedossa, niin komento

sudo /root/bin/newuser -f -y Etunimi Sukunimi

hoitaa homman olettaen, että kyseisellä henkilöllä on JYU-tunnari.

Esim:

sudo /root/bin/newuser -f -y Matti Meikäläinen

8.5 Henkilön lisääminen sudo-ryhmään

Ubuntu:

sudo usermod -a -G sudo vejuoksa

CentOS:

sudo usermod -aG wheel username

Muista lisätä myös docker-ryhmään

sudo usermod -aG docker username

8.6 Kirjaantuminen toisena käyttäjänä

  • https://tim.jyu.fi/quickLogin/TUNNUS

Tunnus jolla kirjaannutaan

Please to interact with this component.

{}

Please to interact with this component.

8.7 Yksittäisen tunnuksen luonti tai päivittämien

./tim run flask user create \
    --username mameikal \
    --firstname Matti \
    --lastname Meikäläinen \
    --email mameikal@example.com \
    --password '' \
    --no-admin

Samalla komennolla jo olemassa olevan käyttäjän tiedot voi päivittää. Esimerkiksi sähköpostin vaihtaminen kannattaa tehdä tällä komennolla, jotta muutos rekisteröityy TIMin postipalvelimelle oikein. Siinä tapauksessa tyhjäksi jätetyt arvot ei päivitetä.

Osan tai kaikki parametreista voi jättää antamatta, jolloin ne kysytään.
Tietojen päivittämistä varten tulee antaa vähintään muutettavan käyttäjän käyttäjätunnus.

8.8 Tunnusten massaluonti

Nimen muoto? Erotellankos tuolta nykyisin jotenkin kutsumanimi ja muu nimi?

Voikos ilman csv-tiedostoa luoda pikaisesti yhden tai useamman käyttäjän?y

21 Apr 21 (edited 21 Apr 21)

Tuo import ei erottele vaan laitetaan full nameen suoraan se mikä on csv:ssä.

Laitoin ylemmäs esimerkin yksittäisen käyttäjän luonnista.

VL: Mutta voisiko csv.ssä olla haluttaessa valmiina nimi osissa jolloin saisi kutsumanimen oikein?

21 Apr 21 (edited 21 Apr 21)
./tim run flask user import --csvfile <CSV file> --password <password for all accounts>

HUOM: CSV-tiedoston on oltava jossain /opt/tim-polussa. CLI-komennossa polku pitää antaa myös polun /opt/tim/timApp suhteen. Siispä jos esimerkiksi on CSV-tiedosto /opt/tim/kayttajat.csv, pitää kirjoittaa --csvfile ../kayttajat.csv.

CSV-tiedostossa on oltava seuraavat 3 saraketta (erottimena ;):

  1. käyttäjän sähköpostiosoite
  2. koko nimi muodossa Sukunimi Etunimet
  3. käyttäjätunnus

Emailin tai käyttäjätunnuksen voi jättää tyhjäksi, mutta vähintään toinen niistä on annettava.

  • Jos käyttäjätunnus puuttuu, käyttäjätunnukseksi laitetaan email.
    • Paitsi jos emaililla löytyy jo jokin tunnus, käyttäjätunnusta ei vaihdeta. Ainoastaan käyttäjän nimi päivittyy.
  • Jos email puuttuu, se jää kantaan nulliksi.
    • Paitsi jos käyttäjätunnus on jo olemassa, emailiin ei kosketa.

TODO: Import-skriptin pitäisi varmaankin sallia emailin jättäminen tyhjäksi vain silloin, kun käyttäjä on jo olemassa. En muista, onko käyttötapaus "pitäisi luoda uusi käyttäjä, jolla ei ole emailia" ollut koskaan tarpeellinen.

ja esimerkkin tällaisia tapauksia.

MIkä tulee käyttäjätunnukseksi jos se puuttuu` Entä sp-osoitteeksiMiten henkilöön saa yhetyden jos sp puuttuu?

21 Apr 21 (edited 21 Apr 21)

Jos salasana sisältää erikoismerkkejä, niin se on syytä kirjoittaa heittomerkkien (siis ei lainausmerkkien) sisään, koska esim. ! on Bashissa varattua syntaksia. Esim. '!kissa'.

Jos haluat jättää salasanan nulliksi, anna tyhjä merkkijono eli --password ''

Esimerkki oikeanlaisesta CSV-tiedostosta:

matti.meikalainen@example.com;Meikäläinen Matti;mameikal
jaska.jokunen@example.com;Jokunen Jaska;
;Esimerkki Erkki;eresim

8.9 Tunnusten yhdistäminen

Komento

./tim run flask user merge ekatunnus tokatunnus

siirtää käyttäjän tokatunnus tiedot tunnuksen ekatunnus alle sekä poistaa pehmeästi tokatunnus-tunnuksen. Operaation jälkeen tokatunnus on siis tyhjä, eli tunnus ei omista yhtään dokumenttia, tehtävän vastausta, jne., eikä sillä voi enää kirjautua TIMiin.

Koska toimintoa ei voi peruuttaa, komento varmistaa ennen yhdistämistä, että yhdistettävillä tunnuksilla on jokin yhteinen asia (esim. toisen tunnuksen käyttäjätunnus vastaa toisen tunnuksen sähköpostiosoitteen alkuosaa).

8.10 Aktiiviset käyttäjät ja dokumentit

TIM-kansiossa ajetaan ./tim pg query ja suoritetaan seuraavat kyselyt tarpeen mukaan:

  • Dokumenttien lukumäärä:

    select count(id) from docentry;
  • Kaikkien käyttäjätunnusten lukumäärä:

    select count(distinct ua.name) from useraccount ua join usergroup ug on ua.name=ug.name;
  • Käyttäjät, jotka omistavat edes yhden dokumentin:

    select count(distinct ua.name) from useraccount ua join usergroup ug on ua.name=ug.name join blockaccess ba on ba.usergroup_id=ug.id join block b on b.id=ba.block_id where ba.type=6 and b.type_id=0 and b.description != 'Bookmarks';
  • Käyttäjät, jotka ovat lukeneet edes jonkun dokumentin:

    select count(distinct usergroup_id) from readparagraph;
  • Kurssitagien määrä (Sisu-integraation kautta tai Aseta kurssiksi -toiminto)

    select count(distinct tag.name) from tag where tag.type='CourseCode';
  • Aktiiviset kurssitagit

    select count(distinct tag.name) from tag where tag.type='CourseCode' and tag.expires is not null;
# usersearch

8.11 Käyttäjän haku (admin)

Kirjoita tuon perään tunnus

Haettava tunnus

Please to interact with this component.

{}

Please to interact with this component.

# useranswers

8.12 Tietyn henkilön kaikki tehtävän vastaukset

https://tim.jyu.fi/getAnswers/docid.taskid/userid

Docid.taskid

Please to interact with this component.

{}

userid

Please to interact with this component.

{}

Please to interact with this component.

9 Seuranta

9.1 Prosessorikuorma

Prosessoreiden käytön seuranta

top

ja sitten painaa 1, niin näkee yksittäiset prosessorit.

9.2 Nettiliikenne

Esimerkiksi komennolla:

watch -n 1 tail -n 50 /extra/tim_logs/timLog.log

9.3 Dockerin logit

Dockereiden logeja voi seurata seuraavasti:

./tim dc logs -t -f tim

./tim dc logs --tail=20 tim

tai

./tim dc logs -t --tail 1000 tim

ja edellistä voi toki putkittaa grepille tai vastaalle, esim:

./tim dc logs -t tim | grep TimDB-dstr

jolloin saa kaikki kantayhteyksien sulkemiset aikoineen joista voi etsiä pitkään kestäviä yhteyksiä.

Tuntui ettei tuo ilman tail oleva valmistu ikinä…

15 Nov 20
./tim dc logs --tail=100 showfile

Paras on ehkä:

 ./tim dc logs -f --tail=10 -t

niin näkee kaikkien konttien tapahtumat follow-moodissa aikaleimoineen

Esimerkiksi jos joku sanoo ettei salasanaa ole lähetetty, sen voi tarkistaa:

 ./tim dc logs -t --tail 10000 tim | grep "Sending temp password"

9.4 Flaskin loki

Flaskin lokista näkee kunkin pyynnön käyttäjätunnuksen. Anonyymit ovat "Anonymous".

watch -n 1 tail -n 50 t /extra/tim_logs/timLog.log

Esimerkiksi miten on käytetty tiettyä dokumenttia tiettyinä tunteina:

sudo tail -n 1270000  /extra/tim_logs/timLog.log | grep -E '2020-03-20 (10|11|12|13)' | grep -E '/((view|teacher|velp|slide|answers|manage)/(kurssit/tie/ohj2/2020k/tentit/valikoe)|read/2/)' > ohj2t-loki-2020-03-20-klo-10-14-utc.txt

tulee esim:

2020-03-20 13:57:43,083 INFO: vesal [xx.xx.xx.xx]: GET /answers/kurssit/tie/ohj2/2020k/tentit/valikoe-20-3-2020?task=t3e&user=xxxxxxx 200 2.31s

tai jos haluaa enemmän, niin esim tietyn dokun kaikki käyttö joltakin käyttäjältä:

tail -n 370000  /extra/tim_logs/timLog.log |  grep -E '(kurssit/tie/ohj2/2020k/tentit/valikoe)|(225721)' | grep vesal

10 Dockerin kaatuessa

Ainakin csPlugin kontti on jumiintunnut joskus niin ettei systeemiä meinaa saada uudelleen käyntiin.

Aluksi oire voi olla esim että csPlugin konttia ei voi poistaa ja sen uudelleenkäynnistysyritys johtaa vain ikuiseen odotukseen. Sen jälkeen edes

docker ps

ei toimi. Tähän auttaa:

sudo restart docker

Jos tämänkään jälkeen ei konteja saa käyntiin:

/opt/tim$ ./tim restart

niin sitten (~/cs on sama kuin /opt/tim/timApp/modules/csplugin tim-koneessa)

vesal@timbeta:~/cs$ ./startPlugins.sh i p
--name csPlugin --net=timnet -p 56000:5000 -v /lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:ro -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/bin/docker -v /opt/cs:/cs/:ro -v /opt/cs/images/cs:/csstatic/ -v /tmp/uhome:/tmp/ -w /cs cs3 /bin/bash
docker: Error response from daemon: Conflict. The name "/csPlugin" is already in use by container 3e09c17644c3bd657f2ec1a6e19a490c5cd85357024b758b41509a5d3db55653. You have to remove (or rename) that container to be able to reuse that name..
See 'docker run --help'.
vesal@timbeta:~/cs$ docker rm 3e09
Failed to remove container (3e09): Error response from daemon: Driver aufs failed to remove root filesystem 3e09c17644c3bd657f2ec1a6e19a490c5cd85357024b758b41509a5d3db55653: rename /var/lib/docker/aufs/mnt/355e6291dba632bdb1754d9185af383ce21d672d0b8a8e0616982b5c4f974ff6 /var/lib/docker/aufs/mnt/355e6291dba632bdb1754d9185af383ce21d672d0b8a8e0616982b5c4f974ff6-removing: device or resource busy
vesal@timbeta:~/cs$ sudo umount /var/lib/docker/aufs/mnt/355e6291dba632bdb1754d9185af383ce21d672d0b8a8e0616982b5c4f974ff6
vesal@timbeta:~/cs$ docker rm 3e09
3e09
vesal@timbeta:~/cs$ ./startPlugins.sh i p
--name csPlugin --net=timnet -p 56000:5000 -v /lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:ro -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/bin/docker -v /opt/cs:/cs/:ro -v /opt/cs/images/cs:/csstatic/

ei ole restart-komentoa?

07 Sep 20

Eikös tuo dockerin uudelleenkäynnistys pitäisi olla

sudo systemctl restart docker

tai

sudo service docker restart

CentOS käyttää Systemd:tä ja jos sitä ajaa servicenä niin se tarvitsee vielä ylimääräisen komennon.

20 Mar 21

Manuaalinen csplugin-kontin käynistys:

docker exec -it tim_csplugin_1 bash ./startAll.sh

11 Dokumentin korjaaminen hajotessa

Yleisin dokumentin hajoamisen syy (siten että view ei toimi eikä sitä ei saa ehjäksi selainliittymästä) on se, että dokumenttiin syystä tai toisesta ilmestyy duplikaatti-id. Tämän ei pitäisi olla mahdollista ja koska useassa paikassa id:t oletetaan uniikeiksi dokumentin sisällä, ongelmia seuraa.

Jos dokumentti hajoaa:

  1. Selvitä dokumentin id. Jos dokumentin manage-sivu toimii, voit katsoa sen sieltä (kohdasta Translations and copies) tai myös hakemistolistauksen manage-linkistä.

  2. Selvitä dokumentin viimeisin versionumero. Jos manage toimii, se näkyy historialistauksen ensimmäisen rivin ensimmäisestä linkistä. Esim. linkissä https://tim.jyu.fi/download/128875/119/0 oleva versio on (119, 0).

  3. Mene tuotantokoneella hakemistoon

    /opt/tim/timApp/tim_files/docs/<doc_id>/<ver_major>

    esim. /opt/tim/timApp/tim_files/docs/128875/119

  4. Muokkaa kappalelistatiedostoa komennolla

    `sudo nano <ver_minor>`, esim. `sudo nano 0`

    ja poista duplikaatti-id-rivi (Nanossa Ctrl+K) ja tallenna.

12 Dokumentin välimuistin tyhjennys

Välimuistin tyhjennys onnistuu laittamalla nocache=true parametri URLiin:

https://tim.jyu.fi/view/tim/TIMin-kehitys/Admin?nocache=true

13 Dokumenttien poistaminen pysyvästi

Jos käyttäjä itse poistaa Manage-sivun kautta dokumentin/kansion, sitä ei oikeasti poisteta, vaan se siirretään Roskakori-kansioon.

Dokumentteja voi poistaa pysyvästi CLI-komennolla

./tim run flask item delete --item-id [ID-numero] --no-dry-run

jossa [ID-numero] on dokumentin tai kansion ID. Dokumenttien ID-numeron näkee Manage-sivulta kohdasta Translations. Kansioiden ID-numeron saa näkyviin painamalla kansion yläkansiossa "Id"-saraketta. Ne voi katsoa myös kannasta esim. seuraavasti:

./tim pg query

...syötä postgresql tunnukset

SELECT * FROM Folder WHERE location LIKE 'KANSION POLKU';

Oletuksena (ilman argumenttia --no-dry-run) delete-komento ajetaan kuivaharjoitteluna, jolloin tulostetaan poistettavat dokumentit ja kansiot ilman että mitään vielä poistetaan levyltä.

Kun komento ajetaan argumentilla --no-dry-drun, tapahtuu seuraavaa:

  1. Dokumentti (ja sen käännökset), kansio nimetään uudelleen muotoon $deleted_[ID-numero]
  2. Dokumentista/käännöksistä/kansioista poistetaan kaikki oikeudet, ja niiden omistajaksi asetetaan ylläpitäjien ryhmä 'Administrators'.
  3. Dokumentin/käännösten/kansioiden aliakset poistetaan TIMin tietokannasta
  4. Dokumentti/käännökset/kansio siirretään TIMin Roskakoriin
  5. Dokumentin ja sen käännösten tiedostot tuhotaan palvelimen levyltä:
    • dokumentin/käännösten lohkot sijainnista /tim/timApp/tim_files/pars
    • dokumentin/käännösten versiohistoria sijainnista /tim/timApp/tim_files/docs
  6. Jos poistettava on kansio, sen sisältämät dokumentit ja kansiot poistetaan kuten yllä.
  7. Lopuksi tulostetaan lista poistetuista dokumenteista ja kansioista.

Komennon suorittaminen ei poista dokumentteja/kansioita varmuuskopioista.

14 Levytila

  • levytilan katsominen

      df -h

    tai

      sudo du 2> /dev/null | sort -n
  • allokoimattoman levytilan katsominen

      sudo vgs
  • eniten vievien tiedostojen listaaminen suurimmasta pienimpään tietyn hakemiston osalta

      find /opt/tim/timApp/tim_files/blocks/uploads -type f -exec du -h {} + | sort -r -h | less
  • levytilan lisääminen (huom Filesystem nimi parametriksi)

      sudo lvextend -r -L +1G /dev/timstack/docker

Mihin tila menee, voi tutkia komennolla:

sudo ncdu -x

15 Testitunnuksia

Kirjautumistiedot             | tunnus oikeuksien antamiseen
------------------------------|--------                              
test1@example.com test1pass   |testuser1
test2@example.com test2pass   |testuser2
test3@example.com test3pass   |testuser3

16 Haku dokumenteista

Esim. missä kappaleissa esiintyy expl: {'

cd /opt/tim/timApp/tim_files/pars
grep -l -r "expl: {'" .

Huom. TIMin oma hakutoiminto toimii nykyään myös.

16.1 Monipuolisempi haku komentorivillä

Esim.

./tim run python3 timApp/admin/search_in_documents.py --progress --term cssyntaksi --folder kurssit/tie --docs-only

17 Dokumenttien massamuokkaus

  • tags: etsi/korvaa

Esim. miten muutetaan suora linkki makroksi tietyssä hakemistossa:

./tim run python3 admin/replace_in_documents.py --folder 'kurssit/tie/ohj2/2018k/demot' --term 'https://trac.cc.jyu.fi/projects/ohj1/wiki/ville' --to '%%VILLE%%'

Komento ajetaan oletuksena kuivana, eli se ei tee mitään. Lisää --no-dry-run, jos tuloste näyttää järkevältä.

Toinen esimerkki:

./tim run python3 admin/replace_in_documents.py --regex --term '#([^\n]*)(2018|2017|2016|2015)([^\n]*)' --to '#\1%%vuosip%%\3' --folder kurssit/tie/ohj1/2018s/luennot

Kolmas esimerkki (haetaan ja muutetaan parametri kaikista lohkoista):

./tim run python3 admin/replace_in_documents.py --regex --term '.*' --folder 'kurssit/tie/ohj1/avoin23/luennot' --filter_attr 'rd=438580' --add-attr 'rd=559479'

Skriptillä on muitakin parametreja, kutsu skripti suoraan nähdäksesi ne kaikki:

$: tim run python3 admin/replace_in_documents.py
usage: replace_in_documents.py [-h] (--doc DOC | --folder FOLDER) [--dry-run | --no-dry-run] [--progress]
                               [--url-path URLPATH] --term TERM [--only-first ONLYFIRST] [--format FORMAT] [--regex]
                               [--filter_attr FILTER_ATTR] (--to TO | --add-attr ADD_ATTR)
replace_in_documents.py: error: the following arguments are required: --term

18 Vastauksien poisto

Lisää TIMin URLiin parametri showAdmin=true, jolloin vastausselaimen yhteydessä näkyy roskakoripainike, jolla vastauksen voi poistaa.

Oiskos tää sellainen toiminto jolle olisi oma ryhmä ketkä saa tehdä. Esim niissä matikan PDF-jutuissa voisivat silloin itsekin poistaa. Tosin ehkä silloin pitåäisi olla käli palauttamiselle…

03 Nov 20

Tämäkään ei täysin poista vastausta, vaan vain poistaa vastauksesta käyttäjäliitokset, jolloin se ei näy TIMissä enää.

Vastauksen poisto lokittuu tarkasti, joten sen pystyy tarvittaessa käsin palauttamaan.

Myös kunkin yksittäisen collaboratorin pystyy poistamaan, jos vastauksessa sellaisia on useampi kuin yksi.

18.1 Rikkinäisten vastausten poisto

Joskus voi käydä niin, että dokumenttia muokatessa pluginin tyyppi on vaihtunut jossakin vaiheessa ja silloin vanhat vastaukset saattavat aiheuttavat virheen.

Koska ainakin csPlugin sattuu olemaan ilmeisen tolerantti vääränmuotoisille vastauksille, niin tällaiset vastaukset saa pois luomalla johonkin dokumenttiin pluginin

#- {#123456.tehtava plugin="csPlugin"}
type: cs

missä 123456.tehtava on dokumentin id ja tehtävän nimi. Sitten voit mennä teacher-näkymään showAdmin=true-parametrilla ja poistaa halutut vastaukset. Plugin heittää virheilmoituksia, mutta vastaukset saa silti poistettua.

18.2 Vastauksien massapoisto

Komentorivillä esim. komento

./tim run flask answer clear kurssit/tie/ohj1/2020s/tenttiilmo -t vakavuus -t aikaleima -t ohuoneurlto

poistaa dokumentin kurssit/tie/ohj1/2020s/tenttiilmo tehtävistä vakavuus, aikaleima ja ohuoneurlto kaikki vastaukset.

Komento ajetaan oletuksena kuivana (näyttää vain poistettavien rivien määrän), eli lisättävä --no-dry-run perään, kun halutaan oikeasti poistaa.

Vastaavasti on komento clear-all, joka poistaa dokumentista kaikki vastaukset.

19 Kannan varmuuskopiointi

19.1 PostgreSQL-kanta

Aja ./tim pg backup <hakemisto>. Hakemiston on oltava olemassa.

19.2 Kannan varmuuskopiointi ajastetusti

1.19.2.1 crontab

Jokatuntisen automaattisen varmuuskopion saa luomalla hakemiston <TIMin juuri>/pg_backup ja lisäämällä crontabiin (sudo crontab -e):

MAILTO="wuff-reports@tim.jyu.fi"
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/root/bin

0 * * * * /opt/tim/tim pg backup-rotate

1.19.2.2 systemd

JYU TIM -instanssissa crontabien sijaan ajetaan systemd-ajastin seuraavilla konfiguraatioilla:

tim-postgre-backup.service:

[Unit]
Description=TIM PostgreSQL backup
Wants=tim-postgre-backup.timer

[Service]
Type=oneshot
WorkingDirectory=/opt/tim
ExecStart=/bin/bash tim pg backup-rotate
User=root

[Install]
WantedBy=multi-user.target

tim-postgre-backup.timer:

[Unit]
Description=Run TIM PostgreSQL backup
Requires=tim-postgre-backup.service

[Timer]
Unit=tim-postgre-backup.service
OnCalendar=hourly

[Install]
WantedBy=timers.target

20 Työkaluja PostgreSQL-tietokannan käsittelyyn

Tässä SQLAlchemyssä täytyy toistaiseksi itse antaa kannanpäivityskomento:

./tim run flask db upgrade

tuo siis git pullin jälkeen.

Korvaa seuraavassa tim3 oman lokaalin tim-koneesi nimellä tai ip:llä.

Katso myös PyCharm (tämä riittää käytännössä kehitystyöhön).

  • SQL Workbench
    • tarvitsee SQL...jar driverin
    • antaa mukavasti katsella tauluja
    • yhteys:
      • URL: jdbc:postgresql://tim3:5432/tim
      • Username: postgres
  • PgAdmin 4
    • yhteys:
      • Host name: tim3
      • Port: 5432
      • Maintenance database: postgres
      • User name: postgres
      • Password: [tyhjä]
    • ei suoraa taulujen käsittelyä
    • asentaa klikkaamalla java-driverin, jota voi käyttää edellisessä hyväkseen, jos asentaa molemmat

20.1 PSQL

PSQL-konsolin saa käyntiin komennolla:

./tim pg query

Sitten esim taulujen nimet:

 SELECT * FROM pg_catalog.pg_tables where tablename like '%users%';

ja taulun kuvaus

\d+ useraccount

Toimii myös:

 \d+ user*

Tietyn taulun sisältö:

 select * from useraccount where name like '%vesal%';

Tietyn vastaajan tallennukset tiettyyn tehtävään:

select * from answer where id in (select answer_id from useranswer where user_id in (select id from useraccount where name='USERNAME')) and task_id = 'DOCID.TASKNAME';

20.2 Uusien SQL-skriptien lisääminen TIM CLIhin

Yleisesti käytetyt SQL-skriptit kannattaa muttaa TIM CLI -komennnoiksi seuraavasti:

  1. Tee uusi .py-tiedosto polkuun cli/commands/pg. Tiedoston nimi on lopullisen komennon nimi.
  2. Kopioi tiedostoon pohjaksi esim. activity.py (löytyy samasta kansiosta)
  3. Muokkaa run_psql-kutsun kohdalla oleva skripti. PyCharm osaa värittää SQL:n automaattisesti tässä
  4. Lisää lyhyt kuvaus info-muuttujassa olevaan help-attribuuttiin

Voit sen jälkeen kutsua skripti seuraavasti (esim. jos skriptin nimi on skripti.py):

./tim pg skripti

Esim. num.sh antaa yhteyksien määrän molemmille kannoille kerralla.

20.3 Kannan yhteyksien listaaminen

./tim pg activity

20.4 Konfiguraation muuttaminen

Komennolla ./tim pg set-conf on mahdollista muuttaa PostgreSQL-instanssin konfiguraatiotiedostoa; tosin tällä skriptillä tehdyt muutokset eivät ole pysyviä, eli ./tim update:n jälkeen asetukset palautuvat takaisin.

Jos esimerkiksi halutaan nostaa pääkannan yhteyksien maksimilukumäärää, niin voidaan sanoa:

Puuttuu: sed_changes.txt

13 Mar 21
./tim pg set-conf max_connections 120

jolloin tulostuu tyyliin:

Lines changed in postgresql.conf:
max_connections = 120
Restarting postgresql-timlocal...
postgresql-timlocal

Yhteyksien, workerien yms. määrää muutetaan timApp/defaultconfig.py -tiedostossa.

20.5 Konfiguraation katsominen

./tim pg get-conf max_connections

20.6 Tietojen päivitys kantaan

Käytä aina transaktioita päivittäessäsi kannan tietoja. Voit myös katsoa, mitä rivejä transaktiossa on päivitetty ennen committia:

begin;
-- update/insert-lauseita...
select * from taulunnimi where xmin::text = (txid_current() % (2^32)::bigint)::text;
-- jos järkevä tulos, niin:
commit;

Poistettuja rivejä ei tällä tyylillä näe.

Jos tulee vahingossa suoritettua virheellinen päivitys, niin suorita:

abort;

20.7 Kannan korjaus ongelmatilanteissa

5.9.2017 kanta hajosi, jolloin PostgreSQL-kontin lokiin ilmestyi seuraavaa:

LOG:  invalid resource manager ID 152 at 0/ED36CF98
LOG:  invalid primary checkpoint record
LOG:  invalid resource manager ID in secondary checkpoint record
PANIC:  could not locate a valid checkpoint record
LOG:  startup process (PID 24) was terminated by signal 6: Aborted
LOG:  aborting startup due to startup process failure

Tällöin kannan sai kuntoon pg_resetwal-komennolla:

./tim dc run --user postgres postgresql /bin/bash
pg_resetwal /var/lib/postgresql/data/
exit
./tim pg backup pg_backup
./tim pg restore pg_backup/<dump-tiedosto>

21 Lokitiedostot

21.1 Pakkaus

XZ_OPT=-9 tar cJf loki.tar.xz loki.log

21.2 Purku tarvittaessa

tar xf archive.tar.xz

21.3 Haku lokeista

cd /extra/tim_logs
grep hakusana timLog.log

Esimerkkejä:

Answers-sivun katsomiset:

grep /answers/kurssit/tie/ohj1/2018s/demot/demo9 timLog.log

Milloin annettu oikeuksia:

 grep '/permissions/add/147056' timLog.log

21.4 Ajastetusti ajettavien ohjelminen logi

Esim:

./tim dc logs --tail=3000 celery | grep 639109

missä id on sen dokun id, josta ajastettu runneri on laitettu käyntiin.

Jos on tarve testata funktion toimintaa celeryn kautta ajettuna, sen voi suorittaa manuaalisesti:

./tim run celery -A timApp.tim_celery.celery shell
import sys
import logging
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
logging.getLogger().setLevel(logging.INFO)

run_user_function(käynnistäjän userid (int), dokumentti.funktionnimi (str), {})

22 proxy-polun sallittujen domainien muuttaminen

https://tim.jyu.fi/getproxy -polku sallitaan vain tietyille domainille. Domainien konfigurointi tapahtuu muokkaamalla prodconfig.py palvelimella:

  1. Mene SSH:lla TIM-koneeseen

  2. Mene TIM-kansioon

    cd /opt/tim
  3. Avaa prodconfig nanolla:

    nano timApp/prodconfig.py
  4. Muokkaa PROXY_WHITELIST ja/tai PROXY_WHITELIST_NO_LOGIN

    • PROXY_WHITELIST - domainit, joista saa hakea sisältöä proxylla
    • PROXY_WHITELIST_NO_LOGIN - domainit, joista saa hakea sisältö ilman sisäänkirjautumista TIMiin (HUOM: saman domainin oltava myös PROXY_WHITELIST-listassa)
  5. Tallenna muutokset ja virkistä TIM-palvelin

    ./tim update back --yes

23 static kuvien sijainti

Esimerkiksi kuva:

https://tim.jyu.fi/static/ohj1/images/forsilmukka-junaradat.png

sijaitsee Linuxin polussa:

/opt/tim/timApp/static/images

Vastaavasti csPluginien tuottamat kuvat tyyliin:

https://tim.jyu.fi/csstatic/cs/70ad9807-e94a-4163-84b2-0409087d27fd.png

sijaitsee

/opt/cs/images/cs/...

24 Dokumentin vastausten vienti toiseen koneeseen

  1. Avaa PG-yhteys: ./tim pg query

  2. Anna komennot (korvaa 117369 halutulla dokun id:llä):

    \copy (select * from answer where task_id like '117369.%') to /backup/answer.csv
    \copy (select * from useranswer where answer_id in (select id from answer where task_id like '117369.%')) to /backup/useranswer.csv
    \copy (select id, 'someuser' || id, 'Some user ' || id, 'someuser' || id || '@example.com' from useraccount where id in (select user_id from useranswer where answer_id in (select id from answer where task_id like '117369.%'))) to /backup/useraccount.csv
    \copy (select * from usergroupmember where user_id in (select user_id from useranswer where answer_id in (select id from answer where task_id like '117369.%'))) to /backup/usergroupmember.csv
    \copy (select id, 'someuser' || id from usergroup where id in (select last_points_modifier from answer where task_id like '117369.%' and last_points_modifier is not null UNION select usergroup_id from usergroupmember where user_id in (select user_id from useranswer where answer_id in (select id from answer where task_id like '117369.%')))) to /backup/usergroup.csv
  1. Lopeta PG-yhteys (\q). CSV-tiedostot ovat nyt hakemistossa pg_backup. Siirrä ne vastaavaan hakemistoon kohdekoneella.

  2. Luo kohdekoneella dokumentti, johon vastaukset halutaan ja katso sen id (esim. selaimen konsolissa docId).

  3. Anna kohdekoneella PG-yhteydellä komennot (korvaa viimeisessä id:t halutuilla):

    \copy answer from /backup/answer.csv
    \copy useraccount (id, name, real_name, email) from /backup/useraccount.csv
    \copy usergroup (id, name) from /backup/usergroup.csv
    \copy usergroupmember from /backup/usergroupmember.csv
    \copy useranswer from /backup/useranswer.csv
    update answer set task_id=replace(task_id, '117369.', '10.') where task_id like '117369.%';
  1. Jos tulee virheitä edellisessä kohdassa, esim.

    • duplicate key value violates unique constraint "usergroup_pkey"
    • insert or update on table "usergroupmember" violates foreign key constraint "usergroupmember_user_id_fkey"

    niin poista harmia aiheuttavat rivit vastaavasta tiedostosta. COPY lisää joko kaikki rivit onnistuneesti tai ei mitään.

  1. Mikäli TIMin ajon aikana tulee virhe tyyliin

    Personal usergroup for user someuser1153 was not found!

    niin suorita: insert into usergroup (name) values ('someuser1153');

# uploadpoisto

25 Käyttäjän lataaman tiedoston poisto

Oletetaan, että käyttäjä on ladannut tiedoston xxx.pdf.

  1. Mene /opt/tim/timApp/tim_files/blocks/uploads

  2. find . | grep xxx.pdf

  3. poista tiedosto kopioimalla sen päälle dummyupload.pdf tyyliin

     sudo cp ./blocks/files/158365/dummyupload.pdf ./blocks/uploads/12345/image2/xxxxx/1/xxx.pdf 
  4. jos halutaan oikeasti poistaa, niin tietokannassa pitäisi tehdä jotakin, mitä???

26 Kurssikategorialistan päivitys

Käyttäjät voivat ehdottaa kurssikategorioita (joita käytetään kurssien tageissa ja saatavilla olevien kurssien listassa) joko sähköpostilla tai seuraavalla sivulla:

Lista tuetuista kurssikategorioiden nimistä:

Uudet kategoriat lisätään course_subjects-listaan mielellään aakkosjärjestyksessä. Lisätty kategoria tulee heti näkyviin käyttäjille Set as a course -dialogissa.

27 TeX PDF cache

Tulostetut dokumentit menevät PDF-cacheen, josta se näytetään, jolloin dokumenttiin ole tullut muutoksia.

Cache on docker-volume tim-palvelussa eli menee

./tim run bash

ja siellä

cd /cache/printed_documents

28 Ajastetut funktiot

Tällä hetkellä ajastettujen funktioiden käyttöliittymä on rajoitettu. Alla on jotain toimintoja, joita voi tehdä TIMin flask shellista (./tim run flask shell):

28.1 Seuraavan ajamishetken asettaminen

Ajatus: asetetaan viimeisimmän ajoajan PeriodicTask.last_run_at haluttuun aikaan. Silloin funktio ajetaan seuraavan kerran ajankohtana PeriodicTask.last_run_at + t.schedule.

from timApp.timdb.sqa import run_sql
from sqlalchemy import select
from datetime import datetime

t = run_sql(select(PeriodicTask).where(PeriodicTask.name.contains("DOCID.TASKID"))).scalar()
t.last_run_at = datetime.fromisoformat("2024-09-20T09:00:00")
db.session.commit()

29 Haka-sertifikaatin uusiminen

Varmuuskopioi vanhat sp.{crt,key} kansiosta timApp/auth/saml/prod/certs jonnekin.

Mene tyhjään hakemistoon ja generoi uusi sertifikaatti komennolla:

openssl req -new -sha256 -x509 -days 3652 -nodes -out sp.crt -keyout sp.key

Kopioi sertifikaatin sp.crt sisältö ilman BEGIN/END rivejä leikepöydälle ja lisää se resurssirekisteriin. Älä poista vanhaa sertifikaattia.

Hyväksy resurssirekisterissä muutokset ja odottele, kunnes muutokset hyväksytään ja Hakan metadata päivittyy (siitä pitäisi tulla sähköposti) ja odottele siitä vielä 24h.

Odotuksen jälkeen ota uusi sertifikaatti käyttöön, eli laita sp.crt ja sp.key kansioon timApp/auth/saml/prod/new/certs. Kopioi myös kansioon timApp/auth/saml/prod/new ylemmän kansion config.py.

Poista vanha sertifikaatti resurssirekisteristä, odota metadatapäivitystä ja siitä vielä 24h.

Kopioi uuden sertifikaatin tiedostot vanhojen päälle.

Poista lopuksi new-hakemisto.

Restarttaa TIM.

30 Sisun suoritusrajapintasertifikaatin uusiminen

openssl req -nodes -newkey rsa:2048 -keyout cert.key -out cert.crt -x509 -days 3652 -subj "/CN=tim.jyu.fi" -addext "subjectAltName = URI:urn:code:custom:jyu-university-root-id:oppimisymparistot:tim"
cat cert.crt cert.key > sisu.pem
# Anna sertifikaatti (cert.crt) Sisu-rajapinnan ylläpidolle ja odota, että se tulee käyttöön. Sitten:
cp sisu.pem <TIMin juuri>/certs/

31 Varautuminen uuteen Haka-metadatavarmenteeseen

Ennen varmenteen vaihtoa:

  1. Hae uusi varmenne. Uusi varmenne yleensä julkaistaan osoitteessa https://wiki.eduuni.fi/display/CSCHAKA/Metadata.

    Varmennetiedosto on yleensä ollut muotoa haka-sign-vX.pem, jossa X on varmenteen numero. Varmista wikistä, milloin uusi varmenne astuu voimaan.

  2. Mene TIM-koneelle ja aja

    curl 'varmenteen_osoite' -o /opt/tim/timApp/auth/saml/prod/certs/metadata_new.crt

    missä varmenteen_osoite on uuden varmenteen osoite

Kokeile, että sisäänkirjautuminen HAKA:lla onnistuu edelleen.

Seuraavaksi odotetaan metadatan julkaisua uudella varmenteella. Varmennetta ei kannata vielä vaihtaa julkaisupäivänä, koska TIM cachettaa metadatan 24h.

Vanha varmenne voi poistaa, kun TIM-lokeissa näkyy varoitusviestejä mallia

SAML (new_cert=False, new_meta=False): Could not validate SAML metadata:

Vanhan varmenteen poisto:

  1. Mene TIM-koneelle ja aja

    mv /opt/tim/timApp/auth/saml/prod/metadata_new.crt /opt/tim/timApp/auth/saml/prod/metadata_new.crt
  2. Käynnistä TIM-palvelin uudelleen

    ./tim update back --yes
  3. Varmista, että HAKA-kirjautuminen onnistuu

  4. Poista lopuksi /opt/tim/timApp/auth/saml/prod/metadata_new.crt

# cpufreq

32 Koneen kellotaajuus

JYU-TIM:ssa on /root/bin/cpu-adjust-skripti, jolla CPUn toimintaa voi säätää. sudo /root/bin/cpu-adjust --help antaa aputekstin, jossa eri optiot selitetään

Oletuksella skripti ajetaan TIM-koneen käynnistyksen yhteydessä (/etc/rc.d/rc.local) --performance-asetuksella.

33 TIM-instanssin datan siirto

Tietojen siirto toiseen koneeseen

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.