Журнал LinuxFormat - перейти на главную

LXF171:Unison: Доступ к своим фай­лам

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
(Син­хро­ни­зи­ру­ем на­ши дан­ные)
 
Строка 154: Строка 154:
 
Те­перь мы уме­ем син­хро­ни­зи­ро­вать дан­ные и от­прав­лять опо­ве­ще­ния. Да­вай­те удобства ради объ­е­ди­ним все эти действия в од­ном скрип­те.
 
Те­перь мы уме­ем син­хро­ни­зи­ро­вать дан­ные и от­прав­лять опо­ве­ще­ния. Да­вай­те удобства ради объ­е­ди­ним все эти действия в од­ном скрип­те.
  
#!/bin/bash
+
#!/bin/bash
  
 
/bin/ping -c 1 www.google.com 2>&1 >/dev/null
 
/bin/ping -c 1 www.google.com 2>&1 >/dev/null

Текущая версия на 14:32, 18 ноября 2018

Содержание

[править] Unison: Доступ к своим фай­лам

(thumbnail)
Наш эксперт Джеймс Лит­тон за­ни­мал ру­ко­во­дя­щие долж­но­сти в не­сколь­ких ор­га­ни­за­ци­ях и яв­ля­ет­ся парт­не­ром и ди­рек­то­ром Identity Automation LP.

Хо­ти­те разделять сво­и дан­ные между раз­ными сис­темами без про­блем с при­ват­но­стью и соб­ст­вен­но­стью на них? Джеймс Лит­тон по­ка­зы­ва­ет, как.

При мыс­лях о сво­их дан­ных у мно­гих из нас воз­ни­ка­ет внут­рен­няя борь­ба: мы по­дыс­ки­ва­ем наи­луч­ший спо­соб га­ран­ти­ро­вать их со­хран­ность. В преж­ние вре­ме­на все дан­ные уме­ща­лись на не­сколь­ких дис­ке­тах; по­том мы пе­ре­шли к лен­там, CD, DVD, NAS и, на­ко­нец, к об­лач­ным хра­ни­ли­щам.

Рас­смот­рев ти­пич­ную стра­те­гию управ­ле­ния дан­ны­ми, мы об­на­ру­жим, что за­час­тую она фраг­мен­тар­на и не­эф­фек­тив­на. Ва­ши по­все­днев­ные фай­лы, воз­мож­но, хра­нят­ся на Dropbox, что по­зво­ля­ет лег­ко раз­де­лять их ме­ж­ду раз­ны­ми ком­пь­ю­те­ра­ми, ко­то­ры­ми вы ре­гу­ляр­но поль­зуе­тесь. Этот ва­ри­ант пре­крас­но под­хо­дит для элек­трон­ных таб­лиц, баз дан­ных и до­ку­мен­тов — все вме­сте это до­воль­но скром­ный объ­ем дан­ных. Но ко­гда до­хо­дит до фо­то­гра­фий, му­зы­ки и филь­мов, на­чи­на­ют­ся про­бле­мы. Для фай­лов муль­ти­ме­диа нуж­но го­раз­до боль­ше мес­та, и они час­то ока­зы­ва­ют­ся на до­маш­нем сер­ве­ре NAS, и, воз­мож­но, вре­мя от вре­ме­ни ко­пи­ру­ют­ся на внеш­ний USB-диск.

Пред­по­ло­жим, что об­щий объ­ем ва­ших дан­ных — 500 ГБ, и вы хо­ти­те со­брать их все в од­ном мес­те. Та­кое по­зво­ля­ет сделать Dropbox — за $ 499 в год, и это, че­ст­но го­во­ря, до­воль­но ра­зум­ная це­на, но мно­гим из нас не нра­вит­ся то, что их дан­ные бу­дут на­хо­дить­ся на сер­ве­рах Amazon S3 и вый­дут из-под кон­тро­ля. Дан­ные мож­но за­шиф­ро­вать, но с их кон­фи­ден­ци­аль­но­стью и соб­ст­вен­но­стью на них не все так про­сто. Что­бы из­ба­вить­ся от этих не­дос­тат­ков, ис­сле­ду­ем ва­ри­ан­ты по­строе­ния соб­ст­вен­ной сис­те­мы.

[править] Аль­тер­на­тив­ные ре­ше­ния

