Русский
Русский
English
Статистика
Реклама

Virtualbox

VirtualBox Запуск Android эмулятора в виртуальной среде для тестирования Android проекта

19.12.2020 00:19:44 | Автор: admin

Введение

В данной статье я постараюсь описать пример инфраструктуры для автотестов Android приложений (mobile automation), а именно, среду для проведения тестранов UI автотестов на эмуляторе Android девайса в виртуальной среде.

Требования:

Для Android эмулятора нужна поддержка Intel Virtualization Technology или AMD Virtualization. Поэтому часто тестировщик сталкивается с необходимостью запуска тестранов только в нативной среде ПК с прямым доступом к центральному процессору.

В этом случае схема получается такая:

Трудности:

  1. Невозможно легко пересоздать среду эмулятора.

  2. Среда не создаётся перед проведением тестирования, и после проведения не удаляется, поэтому среда может влиять на тестируемое приложение.

  3. Починка и настройка среды занимает много времени.

Предлагаемое решение в данной статье:

  1. Создать VM с использованием возможностей nested virtualization VirtualBox (более подробное описание технологии в этой статье).

  2. Пробросить поддержку Intel-VT или KVM внутрь созданной виртуальной машины.

  3. Изнутри VM создать и запустить Android эмулятор девайса.

  4. Провести тестран UI тестов приложения.

  5. После проведения тестирования уничтожить VM.

В этом случае схема получится такая:

Предполагаемые преимущества:

  1. VM можно автоматически создавать перед проведением тестирования, а после окончания уничтожать. В таком случае каждый новый тестран будет проведен в идеально чистых условиях.

  2. Уменьшится время поддержки среды и управляющего ПО, так как не нужно каждый раз руками ничего устанавливать и чинить неисправности инвайронмента.

В настоящей статье будет использоваться оборудование:

  • процеcсор: Intel i5-1035G1

  • память: 12Gb

  • в BIOS включена поддержка виртуализации процессора

  • OC: Ubuntu 20.4

Шаг 1: Установка ПО на нативную OS

Отдельно обращу внимание на управление машиной. Будем использовать протокол VNC для создания удобного удаленного рабочего стола. Протокол универсальный, для Linux, Windows, Mac и т.д.

x11vnc сервер

Установка:

sudo apt-get update #обновляем пакетыsudo apt install x11vnc #устанавливаем x11vncsudo x11vnc -storepasswd <вводим пароль сервера> /etc/x11vnc.pass #создаём пароль в файликеsudo chmod ugo+r /etc/x11vnc.pass #разрешаем использовать файлик с паролем

Запуск с параметрами:

x11vnc -nevershared -forever -dontdisconnect -many -noxfixes -rfbauth /etc/x11vnc.pass

Установка VirtualBox

Вводим в командной строке:

sudo apt-get updatesudo apt install gcc make linux-headers-$(uname -r) dkmswget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -sudo sh -c 'echo "deb http://download.virtualbox.org/virtualbox/debian $(lsb_release -sc) contrib" >> /etc/apt/sources.list.d/virtualbox.list'sudo apt update #обновляем репозиторийsudo apt install virtualbox-6.1

Создание VM

Мы пойдем по самому простому пути и создадим VM из интерфейса VirtualBox с такими характеристиками. В дальнейшем создание VM будет code-first

  • Количество CPU - не больше половины имеющихся на Вашем процессоре (в идеале половина)

  • Оперативная память - будет достаточно 4Gb

Nested Virtualization можно также включить из командной строки:

VBoxManage modifyvm <Имя VM> --nested-hw-virt on

Далее переходим в саму VM.

Шаг 2: Установка ПО на VM

В первый раз мы установим всё руками. В дальнейшем весь установочный сценарий будет помещен в Packer, что позволит нам создавать VM с нужными настройками каждый раз перед началом тестирования.

Устанавливаем последний образ Ubuntu с официального сайта.

Установка KVM

egrep -c '(vmx|svm)' /proc/cpuinfo #Если в результате будет возвращено 0 - значит Ваш процессор не поддерживает аппаратной виртуализации, если 1 или больше - то вы можете использовать KVM на своей машинеsudo apt-get update #Обновляем пакетыsudo apt install qemu qemu-kvm libvirt-daemon libvirt-clients bridge-utils virt-manager #Установка KVM и сопроводительные либыsudo usermod -G libvirt -a ubuntu #Добавление пользователя ubuntu в группу libvirtsudo systemctl status libvirtd #Проверка запуска сервиса libvirtsudo kvm-ok #Проверка статуса KVM

Установка Android command line tools

sudo apt-get update #обновляем пакетыyes | sudo apt install android-sdk #устанавливаем Android SDKsudo apt install unzip #Устанавливаем unzip для распаковки архивовcd ~/Downloads #переходим в каталог Downloadswget https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip #скачиваем архив с command line tools с официального сайта Googlesudo unzip commandlinetools-linux-6858069_latest.zip -d /usr/lib/android-sdk/cmdline-tools/ #распаковываемsudo mv /usr/lib/android-sdk/cmdline-tools/cmdline-tools /usr/lib/android-sdk/cmdline-tools/tools #переименовываем каталог с тулами. Сейчас странная ситуация, Google раздаёт тулу с одним каталогом, а SDK ищет его в другом каталогеexport ANDROID_SDK_ROOT=/usr/lib/android-sdk #регистируем переменнуюexport PATH=$PATH:$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/cmdline-tools/tools/bin #регистрируем новый Pathexport PATH=$PATH:$ANDROID_SDK_ROOT/emulator #регистируем новый Path

Проверяем, что sdkmanager работает и Android SDK доступен:

sdkmanager --version

Устанавливаем Android tools

yes | sdkmanager --licenses #принимаем лицензииsudo chown $USER:$USER $ANDROID_SDK_ROOT -R #Ставим для текущего юзера право менять содержимое папки с ANDROID_SDK_ROOTyes | sdkmanager "cmdline-tools;latest" #устанавливаем cmdline-toolssdkmanager "build-tools;30.0.3" #Устанавливаем build-toolssdkmanager "platform-tools" #Устанавливаем platform-toolssdkmanager "platforms;android-30"sdkmanager "sources;android-30"sdkmanager "emulator" #Устанавливаем AVD manageremulator -accel-check #Проверяем, есть ли поддержка виртуализацииyes | sdkmanager "system-images;android-23;google_apis;x86_64" #Устанавливаем образ для эмулятораsdkmanager --list #Выводим список установленных пакетов. Обычно для CI оставляю.no | avdmanager create avd -n android-23_google_apis_x86_64 -k "system-images;android-23;google_apis;x86_64" #создаём эмулятор из образаemulator -list-avds #проверяем наличие созданного эмулятора

Устанавливаем Git и клонируем проект

В данном примере я использую пустой проект мобильного Android приложения. В нём уже есть дефолтный интеграционный тест. Нам этого будет вполне достаточно.

sudo apt update #обновляем пакетыyes | sudo apt install git #установка Gitgit --version #проверка установкиmkdir ~/workspace #создаём каталог для проектовcd ~/workspace #переходим в каталог для проектовgit clone https://github.com/panarik/AndroidClearApp.git #клонируем проект на локалcd ~/workspace/AndroidClearApp #переходим в каталог проекта

Шаг 3: Проведение тестирования проекта на созданном Android эмуляторе

./gradlew assembleDebug --no-daemon #билдим APKemulator -avd android-23_google_apis_x86_64 -no-audio -no-window -verbose -gpu off -accel off #запускаем эмулятор из ранее созданныхsleep 240 #аналог будильника, ждём четыре минуты пока загрузится эмуляторadb get-state #проверяем, видит ли ADB запущенный эмулятор. Если нет, то ждем еще

ADB видит подключенный к нему эмулятор:

Запускаем тестран:

./gradlew connectedAndroidTest --no-daemon

Ура! Тест пройден!

Негативный тест

Чтобы убедится, в том что именно позволило нам сбилдить тесты, мы сделаем один негативный тест и воспроизведем запуск эмулятора в обычной VM.

Подготовка:

  • Переустановка VirtualBox на родительской машине (чтобы избежать ошибочное сохранение конфигов)

sudo apt purge virtualbox-6.1
  • VM мы создаём без проброса виртуализации и с одним CPU:

  • В созданной VM мы не устанавливаем:

    • VBoxClient

    • KVM

Остальные шаги аналогичны шагу 2 с установкой ПО. Попробуем еще раз наш тестран. Обратите внимание, что ADB также видит эмулятор:

Ура! Тест не пройден! Никогда еще так не радовался проваленному тестрану:

Падает PackageManager, как и обычно при запуске из виртуальной среды без аппаратной поддержки процессора:

Заключение

Мы сделали первый этап построения инфраструктуры для проведения автотестов Android приложений. Следующим этапом должно стать упаковка описанного выше сценария в Packer (ссылка на официальный сайт) который умеет работать с образами VirtualBox. Затем весь сценарий мы попробуем запустить из CI Jenkins. Если учесть, что плагин для него уже порядком устарел, то будет очень интересно.

Все результаты опубликую, как пополнения к этой статье.

В идеале, у нас должна получится code-first инфраструктура для тестрана UI и интеграционных автотестов для Android приложений, которую можно поднять на любом современном офисном ПК, которая работает автономно, билдит тесты на родных Android эмуляторах и есть не просит.

Спасибо большое за внимание!

П.С.

Можно Вас в комментариях попросить привести пример Вашей инфраструктуры с использованием Android эмулятора? К примеру, эмуляторы в докер-контейнерах (https://github.com/budtmo/docker-android) может быть еще какие-нибудь интересные примеры.

Подробнее..

Мой маленький Kubernetes настраиваем тестовый кластер в VirtualBox

28.11.2020 14:04:43 | Автор: admin

За последние пару лет мне довольно часто приходилось сталкиваться с Kubernetes, однако обычно это всегда происходило с позиции разработчика. Посмотреть список подов, их статусы, логи и т.п. В общем, ничего сложного.

Недавно я решил заняться изучением Kubernetes чуть глубже, чтобы лучше понимать, как он работает и что умет. Но тут возникла очевидная проблема: нужна какая-то песочница, в которой можно было бы экспериментировать, не боясь при этом что-то сломать, а ещё лучше иметь возможность в любой момент откатиться назад.

Обычно изучение Kubernetes стоит начинать с minikube - консольной утилиты, которая умеет быстро создавать кластер из одного узла с использованием VirtualBox. Это самый лучший вариант для быстрого старта.

Но есть и другой вариант. Можно взять VirtualBox, создать несколько виртуальных машин, например, с Ubuntu Server и настроить небольшой кластер Kubernetes прямо на своём домашнем компьютере.

Я решил пойти по второму пути, но по ходу настройки начал сталкиваться с различными проблемами, решение которых было для меня не так очевидно, как хотелось бы. Вообще в интернете можно найти достаточно много статей на английском языке, где описан процесс настройки, но, к сожалению, ни одна из них не была для меня достаточно полной. Пришлось собирать информацию по кусочкам из разных источников.

Здесь я решил собрать всё вместе и описать процесс настройки небольшого кластера Kubernetes с использованием VirtualBox настолько подробно, насколько мне самому хотелось бы его видеть. Надеюсь, что эта информация сможет помочь другим разработчикам в их экспериментах.

Осторожно, трафик! В статье очень много скриншотов.

Подготовка

Итак, в этой статье мы, используя VirtualBox, шаг за шагом настроим кластер Kubernetes, состоящий из трёх виртуальных машин c Ubuntu Server 20.04. В качестве хоста я использовал компьютер с Windows 10 Home. В процессе настройки нам понадобятся:

  • VirtualBox 6.1.16 и VirtualBox 6.1.16 Extension Pack. Скачать их можно здесь.

  • Установочный образ Ubuntu Server 20.04. Скачать его можно здесь.

  • Утилита kubectl для управления кластером. Инструкции по установке можно найти здесь.

Дисклаймер

Вообще, обычно я пишу на .NET и не занимаюсь подобной настройкой, поэтому не исключаю, что все описанные ниже шаги хоть и работают, но могут быть сделаны не совсем грамотно. Если я где-то ошибся или вообще написал полную ерунду - смело пишите об этом в комментариях =)

Отключаем Hyper-V

Первым делом, если на вашем компьютере установлены Docker или Windows Subsystem for Linux (WLS), то скорее всего включен Hyper-V. VirtualBox не будет с ним работать, а при попытке запустить виртуальную машину будет выдавать ошибку вроде этой:

Поэтому первым делом Hyper-V нужно отключить. Для этого открываем командную строку от имени администратора и вводим команду:

bcdedit /set hypervisorlaunchtype off

Чтобы включить его обратно вводим команду:

bcdedit /set hypervisorlaunchtype auto

Перезагружаем компьютер, чтобы изменения вступили в силу.

Устанавливаем VirtualBox

Далее нам необходимо установить VirtualBox и VirtualBox Extension Pack. Последний понадобится нам чуть позже, когда мы будем настраивать общие папки между хостом и виртуальными машинами. После установки в меню File Preferences Extensions можно перейти в настройки и убедиться, что Extension Pack установлен:

Настраиваем сетевой адаптер

В VirtualBox каждая виртуальная машина может иметь до четырёх сетевых адаптеров, а каждый такой адаптер имеет определённый режим работы, такой как NAT, NAT Network, Bridged, Host-only и т.п. В основном эти режимы отвечают за то, как виртуальные машины будут взаимодействовать с хостом и между собой, а также будет ли у них доступ в интернет и смогут ли другие устройства в сети хоста взаимодействовать с этими виртуальными машинами. Если хотите лучше разобраться как работают эти режимы, рекомендую почитать здесь и тут (по второй ссылке есть картинки, которые неплохо всё это иллюстрируют).

