ecryptfs
and it was good enough for my needs. When I moved to Manjaro I decided to leave ecryptfs
as my primary encryption method but to recreate the passphrase from scratch with a completely fresh and clean home folder. Then I moved all encrypted files to another location… I believe this was the right decision, but I struggled for about a day to restore access to my previous data. This little note is for me and for those who need a bit of help with the recovery process.
For those who just came for the possible solution, jump straight to TL;DR
If you are here you should already know that the encrypted data is located in /home/.ecryptfs/%username%
. I moved my previous data to /home/.ecryptfs/prev
but it doesn’t really matter. You can replace %username%
or whole path with your value. So let’s replace the whole /home/.ecryptfs/%username%
with short %path%
for the sake of brevity.
I tried to use ecryptfs-recover-private
and got this error:
sudo ecryptfs-recover-private %path%/.Private
### Output ###
# INFO: Found [%path%/.Private].
# Try to recover this directory? [Y/n]:
# INFO: Found your wrapped-passphrase
# Do you know your LOGIN passphrase? [Y/n]
# INFO: Enter your LOGIN passphrase...
# Passphrase:
# Inserted auth tok with sig [3121cedc8cecfb1] into the user session keyring
# mount: /tmp/ecryptfs.xxxxxxxx: mount(2) system call failed: No such file or directory.
# dmesg(1) may have more information after failed mount system call.
# ERROR: Failed to mount private data at [/tmp/ecryptfs.xxxxxxxx].
(I use sudo
instead of #
because syntax highlighting messes up with hashtag)
Wierd…
So it says dmesg
can help. Let’s try. It’s a bit hard to find the necessary information in this constant flow of messages… I tried to run these two commands one right after the other. And there’s a hint:
sudo dmesg
### Output ###
# [128513.402407] Could not find key with description: [2a283744646d8d1]
# [128513.402410] process_request_key_err: No key
# [128513.402411] Could not find valid key in user session keyring for sig specified in mount option: [2a283744646d8d1]
Yeah, I know some of these words. I guess the essential part is user session keyring
My craziest thought was “why not try to add some key in some keyring of the current user”. So I did this (after a lot of googling):
ecryptfs-unwrap-passphrase %path%/.ecryptfs/wrapped-passphrase
### Output ###
# Passphrase:
# %32-long-line-with-random-chars%
Instead of %32-long-line-with-random-chars%
, you will get your own key.
Next I found this line:
echo -n "%32-long-line-with-random-chars%" | ecryptfs-add-passphrase --fnek -
### Output ###
# Inserted auth tok with sig [3121cedc8cecfb1] into the user session keyring
# Inserted auth tok with sig [2a283744646d8d1] into the user session keyring
And now tried mount private folder again:
sudo ecryptfs-recover-private %path%/.Private
### Output ###
# [sudo] password for username:
# INFO: Found [%path%/.Private].
# Try to recover this directory? [Y/n]:
# INFO: Found your wrapped-passphrase
# Do you know your LOGIN passphrase? [Y/n]
# INFO: Enter your LOGIN passphrase...
# Passphrase:
# Inserted auth tok with sig [3121cedc8cecfb1] into the user session keyring
# INFO: Success! Private data mounted at [/tmp/ecryptfs.yyyyyyyy].
And voilà! I have my data back:
ls -al /tmp/ecryptfs.yyyyyyyy
### Output ###
# drwx------ 3 username username 28672 июн 12 15:17 .
# drwxrwxrwt 26 root root 1360 июн 23 23:04 ..
# drwxrwxr-x 3 username username 4096 янв 5 2021 .local
Yeah, there were a lot more things in it. But I’ve already moved it away :grin:
I think this is not a new problem. But I spent a lot of time solving this puzzle, so I decided to share my knowledge for future me.
If you have this error trying ecryptfs-recover-private
:
mount: /tmp/ecryptfs.xxxxxxxx: mount(2) system call failed: No such file or directory.
dmesg(1) may have more information after failed mount system call.
ERROR: Failed to mount private data at [/tmp/ecryptfs.xxxxxxxx].
You can try this:
ecryptfs-unwrap-passphrase %path%/.ecryptfs/wrapped-passphrase
# Shouldn't be sudo!
# Replace "%32-long-line-with-random-chars%" with `ecryptfs-unwrap-passphrase` output
echo -n "%32-long-line-with-random-chars%" | ecryptfs-add-passphrase --fnek -
sudo ecryptfs-recover-private %path%/.Private
If you succeed, please inform me about it somehow. I will be super thankful :blush:
P.S. I’m not a native English-speaking person, my knowledge is relatively low. This post is my first in this language and can have a lot, I mean A LOT of issues. I will be very thankful if you help me to fix my grammar errors or give me an advice(s) :fox:
]]>Последние несколько месяцев я в качестве хобби-проекта разрабатывал небольшой телеграм-бот. Не столько из необходимости, сколько из желания выучить новый язык программирования (Rust ) и немного улучшить себе жизнь.
На текущий момент бот тесно интегрируется со Spotify и выполняет несколько не очень простых функций:
// О том, как это все работает, я планирую написать отдельный пост
На текущий момент бот в состоянии MVP, в нем не хватает некоторых важных функций (например поставить проверку текстов на паузу), он все еще может падать из-за каких-то ошибок, не хватает нормальной документации и раздела помощи, интерфейс полностью на английском и п.р.
Но он уже нашел и проверил тексты >5600 песен для меня, моей семьи и еще пары людей. На текущий момент я дизлайкнул 755 треков, а бот пропустил ~620 раз (на самом деле больше, просто статистику по пропускам я запустил не так давно)
Так вот о чем я. Мне нужно еще 5-10 человек:
Мне нужно больше добровольцев для тестирования!
На текущий момент у бота 5 активных пользователей и многие проблемы были решены на ранних этапах. Пока я не могу сделать его полностью публичным по различным причинам.
Поэтому, если ты подходишь под требования выше и хочешь помочь:
… для получения дальнейших инструкций.
Добро пожаловать всем желающим! :fox:
P.S. Исходный код проекта доступен на github.com/vtvz/rustify
]]>Сначала эта библиотека загружалась синхронно со всей страницей. Это значит то, что индикатор загрузки не исчезнет, пока смайлики не отрисуются. Для рендера использовался простейший скрипт, взятый из официального репозитория, который выглядел следующим образом:
$(function () {
var emoji = new EmojiConvertor();
emoji.img_sets.apple.path = '/assets/images/emoji/';
emoji.include_title = true;
emoji.include_text = true;
emoji.replace_mode = 'css';
emoji.allow_native = true;
emoji.addAliases({
'fox': '1f98a',
});
$('.js-emojify').each(function () {
$(this).find(':not(script)').html(function (i, oldHtml) {
return emoji.replace_unified(emoji.replace_emoticons(oldHtml));
});
});
});
Все понятно и очевидно: вытягиваем весь html, вставляем туда иконки, заменяем старый html новым. И все это работало хорошо… до поры. Проблемы начались тогда, когда я решил, что смайлики должны отрисовываться после загрузки страницы, а не во время. Это значительно ускоряло отображение страниц, но создавало некоторые проблемы.
Самая основная выглядела следующим образом:
И после этого всего виджеты переставали работать. Почему? Потому что мы заменили старый html совершенно новым, после чего все обработчики форм переставали работать совсем. Хотя визуально для нас ничего не поменялось, с точки зрения браузера это совсем другие эллементы.
Искусственно добиться этого эффекта можно следующим образом:
$('#social-post-generator-container').html(
$('#social-post-generator-container').html()
)
Таким образом мы заменили оригинальный html новым
Еще одна проблема была в том, что он заменял emoji даже в теге script
.
Но это уже не так критично и легко решается.
Предположим, что у нас уже есть функция emojificator
, которая добавляет эмотиконы в текст.
Работает она ровно также, как в указанном выше куске кода.
Чего нам нужно добиться:
script
теги.textarea
и прочие “input” элементы.Мне потребовалось несколько часов на исследование и реализацию этого дела, но результатом я остался доволен.
DOM состоит не только из обычных элементов, но и из текста, комментариев и п.р. Наша задача состоит в том, чтобы рекурсивно пройтись по всем текстовым нодам и внедрить туда смайлы.
Выглядит это так:
const blacklist = [
HTMLScriptElement,
HTMLTextAreaElement,
HTMLInputElement,
HTMLSelectElement,
HTMLButtonElement,
];
const skip = (node) => {
for (let cls of blacklist) {
if (node instanceof cls) {
return true;
}
}
return false;
}
const recursiveEmojification = (node) => {
if (node.nodeType !== Node.TEXT_NODE) {
if (node.nodeType === Node.ELEMENT_NODE && !skip(node)) {
node.childNodes.forEach(_ => recursiveEmojification(_))
}
return;
}
// Do something with 'node.nodeValue'
}
document
.querySelectorAll(".js-emojify")
.forEach(_ => recursiveEmojification(_));
В общем, ничего сложного. Обратите особое внимание на функцию skip
.
Именно она гарантирует “невредимость” некоторых элементов страницы.
А именно теги script
, textarea
и подобные им.
Осталось дело за малым. Или нет? :thinking_face:
Теперь у нас есть все куски текстов, в которых потенциально могут быть emoji.
Если нам нужна совместимость только с девайсами Apple, то мы можем заменить все :emoji:
смайлы
на обычный unicode и на этом успокоиться. Но у меня Линукс. И многих других тоже нет ничего яблочного.
Поэтому нужно заменить все текстовые смайлы, на маленькие картинки. Вот тут и начинается самое интересное.
Дело в том, что мы не можем просто взять и, вместо текстовой ноды, вкорячить кусок html кода.
Если попробовать сделать node.nodeValue = '<span>Hi</span>'
, то на выходе будет экранированный html код.
Поэтому этот код не будет работать, как этого хочется:
const emojified = emojificator(node.nodeValue);
// Пропускаем дальнейшие манипуляции, если ничего не изменилось
if (emojified === node.nodeValue) {
return;
}
node.nodeValue = emojified;
А вот результат:
Так себе… Не то, чего я хотел. Поэтому проделываем следующий финт:
span
;Вот так это выглядит:
let replacement = document.createElement('span'); // (1)
replacement.classList.add('js-emojified') // Для наглядности добавим класс
replacement.innerHTML = emojified; // (2)
node.parentNode.insertBefore(replacement, node); // (3)
node.parentNode.removeChild(node); // (4)
Да, мы создали еще один элемент. Но это не должно быть проблемой, так как чистый span
ни на что не влияет.
На выходе получилось достаточно аккуратное решение. Хоть и с небольшими хаками.
const blacklist = [
HTMLScriptElement,
HTMLTextAreaElement,
HTMLInputElement,
HTMLSelectElement,
HTMLButtonElement,
];
const skip = (node) => {
for (let cls of blacklist) {
if (node instanceof cls) {
return true;
}
}
return false;
}
const recursiveEmojification = (node) => {
if (node.nodeType !== Node.TEXT_NODE) {
if (node.nodeType === Node.ELEMENT_NODE && !skip(node)) {
node.childNodes.forEach(_ => recursiveEmojification(_))
}
return;
}
const emojified = emojificator(node.nodeValue);
if (emojified === node.nodeValue) {
return;
}
let replacement = document.createElement('span');
replacement.classList.add('js-emojified')
replacement.innerHTML = emojified;
node.parentNode.insertBefore(replacement, node);
node.parentNode.removeChild(node);
}
document
.querySelectorAll(".js-emojify")
.forEach(_ => recursiveEmojification(_));
Не могу сказать, что смайлы для меня настолько важны, чтобы я стал так заморачиваться. Скорее то, что это был определенный вызов, интересная задача на исследование. Я узнал много нового и стал лучше понимать работу html и js в браузере. И сделал свой сайт чуточку лучше :blush:
Спасибо за внимание. Надеюсь, было интересно :fox:
]]>Или например, сколько человек посмотрело статью из секции “Latest Article” на главной странице, сколько перелистнуло на следующий пост, и так далее. Выбор очевиден – нужно использовать UTM метки. Они очень распространены в рекламной части бизнеса, но их можно использовать и для простой аналитики. Но тут есть одна проблемка…
Проблема в том, что эти метки очень массивные. Вот к примеру, одна из возможных ссылок на пост в социальной сети выглядит следующим образом:
https://vtvz.me/blog/social-post-generator/
?utm_source=_telegram
&utm_medium=social-post
&utm_campaign=blog
&utm_content=social-post-generator
Это 96 дополнительных символов! Хотя многие соц. сети хорошо с этим справляются. Например, в VK такие ссылки ограничены одной строкой. А в Twitter и LinkedIn есть свой укорачиватель. Но вот Телеграм так не умеет.
Тем не менее, помимо постов есть еще и ссылки на сайт в профилях соц. сетей. В ВК, например, у меня целых 3 места, ведущих на главную страницу. И эти длиннющие ссылки немного пугают и уродливо выглядят. Короче, задача в следующем: сделать эти ссылки простыми и эстетичными.
Я уже давно пользуюсь сервисами, которые делают из монстров конфетку. Вот например Bitly неплохо с этим справляется. Вот что он сделал со ссылкой, которую я указал ранее:
https://bit.ly/vtvz-tg-post-generator
Уже гораздо лучше.
НО! Теперь эта ссылка не ведет на мой сайт. Она ведет на bit.ly, который уже кидает куда надо. Проблема ли это? Для меня да. Мой сайт – моя визитная карточка, которая должна явно указывать, кому она принадлежит. Так что, это отметается сразу.
А почему бы самому не укорачивать ссылки и публиковать уже их? Это решает проблему выше, но создает еще несколько.
Вывод: тоже отбрасываем.
Я уверен, что этот метод использовался ранее, и что я изобрел велосипед. Но результат, по-моему, получился просто невероятным. Принцип работы в следующем:
Вместе со ссылкой передается один единственный query параметр, на основании его в url страницы применяются все необходимые utm метки. Все это должно произойти ДО инициализации инструментов аналитики.
Выглядит это следующим образом:
https://vtvz.me/blog/social-post-generator/?utm=tg
https://vtvz.me/blog/social-post-generator/
?utm_source=_telegram
&utm_medium=social-post
&utm_campaign=blog
&utm_content=social-post-generator
В итоге удалось упаковать 96 символов в 7! Вот как это работает…
Предупреждение!
Весь дальнейший код написан на версии JavaScript, который поддерживается не всеми браузерами. Для совместимости со старыми версиями я использую webpack + babel. Но примеры достаточно просты, чтобы транспилировать их в классический JS.
Наш код должен работать следующим образом:
utm
параметр из query адреса;utm
;Выглядит это так:
У нас есть карта стратегий обработки. Это объект, в ключах которого возможные utm сокращения, а в значении – функция, которая генерирует все необходимые метки.
const strategies = {
'tg': (url) => {
const [collection, slug] = url.pathname.split('/').filter(_ => _);
const data = {
source: '_telegram',
medium: 'social-post'
}
collection && (data.campaign = collection);
slug && (data.content = slug);
return data;
}
};
В этом случае функция получает текущий адрес, на основании которого строит кампанию и контент. Эта магия применима в моем случае. В вашем может быть что-то другое.
Теперь нужна функция, которая сделает всю остальную работу:
/**
* @param {Window} w
* @param {Document} d
*/
const utmResolver = (w, d) => { // В качестве параметров передаются window и document
// 1. Парсим ссылку и вытягиваем utm параметр
const url = new URL(w.location.toString());
const utm = url.searchParams.get('utm');
if (null === utm || '' === utm) {
return;
}
// В случае отсутствия стратегии просто ничего не делаем
let strategy = strategies[utm];
if (undefined === strategy) {
return;
}
// 2. Генерируем значения меток
const {
source,
medium,
campaign,
content,
} = strategy(url);
// 3. Удаляем utm
url.searchParams.delete('utm');
// 4. Применяем параметры
url.searchParams.append('utm_source', source);
url.searchParams.append('utm_medium', medium);
url.searchParams.append('utm_campaign', campaign);
content && url.searchParams.append('utm_content', content);
// 5. Обновляем URL
w.history
? w.history.replaceState({}, d.title, url.toString())
: w.location.replace(url.toString());
}
Нам остается только вызвать эту функцию:
utmResolver(window, document);
Напоминание!
Напомню, что это должно произойти ДО инициализации сборщиков статистики в синхронном потоке! Нарушение этих правил может привести и приведет к искажению результатов.
Благодаря этому ссылки стали куда лаконичнее, чем изначально. Выбранный мною способ не является единственно верным. Есть несколько альтернатив, как передать стратегию:
vtvz.me/.../?u=tg
vtvz.me/.../?_=tg
vtvz.me/.../?=tg
vtvz.me/.../?tg
vtvz.me/.../#tg
Ничто не мешает вам модифицировать приведенный выше скрипт под свои нужды.
Мне не удалось протестировать это дело в больших масштабах, но текущие данные показывают правдивые результаты. Так или иначе, если что-то пойдет не так – я сообщу.
А пока, спасибо за внимание :grin: Если возникают вопросы, не стесняйтесь задавать их мне по любому доступному каналу, пока комментарии не появились :fox:
]]>Это второй по счету интерактивный пост, призванный упростить мне жизнь. Но в этом случае этот инструмент не будет полезен никому, кроме как мне. И здесь сделано все так, чтобы создание постов для социальных сетей было тривиальным действием. Если вдруг кто-то хочет себе что-то подобное – обращайтесь :blush:
Фичи этого генератора:
В целом, получилось достаточно мощно. Это значительно упростит мне жизнь.
Если интересно, то вот, можно потыкать:
]]>С самого начала он был дружелюбен. Было пару раз, что он кусался. Но это было давно и неправда. В целом, его можно было взять на руки в любое время. Иногда мы его пугали – не всегда он был готов к контакту с нами. Но, несмотря на это, он не кусался и не царапался.
Он был дружелюбен не только к нам. Возможно, это общее свойство хомяков – доверять либо никому, либо всем, – но не было ни одного случая агрессии по отношению к другим людям и животным. Он чувствовал себя спокойно на руках любого. Мы пытались подружить его и Джейсона (кота), но он все таки мышь, а кот – охотник. Так что с ними не заладилось. Возможно, спустя какое-то время можно было попробовать еще раз, но мы рисковать не стали.
Он был активным и любопытным. Его невозможно было сфотографировать. По ночам он бегал по колесу, чем-то шуршал в своем домике, носился по этажам своей уютной клетки. Чтобы было теплее, мы давали ему кусочки мягкой туалетной бумаги, которые он с удовольствием брал и упихивал в свое жилище. Интересно то, что он всегда знал, что с ней делать. Стоило ему дать бумажку, он сразу утолкает ее за щеку и потащит в свою конуру.
Со временем он стал реагировать на наш голос. Иногда, когда мы его звали, он высовывал свой носик из будки и выходил к нам, чтобы его взяли на ручки. Бывало, он сам просился – забирался на клетку и просовывал свой носик между прутьями, крепко держась лапками за них.
Иногда, когда он был в руках, мы давали ему какую-то вкусняшку, типа яблока. Чаще всего он ухомячивал её за щеку. Но иногда он кушал прямо на руках, что выглядело очень мило. Бывало, что я усаживал его в кармашек на своей футболке. Один раз он там уснул. Был случай, когда он сначала набил щеки зернами в клетке, я положил в карман, а он выложил всю свою еду прям там.
Он прожил хорошую, счастливую хомячью жизнь, в тепле, любви и уюте. У него всегда была еда, вода и чистота в клетке. Мы никогда не давали ему то, что могло навредить, но старались всегда делиться с ним фруктами и овощами, которые можно. Он никогда не падал – мы были с ним аккуратны.
Но хомяки живут недолго. Чаще всего они умирают в возрасте 1-2 года. Наш оказался долгожителем – 2 года и 9 месяцев. Но и его время уже прошло. Под старость лет своих он стал немного странно вести себя. Он старался ухомячить любую ткань, с которой соприкасался, чего раньше не было. Также он перестал спать в домике – там оставалась только голова, а все остальное было снаружи. Он и до этого был серым, но поседел еще больше.
22 апреля 2020 года мы обнаружили его в своей клетке, лежащим на боку у выхода из домика мордочкой наружу. Мы подумали, что он мертв, но он продолжал дышать. У него случались такие-то приступы, когда он начинал сильно дергать передними лапами, вытягивая их вперед. Его рот двигался произвольно, иногда открывался, а иногда он как-будто что-то жевал. Ему определенно было плохо. Он умирал буквально у нас на руках. Мы думали, что он уйдет сам или ему станет лучше.
Но был вечер. А потом настало утро. Но он все был жив, но совершенно нежизнеспособен. Ему все еще было плохо. Он ничего не ел и не пил. Поэтому было решено отвезти к ветеринару. Возможно, благодаря карантину нам удалось пробиться к Бокаревым, где нас смогли принять буквально сразу. Его состояние уже было неисправимо. Если я правильно понял врача, у него было кровоизлияние в мозг. Но сердце его было крепким, благодаря чему он и жил так долго. На вопрос, было ли ему плохо, чувствовал ли он боль. Она сказала, что он был в коматозе и ничего не чувствовал. Если бы я был ветеринаром, то говорил бы то же самое. Но мне проще верить, что это действительно так. В итоге, его пришлось усыпить. Он ушел 11:10 23 апреля 2020 года.
Я хотел, чтобы он умер при нас, чтобы была возможность с ним попрощаться. И мы были рядом, когда ему стало плохо, и когда его не стало…
Похоронили мы его в этот же день вечером. Мы выкопали ему ямку, насыпали древесный наполнитель, поставили его деревянный домик, в котором он жил, сверху и положили его туда. Я хотел отдать ему должное за ту радость и счастье, которые он нам подарил, и похоронить его достойным образом.
Несмотря на то, что я знал, что он скоро умрет, я все равно не был к этому готов. Мне очень сложно принять его смерть и то, что его больше нет. Я разбит и расстроен. В доме стало немного пусто, и мне нужно к этому привыкнуть.
Мы любили его. Я любил его. А он любил нас. Покойся с миром, мой дорогой друг…
]]>Поэтому, я делаю то, что не заставляет меня слишком много думать и не требует полной сосредоточенности. Я улучшаю творение рук моих. Удивительно то, что, несмотря на простую концепцию, всегда есть куда улучшаться. Именно об этом будет этот пост.
Начну с фундаментальных вещей. На сайте появился полноценный раздел, который я решил назвать “Коллекциями”. Сначала были одни достижения – мои успехи в личной и профессиональной жизни. И выглядел он очень даже неплохо. Каждое достижение – это отдельная карточка, в которой собраны ссылки и материалы, использованные мной.
Ко всему этому туда были добавлены заметки и закладки. Первые – для записи коротких мыслей на свободные темы. Вторые – для сохранения ссылок на интересные и полезные материалы. Опять же, чтобы не плодить десяток разделов с несколькими записями в каждом, все эти коллекции были упакованы в один с общей лентой, посты которых отмечены соответствующей иконкой.
В мыслях есть создать еще два раздела: программы и книги. Думаю, названия говорят сами за себя. Мне есть чем поделиться.
Тем не менее, если хочется увидеть что-то одно, например заметки, то их можно отфильтровать в столбце справа, а на мобильных устройствах – в самом низу (я думаю над тем, как сделать это лучше). Фильтр по категориям и тегам тоже скоро будет (наверное).
Особенно мне нравится градиент в самом верху карточек. Искать картинку для каждой записи мне не хотелось. Но оставлять пост без какого-либо цвета очень скучно и некрасиво. На текущий момент доступно 22 градиента(ов), которые выбираются псевдослучайно (в зависимости от количества символов в записи)
У вас тоже есть возможность поучаствовать в улучшении моего сайта:
Очередное глобальное изменение. Это, конечно, не так впечатляет, как новый раздел с коллекциями. Но этот маленький аттрибут очень много значит для любого сайта. По иконке встречают, как говорится. Старый значок служил мне верой и правдой долгих 5 лет, если не больше, и он останется в моём сердце и истории git навсегда :heart:
Конечно, я выбрал лису – у меня фон с лисой и логотип с лисой. Люблю я лис :fox: Пока что я взял Emoji от Apple, сделал ее черно-белой и немного добавил яркости. Надеюсь меня не засудят за нарушение авторских прав :no_mouth: Возможно, я нарисую что-то более уникальное. Но я не художник и не дизайнер. Если хочется помочь мне в это деле – пожалуйста. Мне будет очень приятно :blush:
На страницах блога в правой колонке есть два блока: комментарии и теги.
Некоторые считают, что это лишнее и создаёт информационный шум. Частично я с этим согласен. Но люди достаточно часто переходят по этим ссылкам.
Чтобы это выглядело более презентабельно, я внес пару косметических улучшений:
Это очень незначительное изменение, но в разы улучшает моё резюме, особенно при печати. Я прижал звездочки в скиллах вправо, что сделало табличку в разы лучше.
Несколько других мелочей:
Если у вас есть какие-то идеи, напишите мне. Мне важна любая обратная связь. Также можете предложить темы статей, которые хотите, чтобы я осветил.
Спасибо за внимание :fox:
]]>У каждого из этих проектов, помимо продового, есть еще 1-3 окружения для тестирования. И вот вам, как DevOps инженеру прилетает следующая задача: нужно для каждого тестового окружения добавить robots.txt файл, который будет запрещать поисковикам индексацию.
Есть несколько способов, как это сделать, но я нашел самый простой и оптимальный.
Конечно, можно заставить всех бекендеров добавить этот файл в каждый проект, но это сложный подход, который DevOps инженер не контролирует. Поэтому мы пойдем по другому пути.
Решение очень зависит от используемых вами технологий. У нас используются следущие:
Каждый из этих инструментов вносит свои улучшения в решение этой задачи.
Если у вас используется чистый Kubernetes без установленного Nginx Ingress, то у вас есть 2 пути.
Вы можете взять самый легкий чистый образ с Nginx,
куда с помощью ConfigMap примонтировать как конфиг сервера,
так и содержимое файла robots.txt
.
После этого достаточно только настроить Ingress на то, чтобы он все запросы на /robots.txt
направлял в этот контейнер.
Примеры конфигов приводить не буду, так как есть вариант получше.
Второе, еще более простое решение, это взять wikiwi/robots-disallow образ в Docker Hub. Принцип работы абсолютно такой же, только теперь не придется ничего настраивать. Только Ingress.
Если вы еще не установили его себе в кластер, то я вам настоятельно рекомендую это сделать. Это мощный инструмент, который умеет делать все, что умеет Nginx, но имеет такой же подход к использованию, как и все сущности в Kubernetes.
Вы только посмотрите на количество параметров, которые можно настроить через аннотации или конфиг мапы.
В общем, этим мы и воспользуемся, чтобы решить поставленную задачу. Достаточно добавить в Ingress приложения следующие строки:
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/server-snippet: |
location = /robots.txt {
add_header Content-Type text/plain;
return 200 'User-agent: *\nDisallow: /\n';
}
Да, Nginx умеет не только выдавать статику или проксировать запросы. Он может генерировать ответ самостоятельно.
Строка return 200 'Content'
именно это и делает.
Таким образом, мы решили задачу буквально в 5 строк.
В этой ситуации Helm не делает ничего особенного, но позволяет переиспользовать один манифест в разных окружениях. В простейшем его использовании, Helm по своей сути является шаблонизатором для конфигов Kubernetes.
Поэтому можно сделать так:
{{- if ne .Values.env "production" }}
nginx.ingress.kubernetes.io/server-snippet: |
location = /robots.txt {
add_header Content-Type text/plain;
return 200 'User-agent: *\nDisallow: /\n';
}
{{- end }}
То есть если окружение не продовое, запрещаем поисковикам индексирование.
Либо так, если хочется большей власти:
{{- if .Values.disallowRobots }}
nginx.ingress.kubernetes.io/server-snippet: |
location = /robots.txt {
add_header Content-Type text/plain;
return 200 'User-agent: *\nDisallow: /\n';
}
{{- end }}
Пользуйтесь на здоровье :fox:
]]>Именно поэтому я решил вынести подобные статьи в отдельную категорию с нумерацией. Как настоящий программист я должен был начать отсчет с нуля. Но формально, нулевой пост уже был.
Думаю, теперь я всё буду писать в блог. Я не умею писать маленькие посты. Каждый пост в социальных сетях больше похож на сочинение или целую повесть, чем на короткую историю. Пусть это будет даже небольшая заметка. Но для меня куда важнее улучшать и продвигать свой блог, чем профили в соц. сетях. Пусть это даже не так эффективно.
Прежде, чем приступить к повествованию, хочу сделать небольшой анонс. 26 марта в 19:00 я буду выступать с публичным докладом, где расскажу про свою работу, мою роль в компании и используемые инструменты.
Для этого нужно зарегистрироваться по этой ссылке:
Регистрация на встречу IT Networking #6
Приходите, будет интересно :fox:
А теперь к обновлениям. Что было сделано:
Спасибо Дмитрию Белову за замечательное фото, которое я, конечно же, добавил в свое резюме. Ведь любое резюме должно иметь фотографию. Самым сложным было заставить картинку хорошо смотреться на всех устройствах. До сей поры не уверен, что она хорошо отображается на узкоэкранных девайсах.
Пока это не пригодилось, но вполне может наступить такой момент, что потенциальный работодатель захочет не онлайн версию резюме, а PDF файлик на почту. Перспектива верстать страницы в каком-нибудь LibreOffice Writer мне вообще не улыбается по одной простой причине: придется поддерживать актуальную информацию сразу в двух местах, из-за чего может произойти рассинхрон. Но есть один простой и очевидный способ сделать из странички сайта PDF – “распечатать” его. Bootstrap из коробки предоставляет стили для печати. Но как уродливо он это делает! Пришлось столкнуться с двумя проблемами:
!important
столько, сколько не делал этого за всю свою жизнь.
Например, он отключает фон всем элементам страницы, выкрашивает весь текст в черный цвет,
а ссылкам a[href]
справа добавляет содержимое href
в скобках.
Выглядит это примерно так:Тем не менее, я его победил и результатом очень даже доволен. Единственная проблема, которая осталась, и которую я, вероятно, решать не буду – нормально печатать может только Chrome, и то с несколькими донастройками: выключенные колонтитулы и включенный фон. Firefox в этом плане очень проигрывает. Как минимум потому, что у него нет preview текста перед печатью (или я просто не нашел).
Вот вам небольшая подсказка. Если вам тоже нужно отдебажить то, как будет выглядеть сайт для печати, сделайте следующее:
Ctrl+Shift+I
;1
;2
;3
;4
.В итоге вам все равно придется проверять, как будет выглядеть документ на листе, используя реальный режим печати Ctrl+P
,
потому что, как я говорил ранее, верстка при итоговой печати отличается от отображаемого в браузере.
Но этого должно быть достаточно, чтобы разобраться с цветами, шрифтами и отступами.
Ну и последняя супер мелочь. Обратите внимание на индикатор загрузки страницы. Теперь он навороченный :grin:. Взял я его тут. Там есть много впечатляющих примеров, но этот мне понравился своей относительной простотой.
Также он был вынесен в отдельный файл со стилями. Это критично для устройств с медленным интернетом. Пока в коде сайта всё еще много мусора, поэтому загружается он немного дольше желаемого. Но индикатор должен отобразиться как можно раньше.
У меня есть идея, сделать на сайте раздел достижений, прям как в играх – иметь историю моих побед прямо тут. Туда я мог бы складывать не только сухую информацию о факте победы над проблемой, но и полезные материалы, которые я нарыл во время решения задач :fox:
]]>Поэтому я выдвинул инициативу взять на себя обязанности “завхоза”, менеджера по закупке провизии в офис. За полтора года работы в Axmit я успел набраться опыта в этом деле и хочу поделиться с вами.
Эта статья рассказывает о том, где в Петрозаводске можно закупаться провизией для своих ребят.
Это не рекламный пост!
Даже если так может показаться. У меня не такая большая аудитория, чтобы ко мне приходили за рекламой. Все описанное здесь – мой опыт и находки. Делюсь с вами тем, что нашел для себя полезным.
Самое очевидное место, где можно покупать продукты – это магазины. Всякие там Пятерочки, Магниты, Ленты, Сигмы и п.р. Несмотря на доступные альтернативные варианты, в магазинах порой бывают очень хорошие скидки. Например, не так давно я купил коробку (8 упаковок по 12 печенек в каждой) оригинального Orion ChocoPie по ~110 рублей. Бывало и дешевле. Но это оригинальный ChocoPie, который, следовательно, стоит ощутимо дороже другого.
Один из магазинов, который хочется выделить, это FixPrice. Там не оригинальный ChocoPie продается по 55 рублей за упаковку 6 шт. в каждой. Да, он не такой вкусный, но это хорошая альтернатива с хорошим соотношением цены и качества.
В одно время я покупал по 60 упаковок по 20 каждого вида. Очень рассчитывал, что всем надоест. Но нет, не надоело.
Есть еще “Светофор”. Стоит тоже посмотреть в его сторону, тем у кого есть машина. У меня ее нет. Поэтому для меня этот вариант однозначно отпадает.
Не могу сказать, что Ozon очень выгодный магазин. Лично я в нем в офис ничего не заказывал.
Но начальство там закупает кофе Lavazza, который по их словам там гораздо выгоднее, чем, скажем, когда-то в Спаре.
Я думаю, что прежде, чем что-то покупать в больших количествах где-либо, стоит посмотреть цены в Озоне. Ведь как в других магазинах, там бывают очень неплохие скидки.
Есть такой замечательный интернет-магазин и по совместительству производитель KDV. Они работают в 91 городе и сотрудничают не только с юридическими лицами и крупными магазинами, но и обычными физ. лицами, как мы.
Условия доставки очень простые: достаточно набрать товара на 300 рублей, и продовольствие будет доставлено прямо в офис или домой.
Из того, что я там заказывал:
В общем, очень хороший магазин, вкусная продукция и выгодные цены. Советую всем посмотреть.
Со временем я стал задумываться о том, что все это как-то вредно (не полезно, как минимум). Поэтому начал смотреть в сторону чуть более правильного питания и полезных сладостей.
Первый интернет магазин, с которым я познакомился – Хрум-Хрум. О нем мне рассказал мой коллега.
Из недостатков хочется отметить, что стоимость продукции указывается не за какую-то весовую единицу (кг), а за упаковку, в которой может быть любое количество грамм. Это очень искажает восприятие и анализ реальной стоимости продукта.
В итоге, в этом магазине я заказывал единожды. Этого было достаточно, чтобы убедиться в том, что я точно не буду укладываться в выделенный мне месячный бюджет.
Этот магазин очень популярен среди эко-активистов, так как они продают продукцию исключительно в свою тару, либо в биоразлагаемые бумажные пакеты, многоразовые пластиковые контейнеры или стеклянную тару.
Почти все, что у них есть, продается на развес. С ассортиментом можно ознакомиться в группе в ВК. Советую посмотреть, хотя бы для расширения кругозора. Там продаются некоторые вещи, которые я никогда до этого не видел.
Мне там нравится покупать гранолу и печеньки. Наташа (моя жена) очень любит тамошний зефир. Иногда еще мы берем сливочный сыр и сушеные бананы.
В этом магазине я также заказывал только один раз. Там все гораздо дешевле, а цены прозрачнее. Для обычных потребителей это очень удобный магазин, позволяющий купить ровно столько, сколько нужно.
Из недостатков хочется отметить то, что там работает ооочееень мееедлееенныыый персонал. Если в обычном магазине покупка вам обойдется в 5 минут, тот тут уйдут все 15. И это в том случае, если там нет очереди. Но если перед вами есть хоть один человек… Короче, если у вас не много времени, лучше просто развернуться и уйти.
Герой этой статьи – магазин Ecogreen. Стоит сказать сразу, что почти весь товар продается пакетами минимум пол кило, а бесплатная доставка осуществляется от 2т. рублей. Это значит, что обычному потребителю не очень-то и удобно закупаться в этом магазине. Но для массовых закупок в офис, чтобы прокормить ~20 человек это самый оптимальный вариант.
Также открывается возможность покупать товары для себя вместе с тем, что закупается в офис.
Для ребят в офис я покупаю:
По началу ребята уничтожали двухнедельный запас менее чем за 1.5 недели, а оставшиеся несколько дней пили пустой кофе/чай. Но сейчас, вероятно, организм получил все необходимые витамины, и скорость съедания припасов приубавилась.
Для себя домой я иногда беру:
Обязательно изучите ассортимент в этом магазине. Конечно, не у каждого есть возможность единоразово выложить 2 тысячи рублей сразу. Но, во-первых, не обязательно закупаться одному – уговорите друга/соседа/родственника и закажите вместе. А во-вторых, продаваемый там товар обычно долгого срока хранения. Может быть есть смысл закупаться в начале месяца и потом постепенно уничтожать припасы.
В итоге, мне удалось уложиться в выделенный мне месячный бюджет и перевести весь наш офис на полезные сладости. Опрос показал, что большинство за отказ от сладкого. Но есть и те, кто “готов есть ChocoPie всю оставшуюся жизнь”. Но им придется кушать хорошую пищу :grin:
От себя скажу, что переход на орешки и финики помог уйти от непомерного употребления сладостей и уменьшить объемы съедаемых каллорий. Орехами и финиками быстро наедаешься, тогда как я мог съедать всю упаковку чокопаек в качестве завтрака.
Я прекрасно понимаю, что орехи – это дорого. Но почему бы не провести эксперимент. Один месяц покупать обычные сладости: печеньки, конфеты, и т.п. А потом – орехи и сухофрукты. Сначала дайте полезностям фору – позвольте организму пару недель наесться. А потом посчитайте, сколько денег уйдет на то и другое. И тогда делайте выводы – стоит ли оно того (стоит) :fox:
]]>