На пер­вый взгляд, су­ще­ст­ву­ют от­но­си­тель­но про­стые для реа­ли­за­ции ре­ше­ния, та­кие как OwnCloud и Sparkleshare. Оба вы­гля­дят про­стей­шим спо­со­бом соз­дать пол­но­цен­ную за­ме­ну Dropbox, но ес­ли по­ду­мать о за­да­чах это­го про­ек­та, то нам во­все не нуж­но реа­ли­зо­вы­вать всю функ­цио­наль­ность Dropbox. Дру­ги­ми сло­ва­ми, нам не нуж­ны ни web-ин­тер­фейс, ни воз­мож­ность де­лить­ся фай­ла­ми с дру­ги­ми, а нуж­на толь­ко воз­мож­ность вы­бо­роч­но раз­де­лять фай­лы ме­ж­ду ком­пь­ю­те­ра­ми. То есть луч­ше бы взять что-ни­будь по­лег­че Sparkleshare или OwnCloud.

Учи­ты­вая про­сто­ту и воз­мож­но­сти ре­ше­ний для ко­манд­ной стро­ки, пре­дос­тав­ляе­мые rsync, эта ути­ли­та при­хо­дит на ум пер­вой. Од­на­ко про­бле­ма rsync в том, что она не при­спо­соб­ле­на для дву­сто­рон­ней син­хро­ни­за­ции. У нее есть не­сколь­ко по­лез­ных оп­ций, по­зво­ляю­щих до­воль­но близ­ко по­доб­рать­ся к дву­сто­рон­ней син­хро­ни­за­ции, но дос­тичь таковой пол­но­стью нель­зя. Хо­ро­шая ил­лю­ст­ра­ция — от­сут­ст­вие эф­фек­тив­но­го спо­со­ба ре­ак­ции на уда­ле­ние фай­лов. Су­ще­ст­ву­ют спо­со­бы это обой­ти, ко­то­рые вклю­ча­ют со­хра­не­ние вы­во­да в лог-фай­лы, срав­не­ние и уда­ле­ние, но это из­лиш­не ус­лож­ня­ет де­ло.

Ес­ли не­об­хо­дим про­стой сер­вер для ре­зерв­но­го ко­пи­ро­ва­ния дан­ных, на­хо­дя­щих­ся на од­ном ком­пь­ю­те­ре, rsync пре­крас­но по­дой­дет, но нам нуж­но не­что бо­лее ин­тел­лек­ту­аль­ное, по­это­му мы об­ра­тим­ся к Unison. Unison — ути­ли­та син­хро­ни­за­ции фай­лов, ра­бо­таю­щая в Linux, BSD, OS X и Windows. Она по­зво­ля­ет син­хро­ни­зи­ро­вать на­бор фай­лов и ка­та­ло­гов, ко­то­рые хра­нятся в раз­ных мес­тах, пу­тем рас­про­стра­не­ния из­ме­не­ний ме­ж­ду на­бо­ра­ми.

Пре­ж­де чем рас­су­ж­дать о стра­те­гии, важ­но по­нять, как имен­но ра­бо­та­ет Unison. На са­мом ба­зо­вом уров­не Unison под­дер­жи­вает па­ры ре­п­лик син­хро­ни­зи­ро­ван­ны­ми. Уло­ви­ли сло­во «па­ры»? При ка­ж­дом за­пус­ке Unison он син­хро­ни­зи­ру­ет две ре­п­ли­ки, и ни­че­го боль­ше. Ес­ли ре­п­лик боль­ше двух, по­тре­бу­ет­ся хо­ро­шо про­ду­ман­ная схе­ма, ко­то­рая га­ран­ти­ру­ет, что дан­ные син­хро­ни­зи­ру­ют­ся имен­но так, как мы во­об­ра­жа­ем.

[править] Ре­п­ли­ки

Те­перь уме­ст­но спро­сить: «А что та­кое ре­п­ли­ка?» По-про­сто­му, ре­п­ли­ка — это на­бор фай­лов и ка­та­ло­гов. Ре­п­ли­ки мо­гут со­от­вет­ст­во­вать раз­ным хос­там, но это не обя­за­тель­но. Что­бы луч­ше по­нять идею, пред­ставь­те, что у вас есть ком­пь­ю­тер до­ма и ком­пь­ю­тер в офи­се, и вы хо­ти­те, что­бы до­маш­ний ка­та­лог ав­то­ма­ти­че­­ски син­хро­ни­зи­ро­вал­ся ме­ж­ду эти­ми ком­пь­ю­те­ра­ми. Пусть у вас так­же есть внеш­ние USB-дис­ки для ре­зерв­ных ко­пий до­ма и в офи­се. В этот сце­на­рий во­вле­че­но все­го два ком­пь­ю­те­ра, но ре­п­лик Unison че­ты­ре.