Нам потребуются два адаптера с режимами NAT и Host-only.

NAT адаптер позволяет виртуальным машинам получать доступ в интернет через хост, но не позволяет им взаимодействовать друг с другом (хотя это позволяет NAT Network). Но самое главное, что в этом режиме наши виртуальные машины будут получать IP адрес динамически, поэтому мы не сможем использовать такие адреса для настройки кластера.

Host-only адаптер создаёт одну общую сеть между хостом и всеми виртуальными машинами, а также позволяет назначить каждой из них статический IP адрес, что отлично подходит для настройки кластера. Однако такой режим требует создания на хосте виртуального сетевого адаптера. VirtualBox создаёт такой виртуальный адаптер при установке, и вы можете найти его в меню File Host Network Manager...:

Прежде всего необходимо убедиться для для адаптера выключен режим DHCP Server, чтобы IP адреса не назначались виртуальным машинам автоматически, как это происходит с NAT.

Поле IPv4 Address задаёт IP адрес хоста. Виртуальным машинам мы сможем назначать адрес из той же подсети, которая задаётся полем IPv4 Network Mask. Например, если в данном случае IP хоста 192.168.92.1, а маска подсети 255.255.255.0, то мы сможем назначить виртуальным машинам адреса 192.168.92.2, 192.168.92.10, 192.168.92.42 и т.п.

Стоит отметить, что VirtualBox генерирует адрес хоста случайно и у вас он может отличаться. Я не очень люблю запоминать случайные цифры, поэтому рекомендую изменить адрес хоста на что-то более запоминающееся, я использовал 192.168.10.1:

(На всякий случай напишу, что адрес 192.168.1.1 лучше не использовать, т.к. он обычно используется всякими Wi-Fi роутерами и это может привести к конфликтам и неработающему интернету)

После изменения адреса сетевого адаптера необходимо обязательно перезагрузить компьютер, т.к. без этого виртуальные машины не будут запускаться.

Создаём шаблонную виртуальную машину

Все виртуальные машины, которые мы будем создавать будут немного отличаться настройками, однако большая часть настроек у них будет одинаковая. Чтобы не делать все эти настройки по нескольку раз мы создадим одну шаблонную виртуальную машину, а затем просто клонируем её нужное количество раз и донастроим.

Создаём новую виртуальную машину Kube Template:

Увеличиваем количество памяти хотя бы до 2Гб:

Далее все настройки идут по умолчанию. Создаём для виртуальной машины новый виртуальный жёсткий диск в формате VDI (VirtualBox Disk Image), динамическим выделением места и размером 10Гб:

И получаем нашу новую виртуальную машину:

Но это ещё не всё. Эту виртуальную машину необходимо донастроить. Для этого идём в Machine Settings... System Processor и увеличиваем количество процессоров как минимум до 2, иначе Kubernetes откажется на ней запускаться:

Далее переходим на вкладку Network и проверяем, что первым сетевым адаптером является адаптер с режимом NAT:

Переключаемся на второй сетевой адаптер (он скорее всего выключен), включаем его и переключаем в режим Host-only и выбираем виртуальный сетевой адаптер, который мы ранее настроили (он там будет один):

Сохраняем, и на этом настройка нашей шаблонной виртуальной машины завершена. Можно переходить к установке Ubuntu Server.

Устанавливаем Ubuntu Server

Запускаем нашу шаблонную виртуальную машину. При первом старте VirtualBox предложит выбрать установочный диск. Выбираем iso файл для Ubuntu Server 20.04 и начинаем установку:

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

Но дойдя до настроек сетевых подключений останавливаемся:

Здесь мы видим, что у нашей виртуальной машины два сетевых адаптера, первый из которых уже получил свой IP адрес динамически, а вот второй - нет. Выбираем второй сетевой адаптер и вручную указываем его настройки:

Здесь мы указываем подсеть и статический IP адрес нашей виртуальной машины в этой подсети. Напомню, что IP адрес хоста у нас 192.168.10.1. Остальные параметры можно опустить.

После этого оба сетевых адаптера должны иметь свой собственный IP адрес:

Далее оставляем все настройки по умолчанию, пока не дойдём до настроек профиля. Я назвал машину kube-template, а в качестве username/password использовал test/test:

На следующем шаге нам будет предложено установить OpenSSH server. Я рекомендую воспользоваться этой возможностью, чтобы в будущем иметь возможность подключаться к виртуальным машинам по SSH с помощью PuTTY и Multi PuTTY Manager. Я не стал описывать это в статье, чтобы ещё больше не увеличивать объём:

(Следующий шаг с установкой дополнительных функций пропускаем.)

И наконец запускается сама установка. Теперь мы смело можем сходить пообедать или принять душ, т.к. процесс может занять некоторое время:

После того, как установка завершится, выбираем перезагрузку виртуальной машины (если при этом увидите ошибки об отсутствии cdrom, просто нажмите любую клавишу):

Проверяем настройки сети

После перезагрузки желательно проверить, что сеть между хостом и виртуальной машиной нормально работает, а виртуальная машина имеет доступ в интернет:

Запускаем командную строку на хосте и пингуем виртуальную машину по статическому IP адресу:

Переключаемся в интерфейс виртуальной машины и делаем тоже самое:

И там же проверяем, что виртуальная машина имеет доступ в интернет:

curl https://ya.ru

Если всё работает, то можно переходить к настройке виртуальной машины. В этот момент можно сделать snapshot, чтобы в случае чего не выполнять установку заново.

Устанавливаем mc

Я не очень люблю работать с командной строкой, особенно когда нужно найти и отредактировать какой-нибудь файл. Поэтому первым делам устанавливаем mc:

sudo apt-get updatesudo apt-get install -y mcsudo mc
Если не знакомы с mc, то тут есть список хоткеев, которые нам понадобятся.
  • F3 - Посмотреть содержимое файла

  • F4 - Редактировать содержимое файла. При первом редактировании обычно предлагает выбрать редактор, выбирайте mcedit (3).

    • F2 - Cохранить изменения в файле.

  • F5 - Скопировать файл из левой панели в правую.

  • F8 - Удалить файл.

  • CTRL+O - Скрыть панели.

Отключаем swap

Kubernetes откажется запускаться, если на виртуальной машине включен swap, поэтому его надо отключить.

Проверить, что swap включен или выключен можно командой:

cat /proc/swaps

Если файлы есть, то swap включен, поэтому переходим в папку /etc, ищем там файл fstab и открываем его на редактирование. У меня это выглядит следующим образом:

Закомментируем (или просто удалим) последнюю строку (в которой упоминается файл /swap.img), сохраним файл и перезагрузим виртуальную машину командой:

shutdown -r now

После перезагрузки также удалим файл /swap.img:

Настраиваем общие папки между хостом и виртуальной машиной

Далее нам необходимо установить Docker и Kubernetes, но тут возникает проблема. Для установки нам нужно ввести достаточно длинные команды, которые можно найти на официальных сайтах. Только вот взять и скопировать и вставить их мы не сможем, т.к. буфер обмена между хостом и виртуальной машиной не работает.

Вместо этого, чтобы не вводить все команды вручную, мы создадим между хостом и виртуальной машиной общую папку, скопируем команды для установки в файл из этой папки, а потом выполним этот файл как скрипт в виртуальной машине.

Я честно признаюсь, что это решение я взял отсюда.

Для начала выключаем виртуальную машину (иначе общая папка будет временной и не сохранится при перезагрузке) командой:

shutdown now

Открываем настройки виртуальной машины и переходим на вкладку Shared Folders. Там указываем расположение общей папки на хосте, а также её название в виртуальной машине:

Сохраняем изменения и снова включаем виртуальную машину.

После загрузки сначала подключаем специальный CD диск содержащий VirtualBox Guest Additions, который будет доступен благодаря тому, что мы установили VirtualBox Extension Pack. Найти его можно в меню виртуальной машины Devices Insert Guest Additions CD image:

После нам необходимо выполнить серию команд. Сначала монтируем CD:

sudo mkdir /media/cdromsudo mount -t iso9660 /dev/cdrom /media/cdrom

Затем устанавливаем зависимости, которые понадобятся нам для скрипта установки:

sudo apt-get updatesudo apt-get install -y build-essential linux-headers-`uname -r`

И наконец запускаем скрипт установки:

sudo /media/cdrom/VBoxLinuxAdditions.run

После установки перезагружаем виртуальную машину:

shutdown -r now

После перезагрузки сначала создаём нашу общую папку в домашнем каталоге пользователя:

mkdir ~/shared

Поскольку у меня пользователь называется test, то полный путь к этой папке будет /home/test/shared.

Далее снова запускам mc и идём редактировать уже знакомый нам файл /etc/fstab. Необходимо добавить туда следующую строчку (Вместо <username> используйте имя пользователя, в моём случае это test):

shared /home/<username>/shared vboxsf defaults 0 0

У меня это выглядит следующим образом:

Также нам необходимо отредактировать файл /etc/modules, добавив туда строчку:

vboxsf

У меня это выглядит следующим образом:

И снова перезагружаемся:

shutdown -r now

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

Затем переключаемся на виртуальную машину, заходим в папку ~/shared и убеждаемся, что файл появился:

Устанавливаем Docker и Kubernetes

Для начала установим Docker. Полные инструкции по установке можно найти здесь, но фактически нам нужно просто выполнить следующий скрипт (пока не выполняем его):

#!/usr/bin/env bashsudo apt-get updatesudo apt-get install -y \    apt-transport-https \    ca-certificates \    curl \    gnupg-agent \    software-properties-commoncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -sudo add-apt-repository \    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \    $(lsb_release -cs) \    stable"sudo apt-get updatesudo apt-get install -y docker-ce docker-ce-cli containerd.io

С Kubernetes история аналогичная. Инструкции по установке можно найти тут, но нам нам достаточно будет следующего скрипта:

#!/usr/bin/env bashsudo apt-get updatesudo apt-get install -y \    apt-transport-https \    curlcurl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.listdeb https://apt.kubernetes.io/ kubernetes-xenial mainEOFsudo apt-get updatesudo apt-get install -y kubelet kubeadm kubectl

Можно конечно просто последовательно ввести все эти команды, но мы воспользуемся общей папкой, которую настроили ранее. Создадим в ней на хосте два файла: install-docker.sh и install-kubernetes.sh, а затем скопируем туда содержимое скриптов.

При сохранении обязательно убедитесь, что переносы строк имеют формат LF, а не CRLF.

Теперь переходим в общую папку на виртуальной машине, находим наши скрипты и запускаем их, сначала устанавливая Docker, а затем Kubernetes:

Изменяем cgroup driver для Docker и Kubernetes на systemd

В Linux есть такой механизм, называемый Control Groups (или просто cgroups), который используется для ограничения ресурсов, выделяемых процессам. При запуске Docker и Kubernetes мы можем указать для каждого из них драйвер cgroups, который будет использоваться: cgroupfs или systemd. При этом важно, чтобы и Docker и Kubernetes использовали один и тот же драйвер.

В различных источниках рекомендуется перейти именно на драйвер systemd, как на более современный. Если этого не сделать, Kubernetes при старте может выводить предупреждения.

Для начала сделаем это для Docker. Для этого перейдём в папку /etc/docker и создадим в ней файл daemon.json со следующим содержимым:

{  "exec-opts": ["native.cgroupdriver=systemd"]}

Должно получиться так:

Для изменения драйвера в Kubernetes отредактируем файл /etc/systemd/system/kubelet.service.d/10-kubeadm.conf. Найдём последнюю строку:

ExecStart=/usr/bin/kubelet <тут много всяких параметров>

И добавим в конец этой строки ещё один параметр --cgroup-driver=systemd. Должно получиться следующее:

Сохранив оба файла, выключаем виртуальную машину:

shutdown now

Клонируем виртуальные машины

Мы закончили настройку нашей шаблонной виртуальной машины. Пришло время сделать из неё узлы нашего кластера. Для этого открываем контекстное меню и выбираем Clone...:

Назовём наши новые виртуальные машины: Kube Master, Kube Node1 и Kube Node2.

При клонировании обязательно измените поле MAC AddressPolicy на Generate new MAC address for all network adapters.

В итоге получим следующее:

Изменяем hostname и IP адреса виртуальных машин

Теперь нам необходимо сделать так, чтобы каждая виртуальная машина имела свой уникальный hostname и IP адрес.

Сначала запустим виртуальную машину Kube Master и сделаем изменения на ней.

Для начала изменим hostname. Это делается простой командой:

sudo hostnamectl set-hostname kube-master

Настройки IP адреса в Ubuntu Server 20.04 хранятся в файле /etc/netplan/00-installer-config.yaml. Откроем этот файл и поменяем IP адрес на 192.198.10.10:

После сохранения изменений их необходимо применить командой:

sudo netplan apply

Проверить, что изменения hostname и IP адреса успешно применились можно командой:

hostname && hostname -I

Но это ещё не всё. Когда Kubernetes (а если быть точным, то kubelet) будет запускаться на узле, он в качестве IP узла будет использовать IP адрес сетевого адаптера по умолчанию, а это NAT с динамическими адресами, который нам не подходит.

Чтобы использовать статический IP адрес, который мы указали, отредактируем файл /etc/systemd/system/kubelet.service.d/10-kubeadm.conf. Ранее, мы уже добавили в него параметр --cgroup-driver=systemd. Теперь добавим ещё один: --node-ip=192.168.10.10:

Сохраняем изменения, выключаем виртуальную машину и повторяем эти изменения для двух остальных машин.

Для машины Kube Node1 укажем имя хоста kube-node1 и IP адрес 192.168.10.11.

