CI/CD in Github Actions do thionscadal Flasc+Uingearach

CI/CD in Github Actions do thionscadal Flasc+Uingearach
San Airteagal seo, roinnfidh mé mo thaithí ar CI/CD a bhunú ag baint úsáide as Painéal Rialaithe Plesk agus Gníomhartha Github. Sa lá atá inniu beimid ag foghlaim conas tionscadal simplí a imscaradh leis an ainm neamhchasta "Helloworld". Tá sé scríofa i gcreat Flask Python, le hoibrithe Soilire agus aghaidh Angular 8.

Naisc chuig stórtha: cúl, ceann tosaigh.

Sa chéad chuid den alt, féachfaimid ar ár dtionscadal agus a chuid páirteanna. Sa dara ceann, déanfaimid amach conas Plesk a shocrú agus na síntí agus na comhpháirteanna riachtanacha a shuiteáil (DB, RabbitMQ, Redis, Docker, etc.).

Sa tríú cuid, déanfaimid amach ar deireadh conas píblíne a bhunú chun ár dtionscadal a imscaradh chuig freastalaí i dtimpeallacht dev agus prod. Agus ansin beidh muid ag seoladh an suíomh ar an bhfreastalaí.

Agus tá, rinne mé dearmad mé féin a thabhairt isteach. Oleg Borzov is ainm dom, is forbróir lánstack mé san fhoireann CRM do bhainisteoirí morgáiste ag Domclick.

Forbhreathnú an Tionscadail

Ar dtús, déanaimis féachaint ar dhá stór tionscadail - inneall agus tosaigh - agus téigh thar an gcód.

Inneall: Fleascán+Soilire

Maidir leis an gcuid cúil, ghlac mé bunch a bhfuil an-tóir air i measc forbróirí Python: creat Flask (don API) agus Soilire (don scuaine tasc). Úsáidtear SQLAchemy mar ORM. Úsáidtear Alembic le haghaidh imirce. Le haghaidh bailíochtú JSON sna hanla - Marshmallow.

В stórtha tá comhad Readme.md ann le cur síos mionsonraithe ar an struchtúr agus na treoracha chun an tionscadal a rith.

Web Part API simplí go leor, comhdhéanta de 6 pinn:

  • /ping - infhaighteacht a sheiceáil;
  • láimhseálann le haghaidh clárúcháin, údarú, dí-údarú agus a fháil úsáideoir údaraithe;
  • láimhseáil ríomhphoist a chuireann tasc sa scuaine Soilire.

Cuid soilire níos éasca fós, níl ach fadhb amháin ann send_mail_task.

San fhillteán /conf tá dhá fhofhillteán ann:

  • docker le dhá Dockerfile (base.dockerfile a thógáil íomhá bonn is annamh a athraíonn agus Dockerfile le haghaidh príomhthionóil);
  • .env_files - le comhaid le hathróga timpeallachta do thimpeallachtaí éagsúla.

Tá ceithre chomhad cumadóireachta docker ag bun an tionscadail:

  • docker-compose.local.db.yml bunachar sonraí áitiúil a chruthú lena fhorbairt;
  • docker-compose.local.workers.yml le haghaidh ardú áitiúil an oibrí, bunachar sonraí, Redis agus RabbitMQ;
  • docker-compose.test.yml tástálacha a rith le linn imscaradh;
  • docker-compose.yml le haghaidh imscaradh.

Agus an fillteán deireanach a bhfuil suim againn ann - .ci-cd. Tá scripteanna sliogáin ann le himscaradh:

  • deploy.sh — imirce agus imscaradh a sheoladh. Ritheann sé ar an bhfreastalaí tar éis tástálacha a thógáil agus a rith i nGníomhartha Github;
  • rollback.sh - coimeádáin a thabhairt ar ais go dtí an leagan roimhe seo den tionól;
  • curl_tg.sh - fógraí imscartha a sheoladh chuig Telegram.

Aghaidh ar Angular

Stór le tosaigh i bhfad níos simplí ná ceann Beck. Tá trí leathanach sa tosaigh:

  • Príomhleathanach le foirm chun ríomhphost a sheoladh agus cnaipe scoir.
  • Leathanach logáil isteach.
  • Leathanach clárúcháin.

Tá cuma ascetic ar an bpríomhleathanach:

CI/CD in Github Actions do thionscadal Flasc+Uingearach
Tá dhá chomhad ag an fhréamh Dockerfile и docker-compose.yml, chomh maith leis an bhfillteán eolach .ci-cd le beagán níos lú scripteanna ná mar atá sa stór cúil (scripteanna bainte le haghaidh trialacha a rith).