За­ду­мав­шись о том, ка­кую струк­ту­ру син­хро­ни­за­ции вы­брать, вы по­лу­чи­те раз­лич­ные «то­по­ло­гии», ко­то­рые по­хо­жи на из­вест­ные се­те­вые то­по­ло­гии — ли­ния, звез­да, сет­ка, коль­цо и дру­гие. Опи­сан­ный вы­ше сце­на­рий со­от­вет­ст­ву­ет ли­ней­ной мо­дели, но луч­ший спо­соб ор­га­ни­за­ции на­шей сис­те­мы — с по­мо­щью ха­ба и мо­де­ли «звез­да». В такой кон­фи­гу­ра­ции в цен­тре на­хо­дится сер­вер, и на ка­ж­дом из ком­пь­ю­те­ров имеет­ся один про­филь Unison, ко­то­рый син­хро­ни­зи­ру­ет дан­ные с сер­ве­ром; эту схе­му мы и реа­ли­зу­ем на на­шем уро­ке.

Для на­ше­го тес­то­во­го слу­чая рас­смот­рим си­туа­цию, при ко­то­рой на ре­гу­ляр­ной ос­но­ве ис­поль­зу­ют­ся че­ты­ре ком­пь­ю­те­ра: офис­ный на­столь­ный ком­пь­ю­тер, до­маш­ний на­столь­ный ком­пь­ю­тер, до­маш­ний но­ут­бук и но­ут­бук для по­ез­док. Мы за­ме­ним Dropbox на всех этих че­ты­рех ком­пь­ю­те­рах. На двух ком­пь­ю­те­рах ус­та­нов­ле­на Mac OS X, на двух дру­гих — Linux.

При ра­бо­те с Unison важ­но обес­пе­чить, что­бы на всех сис­те­мах, уча­ст­вую­щих в син­хро­ни­за­ции, бы­ла ус­та­нов­ле­на од­на и та же вер­сия про­грам­мы. Вос­поль­зу­ем­ся вер­си­ей 2.40, это по­след­ний ста­биль­ный ре­лиз.

На плат­фор­ме Mac за­гру­зи­те гра­фи­че­скую обо­лоч­ку вер­сии 2.40.69 с сай­та http://alan.petitepomme.net/unison/index.html. Смон­ти­руй­те dmg и ско­пи­руй­те Unison в ка­та­лог при­ло­же­ний. Те­перь от­крой­те Unison, и про­грам­ма по­про­сит вас ус­та­но­вить вер­сию ути­ли­ты для ко­манд­ной стро­ки — ска­жи­те «да». Ути­ли­та ус­та­но­вит­ся в /usr/bin/. Для про­вер­ки вы­пол­ни­те ко­ман­ду

unison -version

Unison долж­ен вы­вес­ти но­мер вер­сии — 2.40.69. В Ubuntu 12.04 Unison мож­но ус­та­но­вить из ре­по­зи­то­ри­ев Ubuntu, ско­ман­до­вав

sudo apt-get install unison

Про­ве­рить ус­та­нов­ку мож­но ко­ман­дой

unison -version

Про­грам­ма долж­на вы­вес­ти но­мер вер­сии — 2.40.65. Те­перь мож­но соз­дать про­филь Unison. Про­филь оп­ре­де­ля­ет, как Unison бу­дет син­хро­ни­зи­ро­вать две ре­п­ли­ки. Соз­да­дим файл про­фи­ля под на­зва­ни­ем lxfsync.prf в на­шем сис­тем­ном ка­та­ло­ге Unison:

root = /home/lxf/Unison

root = ssh://lxf@example.com//home/lxf/Unison

fastcheck = true

batch = true

force = newer

times = true

sshargs = -C