Для машины Kube Node2 укажем имя хоста kube-node2 и IP адрес 192.168.10.12.

Настраиваем кластер

Теперь у нас всё готово и можем наконец приступить к настройке кластера.

Для начала нам нужно инициализировать master узел следующей командой:

sudo kubeadm init \--apiserver-advertise-address=192.168.10.10 \  --pod-network-cidr=10.10.0.0/16 > ~/shared/kubeadm-join.sh

Здесь нам обязательно необходимо указать два параметра.

Параметр --apiserver-advertise-address отвечает за то, по какому IP адресу будет доступен apiserver. Без него будет использоваться IP адрес сетевого адаптера по умолчанию, которым является NAT, и мы не сможем присоединить узлы к master узлу. Нам нужно использовать значение 192.168.10.10.

Параметр --pod-network-cidr указывает подсеть, в которой подам будут выделяться виртуальные IP адреса внутри кластера. Главное, чтобы эта подсеть не пересекалась с другими подсетями, используемыми виртуальными машинами. Я использовал значение 10.10.0.0/16.

В результате выполнения этой команды произойдёт настройка master узла, а в output будет выведена команда kubeadm join ... для присоединения к кластеру. Чтобы сохранить эту команду и использовать её на двух других узлах, мы записываем весь вывод в файл в общей папке.

Инициализация может занять несколько минут, но после того как она завершится, мы можем перейти в общую папку и найти там там файл kubeadm-join.sh:

В самом конце файла мы найдём нужную нам команду. Удалим весь остальной текст и сохраним файл:

Теперь последовательно зайдём на виртуальные машины Kube Node1 и Kube Node2, перейдём в общую папку и выполним скрипт kubeadm-join.sh:

Подключаемся к кластеру с хоста

Мы только что создали кластер Kubernetes из трёх узлов. Теперь нам необходимо как-то подключиться к нему с хоста. Для этого нам потребуется файл admin.conf из папки /etc/kubernetes, который можно найти на master узле.

Сначала копируем admin.conf в общую папку и заодно переименовываем его в config:

sudo cp /etc/kubernetes/admin.conf ~/shared/config

После этого уже на хосте копируем файл config в папку %UserProfile%/.kube.

Запускаем на хосте командную строку и проверяем доступность кластера командой:

kubectl get nodes -o wide

Настраиваем сетевой плагин

На последнем скриншоте мы видим, что у нас в кластере три узла, но все они в статусе NotReady.

Также, если мы попробуем получить список подов, то увидим, что некоторые поды не запускаются, а остаются в статусе Pending:

kubectl get pods -A

Причина в том, что Kubernetes имеет абстрактную модель работы с сетью, а конкретная её реализация определяется сетевыми плагинами, такими как Flannel или Calico. Подробнее почитать про сравнение разных плагинов можно тут.

Мы установим Flannel (т.к. по описанию он самый простой).

Зайдя на страницу проекта на GitHub видим, что для настройки плагина достаточно выполнить команду:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Не делаем этого, т.к. это не будет работать. Вместо этого скачиваем файл kube-flannel.yml себе на рабочий стол.

Открываем файл и находим там следующий кусок:

  net-conf.json: |    {      "Network": "10.244.0.0/16",      "Backend": {        "Type": "vxlan"      }    }

Заменяем значение 10.244.0.0 на 10.10.0.0. Это то значение, которое мы передавали в команду kubectl init.

Сохраняем изменения и вот теперь уже устанавливаем Flannel командой:

kubectl apply -f .\Desktop\kube-flannel.yml

Теперь, если мы посмотрим список подов, то увидим, что там появились поды Flannel. Все поды через некоторое время перейдут в состояние Running и кластер будет готов к использованию.

Узлы также перейдут в состояние Ready:

Теперь наш кластер готов к использованию.

Заключение

На этом у меня всё. Статья получилась несколько больше, чем я ожидал, поэтому я не стал описывать шаги с проверкой кластера и созданием тестовых объектов в нём.

Надеюсь, что данный материал будет полезен разработчикам, которые захотят настроить себе тестовый кластер для изучения Kubernetes.

Подробнее..

Сравнение производительности систем виртуализации на macOS

24.11.2020 04:23:42 | Автор: admin
Привет, Хабр! Думаю, никто не будет отрицать, что виртуальные машины незаменимая в хозяйстве вещь. Ведь это значительно удобнее, чем ставить множество ОС на свой компьютер. Или я вот, например, был бы и рад debian себе поставить на ноутбук рядом с macOS, да под макбуки с драйверами там большие проблемы. И вот, когда у меня сломался ПК, на котором были винда с линуксом, я собрался настраивать виртуалки у себя на ноутбуке. А так как хочется комфортно работать в виртуальной системе, то в первую очередь я обращал внимание на производительность. Самым простым способом было попробовать всё самим, что я и сделал, и вот делюсь результатами.

Для тестирования взял последние стабильные версии трёх самых популярных решений VMware Fusion Pro 12.1.0 (17195230), Parallels Desktop 16.1.1 (49141) и Oracle VirtualBox 6.1.16 (r140961). VirtualBox бесплатный и open-source (GPL v2), Fusion и Parallels я тестировал в trial версии, потому что я бедный студент, у которого нет денег. У Fusion Pro есть 30 дней пробной версии, а у Fusion Player бесплатная лицензия для персонального использования, для получения которой надо зарегистрироваться и немного подождать (мне выдали license key за где-то за сутки). Parallels только платный (14 дней триала), из-за чего для меня он был вне конкурса, но есть 50% скидка для студентов.

Во всех трёх тестируется один и тот же дистрибутив Debian 10.6.0 amd64, просто потому что у меня был уже скачан iso образ, с практически одинаковыми настройками при установке (немного отличается разбиение диска), в качестве среды рабочего стола везде выбрал Xfce. В качестве бенчмарков взял первые попавшиеся для linux sysbench (cpu, memory и io тесты) и indigo benchmark (cpu тест). Для всех виртуалок во всех системах были выставлены одинаковые настройки: 2GB оперативной памяти, 2 ядра процессора, 64MB видеопамяти. Тесты так же проведены в нативной macOS (для сравнения).

Всё тестировалось на MacBook Pro 13" 2017-го года с Core i5 на 2.3 GHz, ось macOS Big Sur Beta (20A5364e).

Отдельное замечание по поводу VirtualBox. После установки надо в настройках безопасности подтвердить, что мы доверяем расширениям ядра от Oracle, о чём установщик, в отличие от установщиков Fusion и Parallels, не предупреждает, а лишь говорит, что нужно перезагрузиться. После перезагрузки для этого подтверждения уже надо будет переустанавливать заново VirtualBox, потому что запрос на подтверждение пропадёт из настроек macOS (почему Apple не хранит их в отдельном разделе настроек безопасности?), но мне и это не помогло, и VirtualBox заработал лишь после сброса настроек SIP (sudo csrutil clear). В общем, потребовалось немного танцев с бубном.

Итак, вот результаты (полный вывод бенчмарков тут):

VMware Fusion Parallels Desktop Oracle VirtualBox macOS (host)
sysbench CPU (1 поток), events per second 1.2K 1.2K 1.2K 3607.9K
sysbench CPU (2 потока), events per second 2.4K 2.4K 2.4K 6111.5K
sysbench RAM, MiB/sec transferred 5411.45 4287.38 4863.09 2658.28
sysbench I/O, written MiB/sec 948.55 89.13 33.77 429.31
Indigo Bedroom, CPU, M samples/s 0.202 0.202 0.202 0.313
Indigo Supercar, CPU, M samples/s 0.514 0.502 0.496 0.787


Как видно, в синтетических тестах CPU наши виртуалки сильно отстают от оригинальной системы (что логично), но между собой отличаются незначительно. Интересно, что во всех трёх виртуальных машинах тест памяти значительно опережает тесты в macOS. С чем это связано гадать не буду, надеюсь не с разницей в linux и macOS версиях бенчмарка. Если кто-то знает или предполагает причину, объясните мне, пожалуйста, в комментариях. Точно так же любопытно, как Fusion обогнал macOS с тестами диска, но тут я ещё потестирую, так как скорость записи хорошо влияет на производительность, и тесты диска хорошо подвержены случайным факторам.

Что касается субъективного впечатления, parallels и vmware мне показались шустрее. К тому же при установке системы в VirtualBox курсор в один прекрасный момент завис и мне пришлось доустанавливать всё с клавиатуры, после ребута виртуалки пофиксилось. А в VMware система у меня начинает подтормаживать при включённой поддержке 3D ускорения, почему так я, опять же, не знаю.

В заключение скажу, что тесты, конечно, не точные и далеко не полные. Я взял первые попавшиеся бенчмарки и не тестировал, например, GPU. Тесты делал я в первую очередь для себя за один вечер, но решил поделиться с общественностью, думаю есть те, кому пригодится. Если кто-то проведёт более полные и качественные тесты производительности буду рад. Я же лично остановлюсь на Fusion Player, потому что он бесплатный, удобный для меня, к тому же у меня уже был приятный опыт использования VMWare Workstation на windows и не очень приятный с VirtualBox там же.
Подробнее..

Основы Bash-скриптинга для непрограммистов

24.01.2021 20:20:26 | Автор: admin

Статья рассчитана на тех, кто не имеет или имеет мало опыта работы с командной строкой Unix/Linux, но желает научиться с ней эффективно взаимодействовать и разрабатывать скрипты для выполнения своих задач. Приведенные примеры справедливы для выполнения в командной оболочке bash операционной системы Ubuntu/Debian, но могут быть использованы и в других оболочках и ОС с учетом их специфики.

1. Командные оболочки

Существует множество дистрибутивов(форков) операционных систем(ОС) семейства Linux, наиболее известные среди них: Ubuntu, Debian, CentOS, Red Hat, Fedora, SuSE, FreeBSD, Mint.

Здесь есть большая схема со всеми форками Linux.

В каждой ОС существуют различные командные оболочки (shell), их назначение одинаково (администрирование, автоматизация, вычисления, мониторинг и т.д.), как и большинство основных команд, но реализация может отличаться. В таблице ниже приведено сравнение, в котором видно, что некоторые возможности поддерживаются не всеми оболочками.

Feature

Bourne

C

TC

Korn

Bash

Псевдонимы (синонимы)

Нет

Да

Да

Да

Да

Редактор командной строки

Нет

Нет

Да

Да

Да

Расширенные шаблоны файлов

Нет

Нет

Нет

Да

Да

Автозавершение имени файла

Нет

Да

Да

Да

Да

Стеки директорий (pushd and popd)

Нет

Да

Да

Нет

Да

История

Нет

Да

Да

Да

Да

Функции

Да

Нет

Нет

Да

Да

Горячие клавиши

Нет

Нет

Да

Нет

Да

Управление заданиями

Нет

Да

Да

Да

Да

Исправление ошибок в командах

Нет

Нет

Да

Нет

Да

Формат приглашения командной строки

Нет

Нет

Да

Нет

Да

Список доступных командных оболочек можно получить командой

cat /etc/shells

При необходимости можно установить нужную командную оболочку командой sudo apt install <имя_оболочки>. Например, для установки ksh нужно выполнить

sudo apt install ksh

2. Настройка тестовой среды

Если у вас уже есть виртуальная/реальная машина с установленным Linux, или вы знаете, как её настроить, то можно пропустить информацию из спойлера ниже. Если есть доступ по ssh к какому-либо серверу, то Вы также можете использовать его shell для тренировок. Используйте имеющийся доступ с осторожностью, не тренируйтесь на продуктовых(промышленных) серверах и других критичных окружениях. Если вы не хотите развертывать виртуальную машину(ВМ), то для тестов можно воспользоваться онлайн-терминалами, но нужно знать и учитывать их особенности и ограничения. Примеры онлайн-терминалов:
https://cocalc.com/app?anonymous=terminal
https://www.tutorialspoint.com/execute_bash_online.php
https://rextester.com/l/bash_online_compiler

Развертывание виртуальной машины

VirtualBox ПО для виртуализации, позволяющее запускать одну ОС внутри другой. Разумеется, существуют и другие способы развертывания ВМ, здесь мы рассмотрим лишь один из них. В данном случае, предполагается, что у вас ПК под управлением Windows или Mac. Для начала нужно скачать VirtualBox отсюда и установить его.

Также нужно скачать образ ВМ с установленной ОС Ubuntu отсюда. Качайте самую новую версию, убедитесь, что скачиваемый образ имеет формат VirtualBox (VDI).

Создадим виртуальную машину. Сначала создаем на локальном диске папку для размещения в ней ВМ и их файлов (у меня C:\vmachines). Распакуем скачанный образ диска ВМ в созданную папку:

Для распаковки потребуется архиватор 7zip или другой, поддерживающий формат .7z. Далее запускаем VirtualBox и выбираем меню Машина -> Создать:

В открывшемся окне указываем имя ВМ (тип и версия в большинстве случаев подтягиваются автоматически, если это понятно из имени), а также созданную нами папку. Объем оперативной памяти устанавливается автоматически, 1Гб достаточно для выполнения тестов. Выбираем Использовать существующий виртуальный жесткий диск, нажимаем значок выбора образа жесткого диска, в открывшемся окне нажимаем Добавить, выбираем распакованный ранее файл образом ВМ и нажимаем Открыть:

Нажимаем Выбрать:

И нажимаем Создать:

Выбираем в списке созданную ВМ и нажимаем Запустить:

После запуска ВМ появится окно для входа в ОС:

Выбираем учетную запись osboxes.org и вводим пароль osboxes.org. После входа в систему нажимаем Ctrl+Alt+T, у нас откроется окно терминала, в котором можно выполнять тесты:

Для удобства можно развернуть окно виртуальной машины на весь экран, окно терминала также будет развернуто. Для того, чтобы можно было вставлять данные из буфера в терминал ВМ и копировать их, можно включить в настройках ВМ общий буфер обмена в меню Устройства -> Общий буфер обмена -> Двунаправленный:

Создадим тестового пользователя.

Для создания пользователя нам понадобятся права суперпользователя (root). Для их получения выполним команду sudo su -, указав пароль текущего пользователя (osboxes.org). Далее создадим пользователя test командой adduser test. Также выдадим пользователю test права на повышение привилегий при необходимости, выполнив команду usermod -aG sudo test:

osboxes@osboxes:~$ sudo su -[sudo] password for osboxes:root@osboxes:~# adduser testAdding user `test' ...Adding new group `test' (1001) ...Adding new user `test' (1001) with group `test' ...The home directory `/home/test' already exists.  Not copying from `/etc/skel'.New password:Retype new password:passwd: password updated successfullyChanging the user information for testEnter the new value, or press ENTER for the default        Full Name []:        Room Number []:        Work Phone []:        Home Phone []:        Other []:Is the information correct? [Y/n]root@osboxes:~# usermod -aG sudo testroot@osboxes:~#

На данном этапе уже можно использовать тестовую среду, выполняя команды в терминале (Ctrl+Alt+T). Дополнительно можно настроить подключение по ssh клиентом (например, PuTTY), мы рассмотрим это отдельно.

3. Первые команды

Итак, мы подключились к терминалу и находимся в shell. Давайте сориентируемся в пространстве.Чтобы узнать имя машины(сервера), на которой мы находимся, введем hostname и нажмем Enter:

test@osboxes:~$ hostnameosboxes

Имя пользователя, под которым мы подключены, как правило отображается в приглашении командной строки (test@osboxes:~$). Если имя текущего пользователя не отображается (например, если задан другой формат приглашения), то его можно получить командой whoami, или id (также отображает группы пользователя):

test@osboxes:~$ whoamitesttest@osboxes:~$ iduid=1001(test) gid=1001(test) groups=1001(test),27(sudo)

Чтобы узнать, в какой оболочке мы находимся, нужно выполнить команду echo $SHELL:

test@osboxes:~$ echo $SHELL/bin/bash

Разберем, что произошло. Команда echo выводит значение параметра, переданного ей, в нашем случае мы передали $SHELL. Знак $ означает, что мы обращаемся к переменной, т.е. $SHELL возвращает значение переменной SHELL, заданной в окружении. Список значений всех переменных можно получить командой env. Таким образом, отобразив значение переменной, мы видим, что мы находимся в оболочке bash. Оболочка конкретного пользователя указана в файле /etc/passwd, содержимое которого можно получить так:

test@osboxes:~$ cat /etc/passwdroot:x:0:0:root:/root:/bin/bash...test:x:1001:1001:,,,:/home/test:/bin/dash

Команда cat выводит содержимое файла (часть строк в приведенном выводе пропущена и заменена на ). Из файла видим, что для пользователя test указана оболочка /bin/dash. Изменить оболочку текущего пользователя, которая будет загружаться по умолчанию, можно следующей командой(chsh сокращенное от change shell):

test@osboxes:~$ chsh -s /bin/bashPassword:

Теперь давайте проверим, в каком каталоге мы находимся, для этого выполним команду pwd:

test@osboxes:~$ pwd/home/test

Для получения списка файлов текущей директории используем команду ls. По соглашению, скрытые файлы начинаются с точки. Для отображения их с помощью команды ls нужно добавить ключ a. Чтобы отобразить список в расширенном формате, добавим ключ l. Таким образом команда и её вывод будут выглядеть так:

test@osboxes:~$ ls -altotal 36drwxr-xr-x 5 test test 4096 Nov  9 01:05 .drwxr-xr-x 5 root root 4096 Nov  8 11:39 ..-rw------- 1 test test    9 Nov  8 12:28 .bash_history-rw-r--r-- 1 test test  220 Nov  8 11:39 .bash_logout-rw-r--r-- 1 test test 3771 Nov  8 11:39 .bashrcdrwxr-xr-x 4 test test 4096 Nov  8 11:40 .cachedrwxr-xr-x 4 test test 4096 Nov  8 11:40 .configdrwxr-xr-x 3 test test 4096 Nov  8 11:40 .local-rw-r--r-- 1 test test  807 Nov  8 11:39 .profile-rw-r--r-- 1 test test    0 Nov  9 01:05 .sudo_as_admin_successfultest@osboxes:~$

Для команды ls с параметрами может быть задан синоним (alias), что упрощает её ввод. Список уже заданных синонимов можно получить командой alias:

test@osboxes:~$ aliasalias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'alias egrep='egrep --color=auto'alias fgrep='fgrep --color=auto'alias grep='grep --color=auto'alias l='ls -CF'alias la='ls -A'alias ll='ls -alF'alias ls='ls --color=auto'

Видим, что команда ll является синонимом команды ls -alF. Синонимы могут ссылаться на другие синонимы. Так, в приведенном выше примере команда ll выполняет команду ls -alF, в которой ls в свою очередь также является синонимом команды ls --color=auto. Для любой команды с целью упрощения её ввода при частом использовании можно задать синоним. В синонимах также можно использовать переменные среды. Например, чтобы иметь возможность из любой директории получить список файлов домашней директории, можно задать синоним командой alias lshome='ls -alF $HOME', таким образом, можно выполнить:

test@osboxes:~$ cd /tmptest@osboxes:/tmp$ lshometotal 40drwxr-xr-x 5 test test 4096 Nov  9 02:29 ./drwxr-xr-x 5 root root 4096 Nov  8 11:39 ../-rw------- 1 test test   47 Nov  9 02:36 .bash_history-rw-r--r-- 1 test test  220 Nov  8 11:39 .bash_logout-rw-r--r-- 1 test test 3771 Nov  8 11:39 .bashrcdrwxr-xr-x 5 test test 4096 Nov  9 02:29 .cache/drwxr-xr-x 5 test test 4096 Nov  9 02:29 .config/drwxr-xr-x 3 test test 4096 Nov  8 11:40 .local/-rw-r--r-- 1 test test  807 Nov  8 11:39 .profile-rw-rw-r-- 1 test test   72 Nov  9 02:29 .selected_editor-rw-r--r-- 1 test test    0 Nov  9 01:05 .sudo_as_admin_successful

Здесь командой cd /tmp мы перешли в директорию /tmp, и, находясь в ней, выполнили команду lshome, которая вывела список файлов директории /home/test. При этом в синониме мы ссылаемся на переменную $HOME, в которой содержится путь к домашней директории текущего пользователя.

Алиасы задаются в файле ~/.bash_aliases. Тильда (~) означает домашнюю директорию пользователя. В нашем случае /home/test. Также можно задать их в файле ~/.bashrc. Здесь нужно сказать пару слов об этих файлах.

При запуске bash в качестве оболочки, сначала выполняется файлы (в случае их наличия), в которых могут быть заданы различные настройки профиля и выполнены различные действия в процессе входа до появления командной строки: сначала выполняется файл /etc/profile, далее bash последовательно ищет и выполняет первый из найденных файлов в следующем порядке: ~/.bash_profile, ~/.bash_login, ~/.profile. Из указанных файлов могут вызываться и другие.

Так, например, из файла ~./profile вызывается файл ~/.bashrc, из которого, в свою очередь, в числе прочих, вызывается файл .bash_aliases при его наличии. А файл /etc/profile выполняет также все файлы .sh, находящиеся в директории etc/profile.d.

В bash существуют внутренние команды, их список можно получить командой help. Помощь по конкретной внутренней команде можно получить с помощью команды help <имя_команды>, например:

test@osboxes:~$ help pwdpwd: pwd [-LP]    Print the name of the current working directory.    Options:      -L        print the value of $PWD if it names the current working                directory      -P        print the physical directory, without any symbolic links    By default, `pwd' behaves as if `-L' were specified.    Exit Status:    Returns 0 unless an invalid option is given or the current directory    cannot be read.

Некоторые внутренние команды bash дублированы в виде исполняемых файлов. Это сделано, чтобы скрипты можно было корректно выполнять в оболочках, в которых не реализованы эти команды. Например, существует исполняемый файл /usr/bin/echo, который реализует функционал внутренней команды echo. Команда help echo выведет справку по внутренней команде, а команда /usr/bin/echo help выведет справку для соответствующего исполняемого файла. Вывод справки для этих команд отличается, но в целом они реализуют идентичный функционал.

Таким образом, если в оболочке не реализована внутренняя команда echo, скрипт, содержащий вызов echo, сможет успешно выполниться, т.к. для обработки вызова будет использован исполняемый файл /usr/bin/echo. Для поиска выполненных ранее команд можно использовать клавиши Вверх и Вниз, команды из истории можно редактировать и повторно выполнять. В конце статьи приведен список полезных команд.

Если данный материал интересен, то в продолжении статьи я расскажу про скрипты и их параметры, права доступа к файлам, операторы условного выполнения, выбора и циклы, функции и планировщик заданий.

Подробнее..
Категории: *nix , Linux , Unix , Ubuntu , Bash , Bash scripting , Ssh , Virtualbox , Debian , Shells

Основы Bash-скриптинга для непрограммистов. Часть 2

30.01.2021 20:16:42 | Автор: admin

В первой части статьи мы рассмотрели командные оболочки, профили, синонимы и первые команды. Под спойлером я также рассказал, как развернуть тестовую виртуальную машину.

В этой части речь пойдет о файлах скриптов, их параметрах и правах доступа. Также я расскажу про операторы условного выполнения, выбора и циклы.

Скрипты

Для выполнения нескольких команд одним вызовом удобно использовать скрипты. Скрипт это текстовый файл, содержащий команды для shell. Это могут быть как внутренние команды shell, так и вызовы внешних исполняемых файлов.

Как правило, имя файла скрипта имеет окончание .sh, но это не является обязательным требованием и используется лишь для того, чтобы пользователю было удобнее ориентироваться по имени файла. Для интерпретатора более важным является содержимое файла, а также права доступа к нему.

Перейдем в домашнюю директорию командой cd ~ и создадим в ней с помощью редактора nano (nano script.sh)файл, содержащий 2 строки:

#!/bin/bashecho Hello!

Чтобы выйти из редактора nano после набора текста скрипта, нужно нажать Ctrl+X, далее на вопрос "Save modified buffer?" нажать Y, далее на запрос "File Name to Write:" нажать Enter. При желании можно использовать любой другой текстовый редактор.

Скрипт запускается командой ./<имя_файла>, т.е. ./ перед именем файла указывает на то, что нужно выполнить скрипт или исполняемый файл, находящийся в текущей директории. Если выполнить команду script.sh, то будет выдана ошибка, т.к. оболочка будет искать файл в директориях, указанных в переменной среды PATH, а также среди встроенных команд (таких, как, например, pwd):

test@osboxes:~$ script.shscript.sh: command not found

Ошибки не будет, если выполнять скрипт с указанием абсолютного пути, но данный подход является менее универсальным: /home/user/script.sh. Однако на данном этапе при попытке выполнить созданный файл будет выдана ошибка:

test@osboxes:~$ ./script.sh-bash: ./script.sh: Permission denied

Проверим права доступа к файлу:

test@osboxes:~$ ls -l script.sh-rw-rw-r-- 1 test test 22 Nov  9 05:27 script.sh

Из вывода команды ls видно, что отсутствуют права на выполнение. Рассмотрим подробнее на картинке:

Права доступа задаются тремя наборами: для пользователя, которому принадлежит файл; для группы, в которую входит пользователь; и для всех остальных. Здесь r, w и x означают соответственно доступ на чтение, запись и выполнение.

В нашем примере пользователь (test) имеет доступ на чтение и запись, группа также имеет доступ на чтение и запись, все остальные только на чтение. Эти права выданы в соответствии с правами, заданными по умолчанию, которые можно проверить командой umask -S. Изменить права по умолчанию можно, добавив вызов команды umask с нужными параметрами в файл профиля пользователя (файл ~/.profile), либо для всех пользователей в общесистемный профиль (файл /etc/profile).

Для того, чтобы установить права, используется команда chmod <параметры> <имя_файла>. Например, чтобы выдать права на выполнение файла всем пользователям, нужно выполнить команду:

test@osboxes:~$ chmod a+x script.sh

Чтобы выдать права на чтение и выполнение пользователю и группе:

test@osboxes:~$ chmod ug+rx script.sh

Чтобы запретить доступ на запись (изменение содержимого) файла всем:

test@osboxes:~$ chmod a-w script.sh

Также для указания прав можно использовать маску. Например, чтобы разрешить права на чтение, запись, выполнение пользователю, чтение и выполнение группе, и чтение для остальных, нужно выполнить:

test@osboxes:~$ chmod 754 script.sh

Будут выданы права -rwxr-xr--:

test@osboxes:~$ ls -la script.sh-rwxr-xr-- 1 test test 22 Nov  9 05:27 script.sh

Указывая 3 цифры, мы задаем соответствующие маски для каждой из трех групп. Переведя цифру в двоичную систему, можно понять, каким правам она соответствует. Иллюстрация для нашего примера:

Символ перед наборами прав доступа указывает на тип файла ( означает обычный файл, d директория, l ссылка, c символьное устройство, b блочное устройство, и т. д.). Соответствие числа, его двоичного представления и прав доступ можно представить в виде таблицы:

Число

Двоичный вид

Права доступа

0

000

Нет прав

1

001

Только выполнение (x)

2

010

Только запись (w)

3

011

Запись и выполнение (wx)

4

100

Только чтение (r)

5

101

Чтение и выполнение (rx)

6

110

Чтение и запись (rw)

7

111