Tús a chur le tionscadal i Plesk

Tosaímid le Plesk a bhunú agus síntiús a chruthú dár suíomh.

Suiteáil síntí

I Plesk, tá ceithre síneadh ag teastáil uainn:

  • Docker stádas coimeádán a bhainistiú agus a thaispeáint go radhairc i bpainéal riaracháin Plesk;
  • Git chun an chéim imlonnaithe ar an bhfreastalaí a chumrú;
  • Let's Encrypt chun deimhnithe TLS saor in aisce a ghiniúint (agus a athnuachan go huathoibríoch);
  • Firewall chun scagadh tráchta ag teacht isteach a chumrú.

Is féidir leat iad a shuiteáil tríd an bpainéal riaracháin Plesk sa rannán Eisínteachtaí:

CI/CD in Github Actions do thionscadal Flasc+Uingearach
Ní mheasfaimid na socruithe mionsonraithe le haghaidh síntí, déanfaidh na socruithe réamhshocraithe chun ár gcríoch taispeána.

Cruthaigh síntiús agus suíomh

Next, ní mór dúinn a chruthú síntiús le haghaidh ár suíomh gréasáin helloworld.ru agus cuir an subdomain dev.helloworld.ru ann.

  1. Cruthaigh síntiús don fhearann ​​helloworld.ru agus sonraigh an focal faire logála isteach don úsáideoir córais:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach
    Seiceáil an bosca ag bun an leathanaigh Déan an fearann ​​a dhaingniú le Let's Encryptmás mian linn HTTPS a bhunú don suíomh:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  2. Ansin, sa síntiús seo, cruthaigh subdomain dev.helloworld.ru (ar féidir leat teastas TLS saor in aisce a eisiúint ina leith):

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

Suiteáil Comhpháirteanna Freastalaí

Tá freastalaí againn le OS Debian Stretch 9.12 agus painéal rialaithe suiteáilte Plesk Obsidian 18.0.27.

Ní mór dúinn a shuiteáil agus a chumrú le haghaidh ár dtionscadal:

  • PostgreSQL (inár gcás, beidh freastalaí amháin ann le dhá bhunachar sonraí le haghaidh timpeallachtaí dev agus prod).
  • RabbitMQ (mar an gcéanna, an cás céanna le vhosts éagsúla le haghaidh timpeallachtaí).
  • Dhá chás Redis (do thimpeallachtaí dev agus prod).
  • Clárlann Docker (le haghaidh stóráil áitiúil ar íomhánna Docker tógtha).
  • Chomhéadain don chlár Docker.

PostgreSQL

Tagann Plesk le PostgreSQL DBMS cheana féin, ach níl an leagan is déanaí ann (agus Plesk Obsidian á scríobh seo tacaithe Leaganacha Postgres 8.4–10.8). Teastaíonn uainn an leagan is déanaí dár bhfeidhmchlár (12.3 tráth scríofa na hoibre seo), mar sin cuirfimid é de láimh.

Tá go leor treoracha mionsonraithe ann chun Postgres ar Debian a shuiteáil ar an ngréasán (mar shampla), mar sin ní dhéanfaidh mé cur síos mion orthu, ní thabharfaidh mé ach na horduithe:

wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Ag cur san áireamh go bhfuil socruithe réamhshocraithe sách measartha ag PostgreSQL, is gá an chumraíocht a cheartú. Cabhróidh sé seo linn áireamhán: ní mór duit tiomáint i bparaiméadar do fhreastalaí agus na socruithe sa chomhad a athsholáthar /etc/postgresql/12/main/postgresql.confdóibh siúd a thairgtear. Ba chóir a thabhairt faoi deara anseo nach piléar draíochta iad áireamháin den sórt sin, agus ba cheart an bonn a thiúnadh ar bhealach níos cruinne, bunaithe ar do chrua-earraí, feidhmchlár agus castacht na gceisteanna. Ach is leor é seo chun tús a chur leis.

Chomh maith leis na socruithe atá molta ag an áireamhán, táimid ag athrú freisin i postgresql.confan calafort réamhshocraithe 5432 go ceann eile (inár sampla - 53983).

Tar éis duit an comhad cumraíochta a athrú, atosaigh postgresql-server leis an ordú:

service postgresql restart

Tá PostgreSQL suiteáilte agus cumraithe againn. Anois cruthaimis bunachar sonraí, úsáideoirí le haghaidh timpeallachtaí forbartha agus táirgíochta, agus tabhair cearta d’úsáideoirí an bunachar sonraí a bhainistiú:

$ su - postgres
postgres:~$ create database hw_dev_db_name;
CREATE DATABASE
postgres:~$ create user hw_dev_db_user with password 'hw_dev_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_dev_db_name to hw_dev_db_user;
GRANT
postgres:~$ create database hw_prod_db_name;
CREATE DATABASE
postgres:~$ create user hw_prod_db_user with password 'hw_prod_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_prod_db_name to hw_prod_db_user;
GRANT

Coinín MQ

A ligean ar bogadh ar aghaidh go dtí suiteáil RabbitMQ, bróicéir teachtaireachtaí do Soilire. Tá sé simplí go leor é a shuiteáil ar Debian:

wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i erlang-solutions_1.0_all.deb

sudo apt-get update
sudo apt-get install erlang erlang-nox

sudo add-apt-repository 'deb http://www.rabbitmq.com/debian/ testing main'
wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -

sudo apt-get update
sudo apt-get install rabbitmq-server

Tar éis a shuiteáil, ní mór dúinn a chruthú vostas, úsáideoirí agus deonaigh na cearta riachtanacha:

sudo rabbitmqctl add_user hw_dev_amqp_user hw_dev_amqp_password 
sudo rabbitmqctl set_user_tags hw_dev_amqp_user administrator
sudo rabbitmqctl add_vhost hw_dev_vhost
sudo rabbitmqctl set_permissions -p hw_dev_vhost hw_dev_amqp_user ".*" ".*" ".*"

sudo rabbitmqctl add_user hw_prod_amqp_user hw_prod_amqp_password 
sudo rabbitmqctl set_user_tags hw_prod_amqp_user administrator
sudo rabbitmqctl add_vhost hw_prod_vhost
sudo rabbitmqctl set_permissions -p hw_prod_vhost hw_prod_amqp_user ".*" ".*" ".*"

Redis

Anois, déanaimis an chomhpháirt dheireanach dár bhfeidhmchlár a shuiteáil agus a chumrú - Redis. Úsáidfear é mar chúl chun torthaí tascanna Soilire a stóráil.

Ardóimid dhá choimeádán Docker le Redis le haghaidh timpeallachtaí dev agus prod ag baint úsáide as an síneadh Docker le haghaidh Plesk.

  1. Téimid go Plesk, téigh go dtí an rannóg Eisínteachtaí, cuardaigh an síneadh Docker agus é a shuiteáil (ní mór dúinn leagan saor in aisce):

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  2. Téigh go dtí an síneadh suiteáilte, faigh an íomhá tríd an gcuardach redis bitnami agus an leagan is déanaí a shuiteáil:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  3. Téann muid isteach sa choimeádán íoslódála agus déanaimid an chumraíocht a choigeartú: sonraigh an port, an méid RAM uasta a leithdháiltear, an focal faire sna hathróga timpeallachta, agus cuirimid an toirt:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  4. Déanaimid céimeanna 2-3 don choimeádán prod, sna socruithe ní athraíonn muid ach na paraiméadair: port, pasfhocal, méid RAM agus cosán chuig an bhfillteán toirte ar an bhfreastalaí:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

Clárlann Docker

Chomh maith le seirbhísí bunúsacha, bheadh ​​​​sé go deas do stór íomhá Docker féin a chur ar an bhfreastalaí. Go fortunately, tá spás freastalaí sách saor anois (go cinnte níos saoire ná síntiús DockerHub), agus tá an próiseas chun stór príobháideach a bhunú an-simplí.

Ba mhaith linn go mbeadh:

Chun seo a dhéanamh:

  1. Cruthaímid dhá fhofhearann ​​i Plesk inár síntiús: docker.helloworld.ru agus docker-ui.helloworld.ru, agus cumraigh deimhnithe Let's Encrypt dóibh.
  2. Cuir an comhad leis an bhfillteán docker.helloworld.ru subdomain docker-compose.yml le hábhar mar seo:
    version: "3"
    
    services:
      docker-registry:
        image: "registry:2"
        restart: always
        ports:
          - "53985:5000"
        environment:
          REGISTRY_AUTH: htpasswd
          REGISTRY_AUTH_HTPASSWD_REALM: basic-realm
          REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd
          REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
        volumes:
          - ./.docker-registry.htpasswd:/auth/.htpasswd
          - ./data:/data
    
      docker-registry-ui:
        image: konradkleine/docker-registry-frontend:v2
        restart: always
        ports:
          - "53986:80"
        environment:
          VIRTUAL_HOST: '*, https://*'
          ENV_DOCKER_REGISTRY_HOST: 'docker-registry'
          ENV_DOCKER_REGISTRY_PORT: 5000
        links:
          - 'docker-registry'
    

  3. Faoi SSH, ginfimid an comhad .htpasswd le haghaidh údarú Bunúsach sa stór Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Bailigh agus tóg coimeádáin:
    docker-compose up -d
  5. Agus ní mór dúinn Nginx a atreorú chuig ár gcoimeádáin. Is féidir é seo a dhéanamh trí Plesk.