Стро­ки 1 и 2 за­да­ют ме­сто­по­ло­же­ние ре­п­лик. Стро­ка 3 ве­лит Unison применять вре­мя из­ме­не­ния и раз­мер фай­ла как «псевдо­но­ме­р уз­ла» при ска­ни­ро­ва­нии ре­п­лик на на­ли­чие из­ме­не­ний, вме­сто счи­ты­ва­ния со­дер­жи­мо­го ка­ж­до­го фай­ла це­ли­ком. Стро­ка 4 от­клю­ча­ет ин­тер­фейс поль­зо­ва­те­ля. Стро­ка 5 ве­лит Unison брать файл с по­след­ним вре­ме­нем из­ме­не­ния. Стро­ка 6 оз­на­ча­ет, что бу­дет со­хра­нять­ся вре­мя из­ме­не­ния фай­лов; и, на­ко­нец, в стро­ке 7 вклю­ча­ет­ся сжа­тие SSH для уве­ли­че­ния про­из­во­ди­тель­но­сти. За­ме­ча­ние об оп­ции times: увы, она не под­дер­жи­ва­ет ка­та­ло­ги. При ко­пи­ро­ва­нии ка­та­ло­га вре­мя его соз­да­ния бу­дет со­от­вет­ст­во­вать соз­да­нию ка­та­ло­га ко­пии, а не ис­ход­но­го ка­та­ло­га.

Те­перь мы го­то­вы к пер­вич­ной син­хро­ни­за­ции. Для на­ча­ла вы­бе­ри­те один из ком­пь­ю­те­ров, соз­дай­те ко­пию ка­та­ло­га Dropbox и на­зо­ви­те ее Unison.

cp -r ~/Dropbox ~/Unison

За­тем мы под­клю­чим­ся к на­ше­му сер­ве­ру Unison че­рез SSH и соз­да­дим со­от­вет­ст­вую­щий ка­та­лог, в ко­то­рый бу­дут син­хро­ни­зи­ро­вать­ся на­ши че­ты­ре ком­пь­ю­те­ра.

mkdir ~/Unison

[править] Син­хро­ни­зи­ру­ем на­ши дан­ные

Те­перь нуж­но пе­ре­мес­тить ко­пию дан­ных с но­ут­бу­ка на сер­вер. Что­бы убе­дить­ся в шиф­ро­ва­нии дан­ных при пе­ре­да­че ме­ж­ду ком­пь­ю­те­ра­ми, взгля­ни­те на па­ра­мет­ры: с их по­мо­щью мы ука­за­ли, что для под­клю­че­ния к уда­лен­ной ре­п­ли­ке нуж­но поль­зо­вать­ся SSH. Син­хро­ни­за­ция за­пус­ка­ет­ся сле­дую­щей ко­ман­дой:

unison -ui text lxfsync

Пер­вые два па­ра­мет­ра ве­лят Unison за­пус­кать­ся в тек­сто­вом ре­жи­ме. Тре­тий па­ра­метр — имя про­фи­ля, ко­то­рый мы хо­тим ис­поль­зо­вать.

По окон­ча­нии син­хро­ни­за­ции Unison дол­жен со­об­щить ко­ли­че­­ст­во пе­ре­дан­ных эле­мен­тов. Ес­ли не­ко­то­рые эле­мен­ты бы­ли про­пу­ще­ны или воз­ник­ли ошиб­ки, под­роб­ную ин­фор­ма­цию о тран­зак­ции мож­но по­лу­чить, за­гля­нув в файл жур­на­ла — ~/unison.log.При за­пус­ке Unison вы ви­де­ли, что вас про­сят вве­сти па­роль учет­ной за­пи­си на сер­ве­ре. А так как мы со­би­ра­ем­ся ав­то­ма­ти­зи­ро­вать этот про­цесс, ау­тен­ти­фи­ка­ция долж­на про­хо­дить без ва­шего вме­ша­тель­ст­ва.

Что­бы дос­тичь этой це­ли, вос­поль­зу­ем­ся ау­тен­ти­фи­ка­ци­ей SSH по клю­чу. Для это­го на ка­ж­дом ком­пь­ю­те­ре, син­хро­ни­зи­руе­мом с сер­ве­ром, нуж­но сге­не­ри­ро­вать уни­каль­ный ключ. Что­бы сде­лать это на но­ут­бу­ке, вы­пол­ни­те сле­дую­щую ко­ман­ду:

ssh-keygen -t rsa