Чтение, запись и выполнение (rwx)

Выдав права на выполнение, можно выполнить скрипт:

test@osboxes:~$ ./script.shHello!

Первая строка в скрипте содержит текст #!/bin/bash. Пара символов #! называется Шебанг (англ. shebang) и используется для указания интерпретатору, с помощью какой оболочки выполнять указанный скрипт. Это гарантирует корректность исполнения скрипта в нужной оболочке в случае, если у пользователя будет указана другая.

Также в скриптах можно встретить строку #!/bin/sh. Но, как правило, /bin/sh является ссылкой на конкретный shell, и в нашем случае /bin/sh ссылается на /bin/dash, поэтому лучше явно указывать необходимый интерпретатор. Вторая строка содержит команду echo Hello!, результат работы которой мы видим в приведенном выводе.

Параметры скриптов

Для того, чтобы обеспечить некоторую универсальность, существует возможность при вызове передавать скрипту параметры. В этом случае вызов скрипта будет выглядеть так: <имя_скрипта> <параметр1> <параметр2> , например ./script1.sh Moscow Russia.

Для того, чтобы получить значение первого параметра, необходимо в скрипте указать $1, второго - $2, и т.д. Существует также ряд других переменных, значения которых можно использовать в скрипте:
$0 имя скрипта
$# количество переданных параметров
$$ PID(идентификатор) процесса, выполняющего скрипт
$? код завершения предыдущей команды

Создадим файл script1.sh следующего содержания:

#!/bin/bashecho Hello, $USER!printf "Specified City is: %s, Country is: %s\n" $1 $2

Выдадим права на выполнение и выполним скрипт с параметрами:

test@osboxes:~$ chmod u+x script1.shtest@osboxes:~$ ./script1.sh Moscow RussiaHello, test!Specified City is: Moscow, Country is: Russia

Мы передали 2 параметра, указывающие город и страну, и использовали их в скрипте, чтобы сформировать строку, выводимую командой printf. Также для вывода в строке Hello использовали имя пользователя из переменной USER.

Для того, чтобы передать значения параметров, состоящие из нескольких слов (содержащие пробелы), нужно заключить их в кавычки:

test@osboxes:~$ ./script1.sh "San Francisco" "United States"Hello, test!Specified City is: San Francisco, Country is: United States

При этом нужно доработать скрипт, чтобы в команду printf параметры также передавались в кавычках:

printf "Specified City is: %s, Country is: %s\n" "$1" "$2"

Из приведенных примеров видно, что при обращении к переменной для получения её значения используется символ $. Для того, чтобы сохранить значение переменной просто указывается её имя:

COUNTRY=RUSSIAecho $COUNTRY

Операторы условного выполнения, выбора и циклы

Так же, как и в языках программирования, в bash существуют операторы условного выполнения выполнение определенных действий при определенных условиях. Кроме того, существует возможность повторного выполнения определенного блока команд пока выполняется заданное условие операторы цикла. Рассмотрим каждый из них подробнее.

Оператор условного выполнения представляет собой конструкцию вида:

if [ <условие> ]then  <команда1>else  <команда2>fi

Создадим скрипт, проверяющий длину введенной строки (например, для проверки длины пароля), которая должна быть не меньше (т.е. больше) 8 символов:

#!/bin/bashecho Hello, $USER!echo -n "Enter string: "read strif [ ${#str} -lt 8 ]then  echo String is too shortelse  echo String is okfi

Выполним 2 теста, с длиной строки 5 и 8 символов:

test@osboxes:~$ ./script2.shHello, test!Enter string: abcdeString is too shorttest@osboxes:~$ ./script2.shHello, test!Enter string: abcdefghString is ok