Is gá na céimeanna seo a leanas a dhéanamh le haghaidh na fo-fhearainn docker.helloworld.ru agus docker-ui.helloworld.ru:

In alt Dev Tools ár suíomh téigh go dtí Rialacha Seachfhreastalaí Docker:

CI/CD in Github Actions do thionscadal Flasc+Uingearach
Agus cuir riail le seachfhreastalaí tráchta ag teacht isteach chuig ár gcoimeádán:

CI/CD in Github Actions do thionscadal Flasc+Uingearach

  1. Déanaimid seiceáil gur féidir linn logáil isteach inár gcoimeádán ón meaisín áitiúil:
    $ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    Login Succeeded
  2. Déanaimis seiceáil freisin ar oibriú an fhofhearainn docker-ui.helloworld.ru:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach
    Nuair a chliceálann tú ar Brabhsáil stórtha, taispeánfaidh an brabhsálaí fuinneog údaraithe ina mbeidh ort ainm úsáideora agus pasfhocal an stór a chur isteach. Tar éis sin, aistreofar muid chuig leathanach le liosta stórtha (go dtí seo, beidh sé folamh duit):

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

Ag oscailt calafoirt i Balla Dóiteáin Plesk

Tar éis na comhpháirteanna a shuiteáil agus a chumrú, ní mór dúinn calafoirt a oscailt ionas go mbeidh na comhpháirteanna inrochtana ó choimeádáin Docker agus ón líonra seachtrach.

A ligean ar a fheiceáil conas é seo a dhéanamh ag baint úsáide as an síneadh Balla Dóiteáin do Plesk a shuiteáil muid níos luaithe.

  1. Téigh Uirlisí & Socruithe > Socruithe > Balla Dóiteáin:
    CI/CD in Github Actions do thionscadal Flasc+Uingearach
  2. Téigh Athraigh Rialacha Balla Dóiteáin Plesk > Cuir Riail Chustaim leis agus na calafoirt TCP seo a leanas a oscailt don fholíon Docker (172.0.0.0 / 8):
    RabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Dearg: 32785, 32786

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  3. Cuirfimid riail leis freisin a osclóidh calafoirt PostgreSQL agus painéil bhainistíochta RabbitMQ don domhan lasmuigh:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  4. Cuir na rialacha i bhfeidhm ag baint úsáide as an gcnaipe Cuir Athruithe i bhFeidhm:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

CI/CD a bhunú i nGníomhartha Github

A ligean ar a fháil síos go dtí an chuid is suimiúla - a bhunú píblíne comhtháthú leanúnach agus a sheachadadh ár dtionscadal chuig an bhfreastalaí.

Beidh dhá chuid sa phíblíne seo:

  • íomhá a thógáil agus tástálacha a reáchtáil (don backend) - ar thaobh Github;
  • ascnaimh a rith (don inneall) agus imscaradh coimeádáin - ar an bhfreastalaí.

Imscaradh go Plesk

Déanaimis déileáil leis an dara pointe ar dtús (toisc go mbraitheann an chéad cheann air).

Déanfaimid an próiseas imlonnaithe a chumrú ag baint úsáide as an síneadh Git do Plesk.

Smaoinigh ar shampla le timpeallacht Prod do stór Inneall.

  1. Téim go dtí an síntiús ar ár suíomh Gréasáin Helloworld agus téigh go dtí an fo-alt Git:

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  2. Ionsáigh nasc chuig ár stór Github sa réimse "Remote Git Remote Repository" agus athraigh an fillteán réamhshocraithe httpdocs go ceann eile (m.sh. /httpdocs/hw_back):

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  3. Cóipeáil an eochair phoiblí SSH ón gcéim roimhe seo agus cuir tá sé i socruithe Github.
  4. Cliceáil OK ar an scáileán i gcéim 2, agus ina dhiaidh sin beidh muid a atreorú chuig an leathanach stór i Plesk. Anois ní mór dúinn an stór a chumrú le nuashonrú a dhéanamh ar na gealltanais don mháistir-bhrainse. Chun seo a dhéanamh, téigh go dtí Socruithe Stór agus an luach a shábháil Webhook URL (beidh sé ag teastáil uainn níos déanaí agus Gníomhartha Github á socrú):

    CI/CD in Github Actions do thionscadal Flasc+Uingearach

  5. Sa réimse Gníomhartha ar an scáileán ón alt roimhe seo, cuir isteach an script chun an t-imscaradh a sheoladh:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    más rud é:

    {REPOSITORY_ABSOLUTE_PATH} - cosán chuig an bhfillteán táirgí den stór inneall ar an bhfreastalaí;
    {ENV} - timpeallacht (dev / prod), inár gcás prod;
    {DOCKER_REGISTRY_HOST} - ósta ár stór duga
    {TG_BOT_TOKEN} — Comhartha bot teileagram;
    {TG_CHAT_ID} — ID an chomhrá/chainéil chun fógraí a sheoladh.

    Sampla scripte:

    cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/
    .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890
  6. Cuir úsáideoir ónár síntiús leis an ngrúpa Docker (ionas gur féidir leo coimeádáin a bhainistiú):
    sudo usermod -aG docker helloworld_admin

Socraítear an timpeallacht forbartha don stór inneall agus an t-éadanas ar an mbealach céanna.

Píblíne imlonnaithe i nGníomhartha Github

Rachaimid ar aghaidh go dtí an chéad chuid dár bpíblíne CI/CD in Github Actions a bhunú.

Inneall

Tá cur síos ar an bpíblíne i comhad imscaradh.yml.

Ach sula ndéantar é a pharsáil, déanaimis na hathróga Rúnda a theastaíonn uainn i Github a líonadh. Chun seo a dhéanamh, téigh go dtí Socruithe -> Rúin:

  • DOCKER_REGISTRY - óstach ár stór Docker (docker.helloworld.ru);
  • DOCKER_LOGIN - logáil isteach i stór Docker;
  • DOCKER_PASSWORD - pasfhocal dó;
  • DEPLOY_HOST — óstach ina bhfuil painéal riaracháin Plesk ar fáil (mar shampla: dia duit.ru: 8443 nó 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - comhartha le himscaradh chuig an stór táirgí ar an bhfreastalaí (fuair muid é in Imscaradh i Plesk lch. 4);
  • DEPLOY_BACK_DEV_TOKEN - comhartha lena imscaradh chuig an stór forbartha ar an bhfreastalaí.

Tá an próiseas imscartha simplí agus tá trí phríomhchéim ann:

  • ag tógáil agus ag foilsiú na híomhá inár stór;
  • tástálacha a reáchtáil i gcoimeádán bunaithe ar íomhá nuathógtha;
  • imscaradh chuig an timpeallacht inmhianaithe ag brath ar an brainse (dev/máistir).

Frontend

An comhad deploy.yml don stór tosaigh rud beag difriúil ó cheann Beck. Níl aon chéim aige le tástálacha a rith agus athraíonn sé ainmneacha na n-chomharthaí lena n-imscaradh. Rúin don stór tosaigh, dála an scéil, is gá a líonadh amach ar leithligh.

Socrú an tsuímh

Proxying tráchta trí Nginx

Bhuel, tá muid tagtha go dtí an deireadh. Níl ann fós ach seachfhreastalaí tráchta isteach agus amach chuig ár gcoimeádán trí Nginx a chumrú. Tá an próiseas seo clúdaithe againn cheana féin i gcéim 5 de shocrú Chlárlann Docker. Ba cheart an rud céanna a dhéanamh arís le haghaidh na gcodanna cúil agus tosaigh i dtimpeallachtaí dev agus prod.

Cuirfidh mé scáileáin scáileáin de na socruithe ar fáil.

Inneall

CI/CD in Github Actions do thionscadal Flasc+Uingearach

Frontend

CI/CD in Github Actions do thionscadal Flasc+Uingearach
Soiléiriú tábhachtach. Déanfar gach URL a sheachbhóthar chuig an gcoimeádán tosaigh, ach amháin iad siúd a thosaíonn le /api/ - déanfar iad a sheachbhóthar chuig an gcoimeádán cúil (mar sin sa choimeádán cúil, ní mór do gach láimhseálaí tosú leis /api/).

Torthaí

Anois ba chóir go mbeadh ár suíomh ar fáil ag helloworld.ru agus dev.helloworld.ru (prod- agus dev-environments, faoi seach).

San iomlán, d'fhoghlaimíomar conas feidhmchlár simplí a ullmhú i Flask and Angular agus cuirimid píblíne ar bun i Github Actions chun é a rolladh amach chuig freastalaí ag rith Plesk.

Déanfaidh mé na naisc chuig na stórtha a dhúbailt leis an gcód: cúl, ceann tosaigh.

Foinse: will.com

Add a comment