По­сле это­го в ка­та­ло­ге ~/.ssh долж­но поя­вить­ся два фай­ла: id_rsa и id_rsa.pub. Файл id_rsa.pub — наш пуб­лич­ный ключ, и его нуж­но ско­пи­ро­вать на сер­вер, что­бы де­мон SSH мог до­ве­рять это­му клю­чу. Пе­ре­мес­тим файл ко­ман­дой scp:

scp ~/.ssh/id_rsa.pub lxf@example.com:~/.ssh/Computer1.pub

Те­перь нуж­но пре­ду­пре­дить де­мон SSH на сер­ве­ре, что­бы он до­ве­рял это­му клю­чу. Для это­го под­клю­чим­ся к сер­ве­ру по SSH и ско­ман­ду­ем:

cat ~/.ssh/Computer1.pub >> authorized_keys

Что­бы про­ве­рить на­шу ра­бо­ту, сно­ва за­пус­тим ко­ман­ду Unison с но­ут­бу­ка. Ес­ли все в порядке, на сей раз у нас не спро­сят па­роль:

unison -ui text lxfsync

Хо­тя это и не обя­за­тель­но, мно­гим нра­вит­ся, что агент Dropbox ин­фор­ми­ру­ет их о происшедших из­ме­не­ни­ях; пе­ре­не­сем эту воз­мож­ность на че­ты­ре наших ком­пь­ю­те­ра, син­хро­ни­зи­руе­мые с сер­ве­ром. Так как син­хро­ни­за­ция про­из­во­дит­ся с по­мо­щью скрип­тов обо­лоч­ки, нуж­но ус­та­но­вить ути­ли­ты, ко­то­рые по­зво­лят об­ра­тить­ся к сис­те­ме опо­ве­ще­ний ра­бо­че­го сто­ла. На плат­фор­ме Mac мож­но вос­поль­зо­вать­ся Growl по­сред­ст­вом growelnotify. На ком­пь­ю­те­рах Ubuntu вос­поль­зу­ем­ся NotifyOSD с по­мо­щью notify-send.

На плат­фор­ме Mac за­гру­зи­те Growl 1.2.2 с growl.info. По­сле за­груз­ки смон­ти­руй­те dmg и ус­та­но­ви­те Growl, два­ж­ды щелк­нув на скрип­те Growl.pkg. От­крой­те ка­та­лог Extras, за­тем growlnotify, и ус­та­но­ви­те growlnotify, за­пус­тив скрипт growlnotify.pkg. Те­перь мож­но от­прав­лять опо­ве­ще­ния Growl с ко­манд­ной стро­ки. Что­бы это про­ве­рить, от­крой­те тер­ми­нал и вы­пол­ни­те ко­ман­ду

growlnotify --message “Hello World”

В Ubuntu для пе­ре­да­чи со­об­ще­ний де­мо­ну опо­ве­ще­ний ра­бо­че­го сто­ла нуж­но ус­та­но­вить биб­лио­те­ку libnotify. Ус­та­но­вить ее мож­но из ре­по­зи­то­ри­ев Ubuntu, ко­ман­дой

sudo apt-get install libnotify-bin

Что­бы ее про­ве­рить, по­про­буй­те вы­пол­нить сле­дую­щую ко­ман­ду:

notify-send “Hello World”

Ес­ли все хо­ро­шо, ва­ши со­об­ще­ния поя­вят­ся на со­от­вет­ст­вую­щих ра­бо­чих сто­лах.

[править] Объ­е­ди­ня­ем все вме­сте

Те­перь мы уме­ем син­хро­ни­зи­ро­вать дан­ные и от­прав­лять опо­ве­ще­ния. Да­вай­те удобства ради объ­е­ди­ним все эти действия в од­ном скрип­те.

#!/bin/bash

/bin/ping -c 1 www.google.com 2>&1 >/dev/null

if [“$?” == 0 ]; then

root=”/home/lxf”

image=”$root/.unison/sync.png”

stat=`/usr/bin/unison -ui text -logfile “$root/unison.log” lxfsync 2>&1 >/dev/null | tail -1`

if [${PIPESTATUS[0]} != 0 ]; then

notify-send “Unison” “Sync Error” -i “$image” -t 0

exit 1

fi

if [ ${stst:0:7} == “Nothing” ]; then

exit 0

else

stat2=`echo “$stat” | grep -Po ‘(?<=\().*?(?=\))’`

fi

notify-send “Unison” “$stat2” -i “$image”

else

exit 1

fi

Как ви­ди­те, наш скрипт очень прост. В стро­ке 1 за­да­ет­ся тип скрип­та (Bash). В стро­ке 2 про­ве­ря­ет­ся под­клю­че­ние к Ин­тер­не­ту. В стро­ке 3 ана­ли­зи­ру­ет­ся ре­зуль­тат про­вер­ки, и ес­ли под­клю­че­ния нет, мы пе­ре­хо­дим к стро­ке 18, в ко­то­рой скрипт за­вер­ша­ет­ся с ко­дом ошиб­ки, оз­на­чаю­щим, что син­хро­ни­за­ция за­вер­ши­лась не­удач­но.

В том случае, ес­ли под­клю­че­ние дос­туп­но, в стро­ках 4 и 5 за­да­ют­ся не­сколь­ко пе­ре­мен­ных, по­сле че­го мы пе­ре­хо­дим к стро­ке 6. В данной стро­ке мы за­пус­ка­ем Unison, по­лу­ча­ем по­след­нюю стро­ку вы­во­да и со­хра­ня­ем ее в пе­ре­мен­ной $stat, ко­то­рой вос­поль­зу­ем­ся поз­же. В стро­ке 7 мы про­ве­ря­ем, вер­нул ли Unison код 0, оз­на­чаю­щий ус­пеш­ную син­хро­ни­за­цию. Ес­ли мы по­лу­чи­ли дру­гой код ошиб­ки, то в стро­ке 8 мы от­прав­ля­ем опо­ве­ще­ние ра­бо­че­го сто­ла об ошиб­ке син­хро­ни­за­ции.

При ус­пеш­ном за­вер­ше­нии син­хро­ни­за­ции в стро­ке 11 мы ана­ли­зи­ру­ем пе­ре­мен­ную $stat, что­бы по­нять, вы­пол­нил ли Unison ка­кие-ли­бо дей­ст­вия. Ес­ли пер­вое сло­во в пе­ре­мен­ной — “Nothing [Ни­че­го]”, то мы вы­хо­дим из скрип­та, по­то­му что об­нов­ле­ний не бы­ло; в про­тив­ном слу­чае пе­ре­хо­дим к стро­ке 14, где по­лу­ча­ем стро­ку в круг­лых скоб­ках и со­хра­ня­ем ее в пе­ре­мен­ной $stat2, по­сле че­го пе­ре­хо­дим в стро­ку 16 и ото­бра­жа­ем ре­зуль­та­ты поль­зо­ва­те­лю.

Что­бы все ра­бо­та­ло без на­ше­го уча­стия, скрипт дол­жен за­пус­кать­ся ре­гу­ляр­но и син­хро­ни­зи­ро­вать­ся с сер­ве­ром. С этой за­да­чей пре­крас­но спра­вит­ся cron. Да­вай­те сде­ла­ем ин­тер­вал син­хро­ни­за­ции в пять ми­нут сле­дую­щей ко­ман­дой:

crontab -e

Те­перь до­ба­вим сле­дую­щее:

  • /5 * * * * DISPLAY=:0 /home/lxf/sync.sh
  • /5 ве­лит cron за­пус­кать­ся ка­ж­дые пять ми­нут. Сле­дую­щие че­ты­ре звез­доч­ки ве­лят cron за­пус­кать­ся ка­ж­дые пять ми­нут ка­ж­до­го ча­са ка­ж­до­го дня ка­ж­до­го ме­ся­ца. DISPLAY=:0 на­прав­ля­ет вы­вод скрип­та на те­ку­щий мо­ни­тор.

Вот и все! Те­перь вы обзавелись бес­плат­ной за­ме­ной Dropbox, ко­то­рая на­хо­дит­ся под ва­шим кон­тро­лем. Не­ко­то­рые из вас, не­со­мнен­но, по­ин­те­ре­су­ют­ся: а как же луч­ше все­го де­лить­ся фай­ла­ми с чле­на­ми се­мьи и друзь­я­ми? Здесь луч­ше Dropbox вам не най­ти. Про­дол­жай­те поль­зо­вать­ся бес­плат­ной учет­ной за­пи­сью и де­лить­ся фай­ла­ми по ме­ре не­об­хо­ди­мо­сти, не бес­по­ко­ясь об ос­таль­ных дан­ных. |

Персональные инструменты
купить
подписаться
Яндекс.Метрика