Командой read str мы получаем значение, введенное пользователем и сохраняем его в переменную str. С помощью выражения ${#str} мы получаем длину строки в переменной str и сравниваем её с 8. Если длина строки меньше, чем 8 (-lt 8), то выдаем сообщение String is too short, иначе String is ok.

Условия можно комбинировать, например, чтобы указать, чтоб длина должна быть не меньше восьми 8 и не больше 16 символов, для условия некорректных строк нужно использовать выражение [ ${#str} -lt 8 ] || [ ${#str} -gt 16 ]. Здесь || означает логическое "ИЛИ", а для логического "И" в bash используется &&.

Условия также могут быть вложенными:

#!/bin/bashecho Hello, $USER!echo -n "Enter string: "read strif [ ${#str} -lt 8 ]then  echo String is too shortelse  if [ ${#str} -gt 16 ]  then    echo String is too long  else    echo String is ok  fifi

Здесь мы сначала проверяем, что строка меньше 8 символов, отсекая минимальные значения, и выводим "String is too short", если условие выполняется. Если условие не выполняется(строка не меньше 8 символов) - идем дальше(первый else) и проверяем, что строка больше 16 символов. Если условие выполняется - выводим "String is too long", если не выполняется(второй else) - выводим "String is ok".

Результат выполнения тестов:

test@osboxes:~$ ./script2.shHello, test!Enter string: abcdefString is too shorttest@osboxes:~$ ./script2.shHello, test!Enter string: abcdefghijklmnopqrstuvString is too longtest@osboxes:~$ ./script2.shHello, test!Enter string: abcdefghijklString is ok

Оператор выбора выглядит следующим образом:

case "$переменная" in "$значение1" ) <команда1>;; "$значение2" ) <команда2>;;esac

Создадим новый скрипт, который будет выводить количество спутников для указанной планеты:

#!/bin/bashecho -n "Enter the name of planet: "read PLANETecho -n "The $PLANET has "case $PLANET in  Mercury | Venus ) echo -n "no";;  Earth ) echo -n "one";;  Mars ) echo -n "two";;  Jupiter ) echo -n "79";;  *) echo -n "an unknown number of";;esacecho " satellite(s)."

Тест:

test@osboxes:~$ ./script3.shEnter the name of planet: MercuryThe Mercury has no satellite(s).test@osboxes:~$ ./script3.shEnter the name of planet: VenusThe Venus has no satellite(s).test@osboxes:~$ ./script3.shEnter the name of planet: EarthThe Earth has one satellite(s).test@osboxes:~$ ./script3.shEnter the name of planet: MarsThe Mars has two satellite(s).test@osboxes:~$ ./script3.shEnter the name of planet: JupiterThe Jupiter has 79 satellite(s).test@osboxes:~$ ./script3.shEnter the name of planet: Alpha555The Alpha555 has an unknown number of satellite(s).

Здесь в зависимости от введенного названия планеты скрипт выводит количество её спутников.
В case мы использовали выражение Mercury | Venus, где | означает логическое "ИЛИ" (в отличие от if, где используется ||), чтобы выводить "no" для Меркурия и Венеры, не имеющих спутников. В case также можно указывать диапазоны с помощью []. Например, скрипт для проверки принадлежности диапазону введенного символа будет выглядеть так:

#!/bin/bashecho -n "Enter key: "read -n 1 keyechocase "$key" in  [a-z]   ) echo "Lowercase";;  [A-Z]   ) echo "Uppercase";;  [0-9]   ) echo "Digit";;  *       ) echo "Something else";;esac

Мы проверяем символ на принадлежность одному из четырех диапазонов(английские символы в нижнем регистре, английские символы в верхнем регистре, цифры, все остальные символы). Результат теста:

test@osboxes:~$ ./a.shEnter key: tLowercasetest@osboxes:~$ ./a.shEnter key: PUppercasetest@osboxes:~$ ./a.shEnter key: 5Digittest@osboxes:~$ ./a.shEnter key: @Something else

Цикл может задаваться тремя разными способами:

Выполняется в интервале указанных значений (либо указанного множества):

for [ <условие> ] do <команды> done

Выполняется, пока соблюдается условие:

while [ <условие> ] do <команды> done

Выполняется, пока не перестанет соблюдаться условие:

until [ <условие> ] do <команды> done

Добавим в скрипт с планетами цикл с условием while и будем выходить из скрипта, если вместо имени планеты будет введено EXIT

#!/bin/bashPLANET="-"while [ $PLANET != "EXIT" ]do  echo -n "Enter the name of planet: "  read PLANET  if [ $PLANET != "EXIT" ]  then.    echo -n "The $PLANET has "    case $PLANET in      Mercury | Venus ) echo -n "no";;      Earth ) echo -n "one";;      Mars ) echo -n "two";;      Jupiter ) echo -n "79";;      *) echo -n "an unknown number of";;    esac  echo " satellite(s)."  fidone

Здесь мы также добавили условие, при котором оператор выбора будет выполняться только в случае, если введено не EXIT. Таким образом, мы будем запрашивать имя планеты и выводить количество её спутников до тех пор, пока не будет введено EXIT:

test@osboxes:~$ ./script4.shEnter the name of planet: EarthThe Earth has one satellite(s).Enter the name of planet: JupiterThe Jupiter has 79 satellite(s).Enter the name of planet: Planet123The Planet123 has an unknown number of satellite(s).Enter the name of planet: EXIT

Нужно отметить, что условие while [ $PLANET != "EXIT" ] можно заменить на until [ $PLANET == "EXIT" ]. == означает "равно", != означает "не равно".

Приведем пример циклов с указанием интервалов и множеств:

#!/bin/bashrm *.datecho -n "File count: "read countfor (( i=1; i<=$count; i++ ))do  head -c ${i}M </dev/urandom >myfile${i}mb.datdonels -l *.datecho -n "Delete file greater than (mb): "read maxsizefor f in *.datdo  size=$(( $(stat -c %s $f) /1024/1024))  if [ $size -gt $maxsize ]  then.    rm $f    echo Deleted file $f  fidonels -l *.datread

Сначала мы запрашиваем у пользователя количество файлов, которые необходимо сгенерировать (read count).

В первом цикле (for (( i=1; i<=$count; i++ ))) мы генерируем несколько файлов, количество которых задано в переменной count, которую введет пользователь. В команду head передаем количество мегабайт, считываемых из устройства /dev/random, чтение из которого позволяет получать случайные байты.

Символ < указывает перенаправление входного потока (/dev/urandom) для команды head.

Символ > указывает перенаправление выходного потока (вывод команды head -c ${i}M ) в файл, имя которого мы генерируем на основе постоянной строки с добавлением в неё значения переменной цикла (myfile${i}mb.dat).

Далее мы запрашиваем размер, файлы больше которого необходимо удалить.

Во втором цикле (for f in *.dat) мы перебираем все файлы .dat в текущей директории и сравниваем размер каждого файла со значением, введенным пользователем. В случае, если размер файла больше, мы удаляем этот файл.

В конце скрипта выводим список файлов .dat, чтобы отобразить список оставшихся файлов (ls -l *.dat). Результаты теста:

test@osboxes:~$ ./script5.shFile count: 10-rw-rw-r-- 1 test test 10485760 Nov  9 08:48 myfile10mb.dat-rw-rw-r-- 1 test test  1048576 Nov  9 08:48 myfile1mb.dat-rw-rw-r-- 1 test test  2097152 Nov  9 08:48 myfile2mb.dat-rw-rw-r-- 1 test test  3145728 Nov  9 08:48 myfile3mb.dat-rw-rw-r-- 1 test test  4194304 Nov  9 08:48 myfile4mb.dat-rw-rw-r-- 1 test test  5242880 Nov  9 08:48 myfile5mb.dat-rw-rw-r-- 1 test test  6291456 Nov  9 08:48 myfile6mb.dat-rw-rw-r-- 1 test test  7340032 Nov  9 08:48 myfile7mb.dat-rw-rw-r-- 1 test test  8388608 Nov  9 08:48 myfile8mb.dat-rw-rw-r-- 1 test test  9437184 Nov  9 08:48 myfile9mb.datDelete file greater than (mb): 5Deleted file myfile10mb.datDeleted file myfile6mb.datDeleted file myfile7mb.datDeleted file myfile8mb.datDeleted file myfile9mb.dat-rw-rw-r-- 1 test test 1048576 Nov  9 08:48 myfile1mb.dat-rw-rw-r-- 1 test test 2097152 Nov  9 08:48 myfile2mb.dat-rw-rw-r-- 1 test test 3145728 Nov  9 08:48 myfile3mb.dat-rw-rw-r-- 1 test test 4194304 Nov  9 08:48 myfile4mb.dat-rw-rw-r-- 1 test test 5242880 Nov  9 08:48 myfile5mb.dat

Мы создали 10 файлов (myfile1mb.dat .. myfile10mb.dat) размером от 1 до 10 мегабайт и далее удалили все файлы .dat размером больше 5 мегабайт. При этом для каждого удаляемого файла вывели сообщение о его удалении (Deleted file myfile10mb.dat). В конце вывели список оставшихся файлов (myfile1mb.dat .. myfile5mb.dat).

В следующей части мы рассмотрим функции, планировщик заданий cron, а также различные полезные команды.

Подробнее..
Категории: *nix , Linux , Unix , Ubuntu , Bash , Bash scripting , Ssh , Virtualbox , Debian , Shells

Основы Bash-скриптинга для непрограммистов. Часть 3

16.02.2021 20:15:11 | Автор: admin

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

Функции

Часто используемые, повторяющиеся блоки имеет смысл выделять в отдельные функции, чтобы при необходимости их запускать, передавая параметры.

Определение функции выглядит следующим образом:

<имя_функции>() {  <команды>  return <число>}funciton <имя_функции>() {  <команды>  return <число>}

Первый вариант ближе к синтаксису языка С и считается более переносимым, во втором варианте круглые скобки можно не указывать. Также может отсутствовать оператор return, если функция не возвращает значения.

Самый простой пример скрипта, содержащего объявление и вызов функции будет выглядеть так:

#!/bin/bashf() {  echo Test}f

Мы объявили функцию f, которая выводит слово Test, и затем вызвали её:

test@osboxes:~$ ./script6.shTest

Так же, как и скрипт, функция может принимать параметры и использовать их, ссылаясь по номеру ($1, $2, , $N). Вызов функции с параметрами в скрипте осуществляется так:

<имя функции> <параметр1> <параметр2> <параметрN>

Функция может возвращать результат своего выполнения (код завершения) в виде числового значения в диапазоне от 0 до 255. Принято считать, что если функция возвращает 0, то она выполнилась успешно, во всех остальных случаях значение содержит код ошибки. Чтобы получить код завершения функции в скрипте, необходимо обратиться к переменной $?. Добавив параметры и возвращаемое значение, получим следующий скрипт:

#!/bin/bashsumm() {  re='^[0-9]+$'  if ! [[ $1 =~ $re ]] ; then    return 1  elif ! [[ $2 =~ $re ]] ; then    return 2  else    s=$(($1 + $2))    return 0  fi}summ $1 $2case $? in 0) echo "The sum is: $s" ;; 1) echo "var1 is not a nubmer" ;; 2) echo "var2 is not a nubmer" ;; *) echo "Unknown error" ;;esac

Здесь мы создали функцию summ, которая принимает 2 параметра и с помощью регулярного выражения ^[0-9]+$ проверяет, является ли каждый из переданных параметров числом. В случае, если первый параметр не число, то код завершения функции будет 1, если второй параметр не число, то код завершения функции будет 2. Во всех остальных случаях функция вычисляет сумму переданных параметров, сохраняя результат в глобальной переменной s.

Скрипт вызывает функцию, передавая её на вход параметры, которые были переданы ему самому при вызове. Далее проверяется код завершения функции и выдается соответствующая ошибка, если код не равен 0, иначе выдается сумма, сохраненная в переменной s. Протестируем скрипт:

test@osboxes.org:~$ ./script7.sh abc 123var1 is not a nubmertest@osboxes.org:~$ ./script7.sh 234 defvar2 is not a nubmertest@osboxes.org:~$ ./script7.sh 10 15The sum is: 25

По умолчанию переменные объявляются глобальными, т.е. видны в любом блоке скрипта. Переменные, объявленные как локальные, имеют ограниченную область видимости, и видны только в пределах блока, в котором они были объявлены. В случае с функцией это означает, что локальная переменная "видна" только в теле функции, в которой она была объявлена.

Для того, чтобы объявить переменную локальной, используется слово local, например local loc_var=123. Важно отметить, все что переменные, объявляемые в теле функции, считаются необъявленными до тех пор, пока эта функция не будет вызвана.

Объединим все воедино, создав на основе рассмотренных ранее структур следующий скрипт:

#!/bin/bashclearFiles() {  rm *.dat  if [ $? -eq 0 ]  then    echo Files deleted  fi}genFiles() {  for (( i=1; i<=$1; i++ ))  do    head -c ${i}M </dev/urandom >myfile${i}mb.dat  done  ls -l *.dat}delFiles() {for f in *.dat  do    size=$(( $(stat -c %s $f) /1024/1024 ))    if [ $size -gt $1 ]    then      rm $f      echo Deleted file $f    fi  done  ls -l *.dat}showWeather() {  curl -s "https://weather-broker-cdn.api.bbci.co.uk/en/observation/rss/$1" | grep "<desc" | sed -r 's/<description>//g; s/<\/description>//g'}menu() {  clear  echo 1 - Delete all .dat files  echo 2 - Generate .dat files  echo 3 - Delete big .dat files  echo 4 - List all files  echo 5 - Planet info  echo 6 - Show weather  echo "x/q - Exit"  echo -n "Choose action: "  read -n 1 key  echo}while truedo  case "$key" in    "x" | "q" | "X" | "Q") break ;;    "1")      clearFiles      read -n 1    ;;    "2")      echo -n "File count: "      read count      genFiles $count      read -n 1    ;;    "3")      echo -n "Delete file greater than (mb): "      read maxsize      delFiles $maxsize      read -n 1    ;;    "4")      ls -la      read -n 1    ;;    "5")      ./script4.sh      read -n 1    ;;    "6")      echo -n "Enter city code: " # 524901 498817 5391959      read citycode      showWeather $citycode      read -n 1    ;;  esac  menudone

В данном скрипте мы объявили 5 функций:

  • clearFiles

  • genFiles

  • delFiles

  • showWeather

  • menu

Далее реализован бесконечный цикл с помощью оператора while с условием true, в который вложен оператор выбора в зависимости от нажатой клавиши, а также вызов функции menu для отображения списка доступных действий. Данный скрипт в интерактивном режиме позволяет выполнить следующие действия:

  • Удалить все файлы .dat в текущей директории

  • Создать указанное количество файлов

  • Удалить файлы больше определенного размера

  • Вывести список всех файлов текущей директории

  • Запустить скрипт, выдающий информацию о планетах

  • Отобразить погоду по коду указанного города

Не будем подробно разбирать все строки кода, скажем только, что в скрипте демонстрируется вызов другого скрипта, получение информации из интернет, и её парсинг (выделение нужной информации), команда break для выхода из цикла и ряд других возможностей. Предлагаю желающим самостоятельно протестировать скрипт, посмотреть, какие могут быть ошибки при его работе и при вводе различных значений, какие проверки можно добавить, и что можно улучшить. Приведем результаты тестирования:

test@osboxes.org:~$ ./script8.sh1 - Delete all .dat files2 - Generate .dat files3 - Delete big .dat files4 - List all files5 - Planet info6 - Show weatherx/q - ExitChoose action: 4total 40drwxr-xr-x 2 test test 4096 Feb 16 15:56 .drwxr-xr-x 6 root root 4096 Feb 16 15:54 ..-rw------- 1 test test   42 Feb 16 15:55 .bash_history-rw-r--r-- 1 test test  220 Feb 16 15:54 .bash_logout-rw-r--r-- 1 test test 3771 Feb 16 15:54 .bashrc-rw-r--r-- 1 test test  807 Feb 16 15:54 .profile-rw-r--r-- 1 test test 1654 Feb 16 12:40 input.xml-rwxr-xr-x 1 test test  281 Feb 16 14:02 script4.sh-rwxr-xr-x 1 test test  328 Feb 16 13:40 script7.sh-rwxr-xr-x 1 test test 1410 Feb 16 15:24 script8.sh
1 - Delete all .dat files2 - Generate .dat files3 - Delete big .dat files4 - List all files5 - Planet info6 - Show weatherx/q - ExitChoose action: 2File count: 8-rw-rw-r-- 1 test test 1048576 Feb 16 16:00 myfile1mb.dat-rw-rw-r-- 1 test test 2097152 Feb 16 16:00 myfile2mb.dat-rw-rw-r-- 1 test test 3145728 Feb 16 16:00 myfile3mb.dat-rw-rw-r-- 1 test test 4194304 Feb 16 16:00 myfile4mb.dat-rw-rw-r-- 1 test test 5242880 Feb 16 16:00 myfile5mb.dat-rw-rw-r-- 1 test test 6291456 Feb 16 16:00 myfile6mb.dat-rw-rw-r-- 1 test test 7340032 Feb 16 16:00 myfile7mb.dat-rw-rw-r-- 1 test test 8388608 Feb 16 16:00 myfile8mb.dat
1 - Delete all .dat files2 - Generate .dat files3 - Delete big .dat files4 - List all files5 - Planet info6 - Show weatherx/q - ExitChoose action: 3Delete file greater than (mb): 5Deleted file myfile6mb.datDeleted file myfile7mb.datDeleted file myfile8mb.dat-rw-rw-r-- 1 test test 1048576 Feb 16 16:00 myfile1mb.dat-rw-rw-r-- 1 test test 2097152 Feb 16 16:00 myfile2mb.dat-rw-rw-r-- 1 test test 3145728 Feb 16 16:00 myfile3mb.dat-rw-rw-r-- 1 test test 4194304 Feb 16 16:00 myfile4mb.dat-rw-rw-r-- 1 test test 5242880 Feb 16 16:00 myfile5mb.dat
1 - Delete all .dat files2 - Generate .dat files3 - Delete big .dat files4 - List all files5 - Planet info6 - Show weatherx/q - ExitChoose action: 1Files deleted
1 - Delete all .dat files2 - Generate .dat files3 - Delete big .dat files4 - List all files5 - Planet info6 - Show weatherx/q - ExitChoose action: 5Enter the name of planet: MarsThe Mars has two satellite(s).
1 - Delete all .dat files2 - Generate .dat files3 - Delete big .dat files4 - List all files5 - Planet info6 - Show weatherx/q - ExitChoose action: 6Enter city code: 524901    Latest observations for Moscow from BBC Weather, including weather, temperature and wind information      Temperature: -11C (11F), Wind Direction: Northerly, Wind Speed: 0mph, Humidity: 84%, Pressure: 1018mb, , Visibility: Moderate

Примечание: для тестирования работы с данными из Интернет (пункт 6 в меню выбора скрипта) может потребоваться установка curl, это можно сделать командой sudo apt install curl.

Планировщик заданий cron

В случае, когда есть необходимость периодического запуска скриптов, полезно использовать планировщик cron, он позволяет задать расписание запуска скрипта и не требует присутствия администратора.

Просмотр заданий пользователя выполняется командой crontab l. Для редактирования и создания новых задания используется команда crontab e. Строки для запуска команд планировщика в файле конфигурации cron имеют следующий формат:

m h dom mon dow command parameters

Где m минута, h час, dom день месяца, mon месяц, dow день недели, command команда, parameters список параметров. Наглядно этот формат можно представить так:

Например, для того, чтобы в 10 и 30 минут каждого часа каждый день месяца весь год по будням запускать команду, нужно указать следующее:

10,30 * * * 1-5 command parameter1 parameter2

Более простой пример, каждые 15 минут выполнять команду:

*/15 * * * * command

Создадим скрипт для резервного копирования домашней директории пользователя, который будет создавать новый файл бэкапа при каждом запуске:

#!/bin/bashUSER=`whoami`BACKUP_DIR=/tmp/backup_${USER}BACKUP_FILE=${USER}_$(date +%Y%m%d%M%H%S).tgzmkdir -p $BACKUP_DIRcd /tar -zcf $BACKUP_DIR/$BACKUP_FILE home/$USER

Поставим скрипт на выполнение каждый день в 22:00, выполнив команду crontab -eи добавив с помощью открывшегося редактора строку:

00 22 * * * ./backup_home.sh

Проверить, что задача добавлена в планировщик, можно командой crontab -l:

test@osboxes.org:~$ crontab -l00 22 * * * ./backup_home.sh

В результате каждый день в 22:00 будет создаваться резервная копия домашней директории пользователя (в приведенном примере для демонстрации запуск скрипта выполняется каждую минуту):

test@osboxes.org:~$ cd /tmp/backup_test/test@osboxes:/tmp/backup_test$ lltotal 80drwxrwxr-x  2 test test 4096 Feb 16 16:38 ./drwxrwxrwt 17 root root 4096 Feb 16 16:30 ../-rw-rw-r--  1 test test 4431 Feb 16 16:30 test_20210216301601.tgz-rw-rw-r--  1 test test 4431 Feb 16 16:31 test_20210216311601.tgz-rw-rw-r--  1 test test 4431 Feb 16 16:32 test_20210216321601.tgz-rw-rw-r--  1 test test 4431 Feb 16 16:33 test_20210216331601.tgz-rw-rw-r--  1 test test 4431 Feb 16 16:34 test_20210216341601.tgztest@osboxes:/tmp/backup_test$

Нужно отметить, что директория /tmp в примере использована исключительно для тестов, т.к. она предназначена для хранения временных файлов, и использовать её для хранения резервных копий нельзя. Правильное место размещения бэкапов может подсказать системный администратор.

Список полезных команд

Список встроенных команд интерпретатора: help
Помощь по команде: <команда> --help
Мануал по команде: man <команда>
Версия команды: <команда> --version
Список доступных оболочек: cat /etc/shells
Список пользователей и их оболочек: cat /etc/passwd
Текущая директория: pwd
Список файлов текущей директории: ls -la
Текущий пользователь: id
Переменные среды: set
Версия ОС: cat /etc/os-release
Версия ядра: uname -a
Получить привилегии суперпользователя: sudo su -
Установка программы в Debian: apt install mc
Посмотреть утилизацию(загрузку): top
Свободное место: df -h
Сколько занимает директория: du -ks /var/log
Конфигурация сетевых интерфейсов: ifconfig -a
Объем оперативной памяти: free -m
Информация о блочных устройствах(дисках): lsblk
Информация о процессорах: cat /proc/cpuinfo
Список установленных пакетов: apt list --installed
Список и статус сервисов: service --status-all
Перезапуск сервиса: service apache2 restart
Скачать файл: wget https://www.gnu.org/graphics/gplv3-with-text-136x68.png
Получить веб-страницу по URL: curl https://www.google.com
Показать задания планировщика: crontab -l
Редактировать задания планировщика: crontab -e
Вывести новые сообщения в системном логе: tail -f /var/log/syslog
Подсчитать количество строк в выводе команды: <команда> | wc -l
Изменить права доступа к файлу (разрешить выполнение всем): chmod a+x <файл>
Список процессов: ps -ef
Проверить, запущен ли процесс: ps -ef | grep <процесс>
Перейти в предыдущий каталог: cd -
Завершить процесс (сигнал kill): kill -9
Удаление файла: rm <имя файла>
Удаление директории: rm -rf <имя директории>
Редактировать файл: nano <имя_файла>
Топ 10 процессов по использованию памяти: ps aux | awk '{print $6/1024 " MB\t\t" $11}' | sort -nr | head

Полезные ссылки

Руководство по bash: GNU Bash manual
Расширенное руководство по Bash: Advanced Bash-Scripting Guide
Статья на Википедии: Bash
Описание команд и утилит оболочки bash: SS64
Часто задаваемые вопросы о Debian GNU/Linux: Debian FAQ

Заключение

В данной статье мы рассмотрели основы разработки скриптов с использованием bash, изучили базовые структуры, позволяющие реализовывать логику работы скрипта в зависимости от различных условий, познакомились с планировщиком. Bash является очень гибким инструментом, позволяющим реализовать задачи различного уровня сложности. При подключении внешних утилит предоставляет большие возможности для автоматизации.

На этом пока все, надеюсь, было интересно!
Какие другие полезные команды вы знаете и используете в работе?
Какие интересные конструкции приходилось использовать?
Какие задачи решали?
Всем удачного скриптинга, делитесь мнениями в комментариях!

Подробнее..
Категории: *nix , Linux , Unix , Ubuntu , Bash , Bash scripting , Ssh , Virtualbox , Debian , Shells

Ставим Ubuntu из другого LinuxLiveCD

29.03.2021 04:05:11 | Автор: admin

Речь в статье пойдёт об установке Ubuntu из другого Linux без использования ISO-образа. Нужно это прежде всего для создания кастомизированных тестовых окружений. Информации о такой процедуре в интернете достаточно, она легко гуглится, но, как выяснилось, в некоторых моментах существующие инструкции устарели, да, и все они обладают известным фатальным недостатком.

Итак, постановка задачи: есть голая виртуальная машина с выходом в интернет и EFI BIOS, есть некий линукс (в нашем случае это SystemRescue LiveCD), нужно получить установленную Ubuntu. И все действия должны быть легко автоматизированы, что их можно оформить в виде скрипта.

Прежде всего загружаемся в наш SysRCD. Работать мы будем по SSH, и что он заработал, нужно установить пароль root и разрешить SSH в iptables (изначально запрещены любые входящие соединения):

iptables -I INPUT -p tcp --dport 22 -j ACCEPTpasswd

И подключаемся по SSH:

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@192.168.56.110

Теперь нужно подготовить разделы на жёстком диске. Так как система у нас EFI, то таблица разделов будет GPT, нужен EFI FAT-раздел, а сама система будет находится на разделе с ext4-разделе. EFI-раздел может очень небольшим - буквально 10 МБ, но для стабильной работы обновлений системы лучше делать его хотя бы 32 МБ. И важное замечание! Во всех инструкциях написано, что раздел должен быть в формате FAT32, но на практике VirtualBox отказывается работать с EFI-разделом в таком формате! Плюс, есть нюансы с размером диска, размером кластера и совместимостью с EFI биосами. Поэтому форматировать будем в FAT16 - только там удаётся добиться стабильной работы с VirtualBox. Разбивать будем при помощи parted.
Для того, чтобы пометить раздел как служебный EFI в parted ему нужно выставить флаг "esp".

partedunit KiBmktable gptmkpart fat16 1024KiB 32MiBname 1 EFI  set 1 esp onmkpart ext4 32MiB -1sПредложит выравнять - соглашаемся.name 2 LINUXquit

Теперь форматируем вновь созданные разделы. Ещё раз обращаю внимание, что EFI-раздел форматируем в FAT-16, иначе будут проблемы с VirtualBox.

mkfs.fat -F 16 -n EFI /dev/sda1FAT32 не работает!mkfs.ext4 -O ^64bit -L LINUX /dev/sda2

Разворачивать систему будем при помощи утилиты debootstrap. В нашем Linux её нет, поэтому просто скачаем deb-пакет и репозитория Debian и развернём содержимое прямо в наш LiveCD.

mkdir /tmp/1cd /tmp/1wget http://ftp.ru.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.123_all.debar -p *.deb data.tar.gz | tar -xz -C /

Ставить будем Ubuntu 20.04 "Focal" - имя релиза указывается при вызове deboostrap. там же указывается репозиторий, откуда будут скачаны файлы.
Для разворачивания системы, нам естественно, нужно сначала примонтировать её корень в какую-то папку. Не мудрствуя лукаво используем для этого папку "/tmp/".

mkdir /tmp/newrootcd /tmpmount -o relatime /dev/sda2 newroot/usr/sbin/debootstrap --arch=amd64 --include=wget,nano focal /tmp/newroot https://mirror.linux-ia64.org/ubuntu/

Теперь нам нужно настроить список репозиториев, откуда будут браться устанавливаемые и обновляемые пакеты. Список находится в файле /etc/apt/sources.list

( RELEASE=focal ; echo "deb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE} main restricted# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE} main restricteddeb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates main restricted# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates main restricteddeb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE} universe# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE} universedeb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates universe# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates universedeb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE} multiverse# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE} multiversedeb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates multiverse# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-updates multiversedeb http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-backports main restricted universe multiverse# deb-src http://ru.archive.ubuntu.com/ubuntu/ ${RELEASE}-backports main restricted universe multiversedeb http://archive.canonical.com/ubuntu ${RELEASE} partner# deb-src http://archive.canonical.com/ubuntu ${RELEASE} partnerdeb http://security.ubuntu.com/ubuntu focal-security main restricted# deb-src http://security.ubuntu.com/ubuntu ${RELEASE}-security main restricteddeb http://security.ubuntu.com/ubuntu ${RELEASE}-security universe# deb-src http://security.ubuntu.com/ubuntu ${RELEASE}-security universedeb http://security.ubuntu.com/ubuntu ${RELEASE}-security multiverse# deb-src http://security.ubuntu.com/ubuntu ${RELEASE}-security multiverse" >newroot/etc/apt/sources.list )

Теперь настраиваем chroot-окружение и входим в нашу новую систему:

mount --bind /dev newroot/devmount --bind /dev/pts newroot/dev/pts mount -t sysfs sys newroot/sys mount -t proc proc newroot/procLANG=C.UTF-8 chroot newroot

Первым делом настраиваем поддерживаемые локали. Обратите внимание, что добавляется CP866 (на самом деле она "IBM866"), которая до сих пор бывает актуальной при работе со windows-legacy данными.
Список поддерживаемых кодировок хранится в /etc/locale.gen Ещё раз обращаю внимание, что CP866/IBM866 по-умолчанию там нет. Пос

locale-gen en_US.UTF-8echo "en_GB ISO-8859-1en_GB.UTF-8 UTF-8en_US ISO-8859-1en_US.UTF-8 UTF-8ru_RU.CP1251 CP1251ru_RU.IBM866 IBM866ru_RU.KOI8-R KOI8-Rru_RU.UTF-8 UTF-8" >/etc/locale.gen# Генерируем файлы выбранных кодировок и локалей.locale-gen

Обновляем список пакетов и сразу ставим mc, aptitude и фс, чтобы жить стало легче.

apt-get updateapt-get upgradeapt-get install -y aptitude mc man# Ставим базовый языковой пакет.apt-get install -y language-pack-en

EFI раздел будет примонтирован в /boot/efi. Монтируем и настраиваем /etc/fstab.

echo " <file system>                           <mount point>          <type>  <options>                    <dump> <pass># / was on /dev/sda2 during installationUUID=`blkid -o value -s UUID /dev/sda2`   /                      ext4    errors=remount-ro,relatime      0     2# /boot/efi was on /dev/sda1 during installationUUID=`blkid -o value -s UUID /dev/sda1`   /boot/efi              vfat    umask=0033                      0     1" >/etc/fstab# Монтируем EFI-раздел.mount /boot/efi

Настраиваем локаль.

echo 'LANG="C"LANGUAGE="en_US:C:ru_RU"LC_CTYPE="ru_RU.UTF-8"LC_MESSAGES="en_US.UTF-8"LC_COLLATE="ru_RU.UTF-8"LC_NUMERIC="C.UTF-8"LC_TIME="C.UTF-8"LC_MONETARY="en_US.UTF-8"LC_PAPER="ru_RU.UTF-8"LC_NAME="en_US.UTF-8"LC_ADDRESS="en_US.UTF-8"LC_TELEPHONE="ru_RU.UTF-8"LC_MEASUREMENT="ru_RU.UTF-8"LC_IDENTIFICATION="en_US.UTF-8"' >/etc/default/locale

Настраиваем часовой пояс. То же самое можно выполнить вызовом "dpkg-reconfigure tzdata". Но нам же нужно, чтобы это можно было заскриптовать. Просмотреть спиcок часовых поясов можно вызовом "timedatectl list-timezones".

ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtimeecho "Europe/Moscow" >/etc/timezoneecho "test" >etc/hostname# Но сейчас принято делать так:timedatectl set-timezone "Europe/Moscow" # Просмотреть варианты можно вызовом timedatectl list-timezones

Указываем, что аппаратные часы у нас хранят время в UTC. Обратите внимание, что "0" означает время в UTC.

timedatectl set-local-rtc 0

Ставим ядро, дополнительные модули и заголовки ядра. Ядро ставим самое свежее из доступный и заточенное под виртуализацию:

apt-get install -y linux-image-virtual-hwe-20.04-edge linux-image-extra-virtual-hwe-20.04-edge linux-headers-virtual-hwe-20.04-edge

Ставим поддержку консоли, сети, GRUB, SSH и всякие мелкие утилиты:

apt-get install -y console-setup console-common sshapt-get install -y net-tools bind9utils build-essential pixz pigz pv htopapt-get install -y grub-efi-amd64

Настраиваем клавиатуру:

# Consult the keyboard(5) manual page.XKBMODEL="pc105"XKBLAYOUT="us,ru"XKBVARIANT=","XKBOPTIONS="grp:rctrl_toggle,lv3:ralt_switch,grp_led:scroll"BACKSPACE="guess"' >/etc/default/keyboardecho '# CONFIGURATION FILE FOR SETUPCON# Consult the console-setup(5) manual page.ACTIVE_CONSOLES="/dev/tty[1-6]"CHARMAP="UTF-8"CODESET="guess"FONTFACE="Terminus"FONTSIZE="8x16"VIDEOMODE=" >/etc/default/console-setup

Это так же можно сделать в интерактивном режиме выполнив:
dpkg-reconfigure console-common
dpkg-reconfigure console-data
dpkg-reconfigure keyboard-configuration

Ставим GRUB на EFI-раздел:

grub-install --target=x86_64-efi --recheck --efi-directory=/boot/efi /dev/sda

Если нужно, то правим настройки GRUB в файле /etc/default/grub и обновляем конфигурацию GRUB вызовом:

update-grub2

Обновляем образ ядра, чтобы подхватились настройки консоли:

update-initramfs -u

Задаём пароль root и разрешаем авторизацию root в SSH по паролю. Это нужно для того, чтобы можно было подключиться первый раз и залить SSH-ключи. Затем авторизацию root по паролю нужно не забыт запретить.
Для этого в файле настроек SSH-сервера /etc/ssh/sshd_config нужно добавить строку:
PermitRootLogin yes

# Задаём пароль rootpasswdecho "PermitRootLogin" >>/etc/ssh/sshd_config
echo "test1">/etc/hostname

Задаём настройки сетевых подключений. У нас netplan и networkd. Не забываем ставить актуальные значения MAC-адресов адаптеров. На первом адаптере ставим статический адрес, а на второй работает DHCP (это NET-подключение к интернет). Обратите внимание, что IPv6 отключается указанием "link-local: [ ]" в настройках подключения.

echo "network:  version: 2  renderer: networkd  ethernets:    eth0:      match:        macaddress: 08:00:27:2e:69:24      addresses:        - 192.168.56.10/24      gateway4: 192.168.56.1" >/etc/netplan/eth0.yamlecho "network:  version: 2  renderer: networkd  ethernets:    eth1:      match:        macaddress: 08:00:27:e4:46:31      # Let's disable IPV6 for this interface.      link-local: [ ]       dhcp4: yes" >/etc/netplan/eth1.yaml

Создаём пользователя и добавляем его в административные группы:

adduser userusermod -G 'adm,dialout,sudo,cdrom,dip,plugdev,users' user

Чистим кэш apt:

apt-get clean

Всё! Можно перегружаться и при загрузке с жёсткого диска загрузится уже наша свежеустановленная система.

Если это виртуальная машина VirtualBox, то после перезагрузки нужно ещё поставить дополнения, подключаем "Guest Additions CD Image" и выполняем из-под нашей новой системы:

sudo mkdir /cdromsudo mount -o loop,ro /dev/cdrom /cdromsudo /cdrom/VBoxLinuxAdditions.runsudo umount /cdrom

На этом всё. Дальше нужно подключиться по SSH и залить SSH ключи пользователей. После чего удалить настройку "PermitRootLogin yes" из /etc/ssh/sshd_config.

Если кому-то интересно, то вот такой образ Ubuntu 20.04 занимает 2.2 ГБ дискового пространства.

Подробнее..

Запуск Linux с виртуального диска vmdk на реальном железе и VirtualBox

17.03.2021 14:12:14 | Автор: admin

Возникла необходимость обеспечить работу Linux как на виртуальной машине (VirtualBox), так и на реальном железе. После долгих поисков и попыток запускать Linux с виртуального диска формата VHD, по примеру Windows, которые либо слишком сложны, либо не работают, я пришел к достаточно простому способу сделать это. Правда не из дисков в формате VHD, а из образа раздела диска в формате VMDK.


Linux возможно загрузить из образа раздела. Теперь нужно сделать так, что бы у нас был и образ диска, который понимает VirtualBox и образ раздела, который может загрузить grub.


Далее расписано, как это можно сделать быстро и без лишней головной боли.


Все что далее, сделано из Windows.


Создаем новый диск фиксированного размера в формате vmdk:


VBoxManage createmedium disk --format VMDK --variant Fixed --filename test1.vmdk --size 10000

Имеем созданные файлы:


  • test1.vmdk дескриптор диска, текстовый файл
  • test1-flat.vmdk файл с образом диска

Теперь необходимо в начало диска добавить еще один кусок размером 1M.


Создаем файл test1-boot.vmdk размером 1M:


fsutil file createnew test1-boot.vmdk 1048576

В test1.vmdk меняем createType="custom" на createType="monolithicFlat". Это будет означать, что диск состоит из нескольких файлов.


Добавляем test1-boot.vmdk в test1.vmdk, первым. После добавления test.vmdk должен выглядеть как-то так:


...createType="monolithicFlat"RW 2048 FLAT "test1-boot.vmdk" 0RW 20480000 FLAT "test1-flat.vmdk" 0...

где 2048 это 2048*512=1048576 байт (1M) для этой части диска.


Создаем виртуальную машину для установки Linux, подключаем к ней диск test1.vmdk и ставим ubuntu/kubuntu/xubunu. Я ставил только эти дистрибутивы, начиная с версий 18.04 до последней (еще не вышедшей) 21.04, все остальное не проверял.


Особенность при установке: должен быть создан только один раздел на виртуальном диске и должен он быть на границе 1M. Это поведение по умолчанию при ручном создании раздела.


Загрузчик должен быть установлен на диск /dev/sda, а не на раздел /dev/sda1. Это тоже поведение по умолчанию.


После того, как все установили, перезагружаемся в VirtualBox, что бы убедится, что Linux загружается.


Теперь загрузим только что установленный Linux на реальном железе. Проще всего сделать это с использованием загрузочной флешки.


Создаем загрузочную флешку (или usb-диск) с использованием Ventoy (https://www.ventoy.net/).


Создаем файл ventoy\ventoy_grub.cfg на разделе данных флешки со следующим содержимым:


menuentry 'boot linux from vmdk part' {     set imgfile="/mydisks/test1-flat.vmdk"    set d_label="MYDISK"    search --set=root --label ${d_label}     loopback loop0 ${imgfile}    set root=(loop0)    linux /boot/vmlinuz root=/dev/disk/by-label/${d_label} loop=${imgfile} rw nosplash    initrd /boot/initrd.img}

Здесь:


  • imgfile="/mydisks/test1-flat.vmdk" путь до файла с образом раздела
  • d_label="MYDISK" метка раздела, где лежит файл с образом раздела test1-flat.vmdk

Загружаемся с этой флешки, нажимаем F6 и попадаем в меню, где выбираем пункт "boot linux from vmdk part". Радуемся запущенному Linux.


Можно вернуться в свою рабочую OS, запустить VirtualBox и загрузить Linux из виртуального диска.


Таким вот, незамысловатым, способом можно иметь возможность сидя в Windows запускать Linux в VirtualBox, настраивать его А потом запускать на реальном железе.


Стоит иметь ввиду, что если обновления затрагивают grub, то они не корректно будут завершены в системе, запущенной на реальном железе, ибо нет раздела с загрузчиком. Однако это не мешает нормальной работе. А такие обновления можно и через VirtualBox применять.


Кстати, образ test1-flat.vmdk можно скопировать на флешку Ventoy, и запускать с нее, тоже работает.


Ну и на последок. Ventoy умеет загружать linux из vhd, но требует дополнительных манипуляций с установленным Linux (https://www.ventoy.net/en/plugin_vtoyboot.html). Но, к сожалению, у меня эти манипуляции привели к тому, что загрузка работает либо на реальном железе, либо в VirtualBox. И там и там с одним образом не получается.

Подробнее..
Категории: Linux , Настройка linux , Virtualbox , Vmdk , Grub

Запуск x64 систем в VirtualBox 6.1.2 на Windows 10 2004

24.08.2020 18:21:28 | Автор: admin
Написать подобный пост меня сподвигло потраченное время на решение проблемы.

Суть проблемы запускаете виртуальную машину в VirtualBox, а она грузится как черепаха, бывает просто зависает и спустя некоторое время перезагружается и в окне виртуальной машины внизу справа высвечивается значок image

Прежде чем найти решение я искал проблему в обновлении видео-драйверов, в ssd, в самой виртуалке, но никак не в том, что явилось причиной обновление до версии 2004.

Долго разбирал лог vbox.log на предмет ошибок, пока не наткнулся на это:

{timestamp} HM: HMR3Init: Attempting fall back to NEM: VT-x is not available
{timestamp} NEM: WHvCapabilityCodeHypervisorPresent is TRUE, so this might work...


Всему виной является сама Windows 10. В версии 2004 по умолчанию включен Hyper-V, если у вас установлен компонент WSL2 или Песочница и если этого не знать, то много времени пропадёт впустую.

Вы думаете, что сможете решить проблему отключением комнонентов, использующих Hyper-V вроде WSL2, Песочница? это не так.

Решается вопрос одной командой. Нужно просто в cmd из-под администратора выполнить:
bcdedit /set hypervisorlaunchtype off
При этом выполнить перезагрузку и полностью отключить питание от ПК на секунд 30.

А после чего полёт нормальный и при старте виртуальной машины вы снова увидите значок image, означающий что всё хорошо

PS: К слову, в VMWare Workstation такой проблемы не наблюдалось.
Подробнее..

Nextcloud на VirtualBox с хранилищем в общей папке

17.01.2021 18:05:05 | Автор: admin

Идея иметь собственное домашнее облако у меня была давно. Рассматривал варианты NAS на основе бесплатных дистрибутивов типа FreeNAS, NAS4Free, OpenMediaVault и пр. Но хотелось, чтобы был мобильный клиент, простой и красивый webUI. Раньше как-то баловался с разными решениями и понравился проект ownCloud. Но на текущий момент у него платное мобильное приложение. Сейчас стоит около 30 рублей, но хотелось иметь что-то более бесплатное. Вспомнил про хороший форк ownCloud Nextcloud. Мобильное приложение бесплатное (+ для есть и дополнительные приложения) и есть декстопные клиенты (Win, Mac, Linux). Сам Nextcloud имеет множество настроек, интеграций, а также возможность установки расширений (приложений).

Распространяется Nextcloud несколькими вариантами:

  1. Архив серверного приложения для web-сервера;

  2. Web-инсталлер;

  3. Образами для VirtualBox, Docker и Snap-пакет.

Я решил реализовать схему на VirtualBox, с подключением общей папки, как хранилища.

Предусловие: На сервере должен быть установлен VirtualBox (далее VB) и VirtualBox Extension Pack (далее VBEP).

Импорт виртуальной машины

1. Скачиваем образ виртуальной машины Nextcloud-VM.ova.

Другие варианты образов представлены на сайте Hansson IT.

2. Двойным кликом запускаем скаченный образ, после чего откроется импорт VirtualBox.

В настройках можно указать для создаваемой виртуальной машины (далее ВМ) Имя, Описание и Папку. Характеристики железа уменьшать не стоит, иначе при установке Nextcloud могут появиться ошибки о недостаточности ресурсов. Все настройки ВМ, в т.ч. общие папки, лучше настраивать после завершения установки Nextcloud.

3. После нажимаем Импорт и ждём завершения создания нашей ВМ.

4. После успешного импорта, ВМ отобразиться в списке ВМ VB.

Первоначальная настройка Nextcloud

Образ ВМ основан на Ubuntu Server 20.04.1 LTS в котором предустановлены скрипты разворачивания Nextcloud.

1. Запускаем ВМ.

2. После запуска ВМ появляется приглашение авторизации. По умолчанию пользователь (админ) сервера ncadmin, с паролем nextcloud.

Смена пароля будет предложена после завершения конфигурации Nextcloud.

3. Авторизовываемся на сервере.

4. После авторизации появляется приветственное сообщение первого запуска с прделожением запустить скрипт установки. Для запуска необходимо ввести пароль пользователя ncadmin.

Вводим пароль, нажимаем Enter и запускается процесс установки Nextcloud.

5. После проверки конфигурации ВМ будет отображено сообщение о выборе варианта хранения данных. В образе ВМ подключено 2 жестких диска (динамические по 40 Гб):

  • disk1 диск с ОС, файловая система ext4.

  • disk2 диск с файловой системой ZFS.

По умолчанию предлагается хранить данные на втором диске. Я собираюсь хранить данные в сетевой папке (на отдельном физическом жестком диске), поэтому использовать второй диск я не буду.

Ознакомившись с сообщением, нажимаем Ок.

6. Открывается окно выбора жесткого диска для хранения.

Стрелками встаем на позицию 1 Disk, активируем её пробелом.

Клавишей Tab переходим к блоку кнопок, выбираем Ok и нажимаем Enter.

7. На следующем шаге открывается окно выбора DNS сервера:

  • Quad9

  • Cloudflare

  • Local локальный сервер (по DHCP)

Я предпочитаю использовать Cloudflare. Выбираю его и нажимаю Ok.

8. Следующее окно сообщение о выборе зеркала обновлений.

Ознакомившись с сообщением, нажимаем Ок.

9. Следующее сообщение информирует о текущем сервере обновлений http://archive.ubuntu.com/ubuntu.

Ознакомившись с сообщением, нажимаем Ок.

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

Я решил остаться на стандартном, хотя по тестам есть зеркала и получше (выше скорость, меньше пинг, шире канал). Поэтому на этом шаге выбираю No и нажимаю Enter.

После чего начнется установка Nextcloud (+PostgreSQL, PHP, Apache).

11. По завершению установки будет предложено изменить пароль ncadmin

Нажимаем любую клавишу. Вводим новый пароль, нажимаем Enter, подтверждаем новый пароль ещё раз и нажимаем Enter.

12. После смены пароля появляется сообщение что текущий админ в Nextcloud ncadmin. И его нужно заменить на нашего.

Нажимаем любую клавишу. Вводим имя пользователя, нажимаем Enter, вводим пароль, нажимаем Enter, подтверждаем пароль ещё раз и нажимаем Enter.

13. Далее появляется окно с выбором местоположения

Выбираем Europe, и нажимаем Ok.

14. В следующем окне необходимо выбрать город. Выбираем необходимый и нажимаем Ok.

15. Может появиться следующее сообщение о том, что существует обновленная версия файла '/etc/sysemd/resolved.conf' и нужно принять решение что делать:

Y или I установить обновленную (основную действующую) версию;

N или O оставить текущую установленную версию;

D показать изменения между версиями;

Z запустить shell

Я решил установить обновленную версию: ввожу Y и нажимаю Enter.

После обновления файла ВМ будет перезагружена.

16. После перезагрузки ВМ необходимо авторизоваться (на этом этапе можно пользоваться PuTTY). После авторизации будет приветственное окно, которое сообщит, что мы все установили и это окно можно отключить удалив файл /home/ncadmin/welcome.sh (иначе оно будет постоянно появляться).

Нажимаем Ok. Nextcloud установлен.

Настройка ВМ

Для работы расширений VB установим соответствующий пакет sudo apt install virtualbox-guest-utils

После установки выключим ВМ для её настройки sudo shutdown -h now

После того, как ВМ будет выключена, в VB зайдем в настройки.

1. Можно включить двунаправленный буфер обмена (но лучше пользоваться PuTTY)

2. Я уменьшил оперативную память до 1024 Гб и отключил гибкий диск

3. Установил использование одного ядра процессора

4. Создал общую папку (folder): указал путь и включил авто-подключение

Сохраняем настройки и запускаем ВМ.

Изменение папки хранения данных

Основной гайд для этого блока взял отсюда https://enk2x.ru/2019/09/21/datanew/

После запуска ВМ, авторизуемся.

1. Проверяем наличие общей папки

cd /media

ls

Должно отобразиться наименование sf_folder (на гостевой машине у общей папки префикс sf_), где folder имя общей папки на хост машине.

2. Включаем в группу vboxsf (группа-владелец общей папки) пользователей ncadmin и www-data (пользователь Apache).

sudo usermod -aG vboxsf ncadmin

sudo usermod -aG vboxsf www-data

После включения в группу перезагружаем ВМ

sudo shutdown -r now

3. После перезагрузки авторизуемся и переводим приложение nextcloud в режим обслуживания

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on

Папка nextcloud расположена в корне папки www, а не внутри html

4. Копируем файлы настроек и пользовательские файлы в общую папку

sudo cp -R /mnt/ncdata /media/sf_folder

5. Убеждаемся что всё скопировано

cd /media/sf_folder/ncdata

ls

Так же можно проверить на хост машине в общей папке

6. Изменяем путь к папке данных в конфиг-файле

sudo nano /var/www/nextcloud/config/config.php

Откроется файл config.php, где для параметра 'datadirectory' необходимо изменить значение '/mnt/ncdata' на '/media/sf_folder/ncdata' (где folder имя общей папки)

После внесения изменений нажимаем Ctrl+X, на вопрос о сохранении изменений вводим y и нажимаем Enter.

7. Выключаем режим обслуживания

sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off

Результат

Проверим работоспособность.

1. Авторизуемся на сервере Nextcloud через web-интерфейс под пользователей admin и добавим картинку в папку Photos

2. Проверим наличие файла в общей папке на хост-машине

3. Проверим наличие файла в мобильном приложении.

В результате мы получили облачный сервер на виртуальной машине с внешним хранилищем, к которому можно получить прямой доступ посредством файлового менеджера.

4. Обратный порядок копирования

Если мы сначала вручную закидываем файлы в общую папку (без использования приложения), то в приложении они не будут видны. Для того, чтобы они отобразились, нужно пересканировать папки командой

sudo -u www-data php /var/www/nwxtcloud/occ files:scan all

После сканирования, добавленный файлы отобразятся в приложении.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru