Так начинается история Александра Синчинова на DevOpsConf. Когда из компании ушел ведущий специалист по Windows, Александр задался вопросом, что теперь делать. Переходить на Linux, конечно же! Александр расскажет, как ему удалось создать прецедент и перевести часть Windows разработки на Linux на примере реализованного проекта на 100 000 конечных пользователей.
Как легко и непринужденно доставлять проект в RPM, используя TFS, Puppet, Linux .NET core? Как поддерживать версионирование БД проекта, если разработка впервые слышит слова Postgres и Flyway, а дедлайн послезавтра? Как интегрировать с Docker? Как мотивировать .NET-разработчиков отказаться от Windows и смузи в пользу Puppet и Linux? Как решать идеологические конфликты, если обслуживать Windows в продакшн нет ни сил, ни желания, ни ресурсов? Об этом, а также о Web Deploy, тестировании, CI, о практиках использования TFS в существующих проектах, и, конечно, о сломанных костылях и работающих решениях, в расшифровке доклада Александра.
Итак, Вася ушел, задача на мне, девелоперы ждут
Так как мы активно развиваем DevOps, я понял, что нужно что-то менять в подходе выноса нового приложения. Решение было одно — по возможности перевести все на Linux. Google мне помог — на тот момент уже был портирован .Net под Linux, и я понял, что это решение!
Почему .NET core в связке с Linux?
На это было несколько причин. Между «платить деньги» и «не платить» большинство выберет второе — как и я. Лицензия на MSDB стоит около 1 000 $, обслуживание парка виртуальных машин Windows исчисляется сотнями долларов. Для большой компании это большие затраты. Поэтому экономия — первая причина. Не самая важная, но одна из весомых.
Виртуальные машины Windows занимают больше ресурсов, чем их братья из Linux — они тяжелые. Учитывая масштаб большой компании мы выбрали Linux.
Система просто встраивается в существующий CI. Мы считаем себя прогрессивными DevOps’ами, используем Bamboo, Jenkins и GitLab CI, поэтому большая часть у нас крутится на Linux.
Последняя причина — удобное сопровождение. Нам нужно было снизить порог вхождения для «сопровожденцев» — ребят, которые понимают техническую часть, обеспечивают бесперебойность и обслуживают сервисы со второй линии. Они уже были знакомы со стеком Linux, поэтому им гораздо проще понять новый продукт, поддерживать и сопровождать, чем тратить дополнительные ресурсы, чтобы разобраться с аналогичным функционалом ПО для Windows платформы.
Требования
Первое и главное — удобство нового решения для разработчиков. Не все из них оказались готовы к переменам, особенно после произнесенного слова Linux. Разработчики хотят любимую Visual Studio, TFS c автотестами по сборкам и смузи. Как происходит доставка в продакшн — им не важно. Поэтому мы решили не менять привычный процесс и оставить для Windows-разработки всё без изменений.
Новый проект нужно встроить в существующий CI. Рельсы уже были и всю работу было необходимо выполнить с учетом параметров системы управления конфигурацией, принятых стандартов доставки и систем мониторинга.
Простота в поддержке и эксплуатации, как условие для минимального порога вхождения для всех новых участников со стороны разных подразделений и отдела сопровождения.
Дедлайн — вчера.
Группа Win разработки
С чем тогда работала команда Windows?
Сейчас я могу уверенно сказать, что IdentityServer4 — это классная бесплатная альтернатива ADFS с аналогичными возможностями, или что Entity Framework Core — рай для разработчика, где можно не заморачиваться написанием SQL скриптов, а описывать запросы в БД в терминах ООП. Но тогда, на обсуждении плана действий, я смотрел на этот стэк как на шумерскую клинопись узнавая лишь PostgreSQL и Git.
На тот момент мы активно использовали Puppet как систему управления конфигурацией. В большинстве наших проектов мы применяли GitLab CI, Elastic, балансировали высоконагруженные сервисы с помощью HAProxy, следили за всем с помощью Zabbix, связки Grafana и Prometheus, Jaeger, и все это крутилось на железяках HP c ESXi на VMware. Всем знакомо — классика жанра.
Посмотрим и попытаемся понять, что же происходило до того, как мы затеяли все эти вмешательства.
Что было
TFS — это довольно мощная система, которая не только доставляет код от разработчика до конечной продакшн-машины, но также имеет набор для очень гибкой интеграции с различными сервисами — для обеспечения CI на кроссплатформенном уровне.
Раньше это были сплошные форточки. TFS использовал несколько Build-агентов, на которых собиралось множество проектов. В каждом агенте по 3-4 worker-a, чтобы распараллелить задачи и оптимизировать процесс. Дальше, согласно релизным планам, TFS доставлял свежеиспеченный Build на Windows-сервер приложений.
К чему мы хотели прийти
Для доставки и разработки используем TFS, а запускаем приложение на Linux Application server, и между ними какая-то магия. Этот Magic Box и есть соль предстоящей работы. Перед тем, как разобрать его по частям, сделаю шаг в сторону и скажу два слова о приложении.
Проект
Приложение предоставляет функциональность для оперирования предоплаченными картами.
Client
Существовало два типа пользователей. Первый получал доступ, авторизуясь по сертификату SSL SHA-2. У второго был доступ по логину и паролю.
HAProxy
Дальше клиентский запрос попадал в HAProxy, который решал следующие задачи:
- первичная авторизация;
- терминирование SSL;
- тюнинг HTTP запросов;
- трансляция запросов.
Проверка сертификата клиента шла по цепочке. Мы — authority и можем себе такое позволить, так как сами выдаем сертификаты клиентам сервиса.
Обратите внимание на третий пункт, чуть позже вернемся к нему.
Backend
Бэкенд планировали сделать на Linux. Бэкенд взаимодействует с БД, подгружает необходимый список привилегий и потом, в зависимости от того, какими привилегиями обладает авторизовавшийся пользователь, предоставляет доступ для подписания финансовых документов и отправки их на исполнение, либо генерации какого-то отчета.
Экономия c HAProxy
Кроме двух контекстов, по которым ходил каждый из клиентов, существовал еще контекст identity. IdentityServer4 как раз позволяет авторизоваться, это бесплатный и мощный аналог для ADFS — Active Directory Federation Services.
Запрос в identity обрабатывался в несколько шагов. Первый шаг — клиент попадал в бэкенд, который обменивался данными с этим сервером и проверял наличие токена для клиента. Если не находил — запрос возвращался обратно на тот контекст, с которого он пришел, но уже с редиректом, и с редиректом шел на identity.
Второй шаг — запрос попадал на страницу авторизации в IdentityServer, где клиент регистрировался, а в базе данных IdentityServer появлялся тот самый долгожданный токен.
Третий шаг — клиент редиректился обратно на контекст, с которого он пришел.
У IdentityServer4 есть особенность: ответ на обратный запрос он возвращает по HTTP. Как ни бились с настройкой сервера, как ни просвещались документацией, но мы каждый раз получали первоначальный запрос клиента с URL, который пришел по HTTPS, а IdentityServer возвращал тот же самый контекст, но с HTTP. Мы были в шоке! И перевели все это через контекст identity на HAProxy, а в хедерах пришлось модифицировать протокол HTTP на HTTPS.
В чем же улучшение и где сэкономили?
Мы сэкономили деньги, используя бесплатное решение для авторизации группы пользователей, ресурсы, так как не выносили IdentityServer4 как отдельную ноду в отдельный сегмент, а использовали его совместно с бэкендом на том же самом сервере, где крутится бэкенд приложения.
Как должно работать
Итак, как я обещал — Magic Box. Мы уже понимаем, что гарантированно движемся в сторону Linux. Давайте сформулируем конкретные задачи, которые требовали решения.
Манифесты Puppet. Чтобы доставлять и управлять конфигурацией сервиса и приложения, нужно было написать классные рецепты. Рулончик с карандашом красноречиво показывает как быстро и качественно это было сделано.
Способ доставки. Стандарт — это RPM. Все понимают, что в Linux без него никак, но сам проект после сборки представлял собой набор исполняемых DLL-файлов. Их было около 150, проект достаточно тяжелый. Единственное гармоничное решение — упаковать эту бинарщину в RPM и уже из нее разворачивать приложение.
Версионирование. Нам предстояло релизиться очень часто, и нужно было решить, каким образом формировать имя пакета. Это вопрос уровня интеграции с TFS. Build-агент у нас был на Linux. Когда TFS отправляет задачу обработчику — worker — на Build-агент, он передает ему еще и банч переменных, которые попадают в environment процесса обработчика. В этих переменных окружения передается имя Build, имя версии и другие переменные. Подробнее об этом в с разделе «сборка RPM-пакета».
Настройка TFS сводилась к настройке Pipeline. Раньше мы собирали на Windows-агентах все Windows-проекты, а сейчас появляется Linux-агент — Build-агент, который нужно включить в группу сборки, обогатить какими-то артефактами, сказать, какого именно типа проекты будут собираться на этом Build-агенте, и как-то модифицировать Pipeline.
IdentityServer. ADFS не наш путь, топим за Open Source.
Пройдемся по компонентам.
Magic Box
Состоит из четырех частей.
Linux Build-агент. Linux, потому что мы под него собираем — логично. Эта часть выполнялась в три шага.
- Настроить worker-ы и не один, так как предполагалась распределенная работа над проектом.
- Установить .NET Core 1.х. Почему именно 1.х, когда уже доступно 2.0 в стандартном репозитории? Потому что, когда мы начинали разработку, стабильной версией была 1.09, и проект было решено делать под неё.
- Git 2.x.
RPM-repository. RPM-пакеты нужно было где-то хранить. Предполагалось, что мы будем использовать тот же самый корпоративный RPM-репозиторий, который доступен всем Linux хостам. Так и поступили. На сервере репозитория настроен webhook который скачивал из указанного места требуемый RPM-пакет. Версию пакета webhook’у сообщал Build-агент.
GitLab. Внимание! GitLab здесь используется не разработчиками, а отделом эксплуатации для контроля версий приложения, версий пакетов, контроля состояния всех Linux-машин и в нём хранится рецептура — все манифесты Puppet.
Puppet — разруливает все спорные моменты и доставляет именно ту конфигурацию, которую мы хотим, из Gitlab.
Начинаем погружаться. Как происходит доставка DLL в RPM?
Доставка DDL в RPM
Допустим, у нас есть рок-звезда разработки на .NET. Он использует Visual Studio и создает релизную ветку. После этого загружает ее в Git, и Git здесь — TFS-сущность, то есть это репозиторий приложения, с которым работает разработчик.
После чего TFS видит, что прилетел новый коммит. Какое приложение? В настройках TFS есть метка, какими ресурсами обладает тот или иной Build-агент. В данном случае он видит, что мы собираем .NET Core проект и выбирает Linux Build-агент из пула.
Build-агент получает исходники, выкачивает необходимые dependencies c репозитория .NET, npm и т.д. и после сборки самого приложения и последующей упаковки отправляет RPM-пакет в RPM-репозиторий.
С другой стороны происходит следующее. Инженер отдела эксплуатации занимается непосредственно выкаткой проекта: меняет версии пакетов в Hiera в репозитории, где хранится рецептура приложения, после чего Puppet триггерит Yum, забирает новый пакет из репозитория, и новая версия приложения готова к использованию.
На словах все просто, но что происходит внутри на самом Build-агенте?
Упаковка DLL RPM
Получены исходники проекта и задача на сборку от TFS. Build-агент запускает сборку самого проекта из исходников. Собранный проект доступен в виде множества DLL файлов, которые упакованы в zip-архив для снижения нагрузки на файловую систему.
ZIP-архив выкидывается в директорию сборки пакета RPM. Дальше Bash-скрипт инициализирует переменные окружения, находит версию Build, версию проекта, путь до директории сборки, и запускает RPM-build. По окончании сборки пакет публикуется в локальный репозиторий, который находится на Build-агенте.
Дальше, с Build-агента на сервер в RPM-репозитория отправляется JSON-запрос с указанием имени версии и билда. Webhook, про который я раньше говорил, выкачивает этот самый пакет из локального репозитория на Build-агенте и делает новую сборку доступной для установки.
Почему именно такая схема доставки пакета в репозиторий RPM? Почему нельзя сразу отправить собранный пакет в репозиторий? Дело в том, что это условие для обеспечения безопасности. Такой сценарий ограничивает возможность несанкционированной загрузки RPM-пакетов посторонними людьми на сервер, который доступен всем Linux-машинам.
Версионирование БД
На консилиуме с разработкой выяснилось, что ребятам ближе MS SQL, но в большинстве non-Windows проектов мы уже вовсю использовали PostgreSQL. Так как мы уже решили отказаться от всего платного, то стали использовать PostgreSQL и здесь.
В этой части хочу рассказать, как мы осуществляли версионирование БД и как выбирали между Flyway и Entity Framework Core. Рассмотрим их плюсы и минусы.
Минусы
Flyway идёт только в одну сторону, мы не можем откатиться назад — это существенный минус. Сравнивать с Entity Framework Core можно по другим параметрам — с точки зрения удобства разработчика. Вы же помните, что мы это поставили во главу угла, и основным критерием было не изменить ничего для Windows-разработки.
Для Flyway нам требовалась какая-то обертка, чтобы ребята не писали SQL-запросы. Им гораздо ближе оперировать в терминах ООП. Написали инструкции по работе с объектами БД, сформировался SQL-запрос и выполнился. Новая версия БД готова, прокаталась — всё хорошо, всё работает.
У Entity Framework Core есть минус — при больших нагрузках он строит не оптимальные SQL-запросы, и просадка по БД может быть существенной. Но так как у нас не высоконагруженный сервис, мы не исчисляем нагрузку сотнями RPS, мы приняли эти риски и делегировали проблему будущим нам.
Плюсы
Entity Framework Core работает из коробки и удобен разработке, а Flyway легко интегрируется в существующий CI. Но мы же делаем удобно девелоперам:)
Процедура наката
Puppet видит, что приходит изменение версии пакетов среди которых, тот, что отвечает за миграцию. Сначала устанавливает пакет, где содержатся миграционные скрипты и функционал завязанный на БД. После этого рестартуется приложение, которое работает с БД. Дальше идет установка оставшихся компонентов. Очередность установки пакетов и запуска приложений описаны в манифесте Puppet.
Приложения используют чувствительные данные, такие как токены, пароли к БД, все это подтягивается в конфиг с Puppet master, где они хранятся в зашифрованном виде.
Проблемы TFS
После того, как мы определились и поняли, что у нас действительно все работает, я решил посмотреть, что творится со сборками в TFS в целом для отдела Win-разработки по другим проектам — быстро или нет собираемся/релизимся, и обнаружил существенные проблемы со скоростью.
Один из основных проектов собирается 12-15 минут — это долго, так жить нельзя. Быстрый анализ показал жуткую просадку по I/O, и это на массивах.
Проанализировав покомпонентно, я выделил три очага. Первый — «Kaspersky antivirus», который на всех Windows Build-агентах сканирует исходники. Второй — Windows Indexer. Он не был отключен, и на Build-агентах в реальном времени индексировалось все в процессе деплоя.
Третий — Npm install. Оказалось, что в большинстве Pipelines мы использовали именно этот сценарий. Чем он плох? Процедура Npm install запускается при формировании дерева зависимостей в package-lock.json, где фиксируются версии пакетов, которые будут использоваться для сборки проекта. Минус в том, что Npm install каждый раз подтягивает актуальные версии пакетов из интернета, а это немалое время в случае большого проекта.
Разработчики иногда экспериментируют на локальной машине, чтобы проверить работу отдельной части или проекта целиком. Иногда получалось, что локально все круто, но собирали, выкатывались — ничего не работало. Начинаем разбираться, в чем проблема — ага, разные версии пакетов с зависимостями.
Решение
- Исходники в исключения AV.
- Отключение индексации.
- Переход на npm ci.
Плюсы npm ci, в том, что мы собираем древо зависимостей единожды, и получаем возможность предоставить разработчику актуальный список пакетов, с которым он может сколько угодно экспериментировать локально. Это экономит время разработчиков, которые пишут код.
Конфигурация
Сейчас немного о конфигурации репозитория. Исторически мы используем Nexus для управления репозиториями, в том числе Internal REPO. В этот внутренний репозиторий поставляются все компоненты, которые мы используем для внутренних целей, например, самописные мониторинги.
Мы также используем NuGet, так как он лучше кэширует по сравнению с другими пакетными менеджерами.
Результат
После того, как мы оптимизировали Build-агентов, среднее время сборки сократилось с 12 минут до 7.
Если посчитать все машины, которые мы могли бы использовать для Windows, но перевели на Linux в этом проекте, мы сэкономили порядка $10 000. И это только на лицензиях, а если учитывать содержание — больше.
Планы
На следующий квартал заложили в план работу над оптимизацией доставки кода.
Переход на пребилд Docker-образа. TFS — классная штука со множеством плагинов, которые позволяют интегрировать в Pipeline, в том числе, и сборку по триггеру, допустим, Docker-образа. Этот триггер мы хотим сделать на тот самый package-lock.json. Если каким-то образом меняется состав компонентов, которые используются для сборки проекта — у нас собирается новый Docker-образ. В дальнейшем он используется для развертывания контейнера с собранным приложением. Сейчас этого нет, но планируем перейти на микросервисную архитектуру в Kubernetes, который активно развивается в нашей компании и давно обслуживает продакшн решения.
Резюме
Призываю всех выкинуть Windows, но это не потому, что я не умею ее готовить. Причина в том, что большая часть Opensource-решений — это Linux-стек. Вы хорошо сэкономите на ресурсах. На мой взгляд, будущее за решениями Open Source на Linux с мощным комьюнити.
Профиль спикера Александра Синчинова на GitHub.
DevOps Conf — это конференция по интеграции процессов разработки, тестирования и эксплуатации для профессионалов от профессионалов. Именно поэтому проект, о котором рассказывал Александр? реализован и работает, а в день выступления проведено два успешных релиза. На DevOps Conf на РИТ++ 27 и 28 мая будет еще больше подобных кейсов от практиков. Еще можно вскочить в последний вагон и подать доклад или не торопясь забронировать билет. Встретимся в Сколково!
Комментарии (26)
White_gosHawk
23.04.2019 16:46А что мешало найти другого Васю?) «sarcasm»
sshikov
23.04.2019 19:39Мне кажется, включать сарказм еще рано. Я бы хотел увидеть стоимость данного проекта (в перспективе, с учетом поддержки нового решения в сравнении со старым). Потому что если найти другого Васю окажется дороже — то почему бы и нет?
crazylh
23.04.2019 21:09Это все хорошечно, но какому-нибудь легаси проекту на .Net Framework 4.0 ваши доводы как мертвому припарки.
Прежде всего команда разработки должна захотеть пересесть на .NET Core — после этого появляется и нормальный девопс процесс и релизы и это всё.
Poiser
23.04.2019 21:37Интересная статья! Мы делаем несколько PWAs и у нас похожий стек, только вместо TFS используем TeamCity, ну и во frontend у нас Angular7 + Apache Cordova.
По поводу настройки редиректов в IdentityServer4. Эта проблема известная! Смотрите например тут — https://github.com/IdentityServer/IdentityServer4/issues/2598.
Dansoid
23.04.2019 22:45+1Для Flyway нам требовалась какая-то обертка, чтобы ребята не писали SQL-запросы. Им гораздо ближе оперировать в терминах ООП. Написали инструкции по работе с объектами БД, сформировался SQL-запрос и выполнился. Новая версия БД готова, прокаталась — всё хорошо, всё работает.
Странно почему ребята не посмотрели в сторону FluentMigrator. И туда и назад. Но в чистый назад я не верю. Лучше бакап перед миграцией. EF Core миграции еще тот минингит судя по фиксам и ломающим изменениям.
У Entity Framework Core есть минус — при больших нагрузках он строит не оптимальные SQL-запросы, и просадка по БД может быть существенной. Но так как у нас не высоконагруженный сервис, мы не исчисляем нагрузку сотнями RPS, мы приняли эти риски и делегировали проблему будущим нам.
У EF Core, большой минус, что он еще только родился. И если вы сидите на старых версиях — вы сами себе буратино, так как оптимизацией запросов они только начали заниматься. А там небольшой толк появляется только с .NET Core 3 — без малейшего понятия почему они так сделали, но что есть то есть.
И не при больших нагрузках, а в основном. Так складываются камешки в блоки потери производительности. Попросите ребят отключить предупреджение об client evaluation и превратить их в ошибки. Думаю 50% запросов у вас свалится. И это к лучшему, так как новая версия аннонсирует отключение client evaluation по умолчанию. Видать только так они могли сие стартануть в сроки (я их понимаю, это очень даже не просто).
Terras
24.04.2019 10:45«Призываю всех выкинуть Windows», когда .net core научится делать все, что делает класический .net => тогда можно подумать. А пока это какая-то бета, где для привычных вещей надо придумывать велосипед
Dansoid
24.04.2019 18:25Что-то я не понял. Чего еще не хватает для сервера приложений?
mayorovp
24.04.2019 19:39+1- Серверной части WCF
- IKVM.NET (впрочем, её можно попробовать заменить на микросервис)
- LinqToSql (говорят, можно заменить на более современные Dapper или LinqToDB — но у них нет аналога SqlMetal, придется самим писать)
- EntityFramework 6 (кажется, EF Core до сих пор не умеет всего что умела прошлая версия)
- Файла web.config, в котором можно было не меняя кода настроить много интересных вещей
supcry
24.04.2019 20:48Серверной части WCF в осязаемых планах у MSFT нет. Смотрите в сторону WebApi или gRPC (зависит от умения готовить и окружения).
Linq2Sql разве жив? Простите, но чем вам EF не угодил? (сами мигрировали с первого на второе лет эдак пять назад).mayorovp
24.04.2019 21:53Серверной части WCF в осязаемых планах у MSFT нет. Смотрите в сторону WebApi или gRPC (зависит от умения готовить и окружения).
WebApi и gRPC — это, конечно, хорошо — но спецификации Web Services они не поддерживают.
Linq2Sql разве жив? Простите, но чем вам EF не угодил?
Linq2Sql — это очень простой (и быстрый!) способ подключиться к существующей базе. EF тупо медленнее стартует, к тому же для него тоже нет аналогов SqlMetal
Ernado
25.04.2019 10:36Серверной части WCF
WCF уже потихоньку уходит в прошлое, во многих проектах его уже давно и успешно заменил REST API.
LinqToSql (говорят, можно заменить на более современные Dapper или LinqToDB — но у них нет аналога SqlMetal, придется самим писать)
LinqToSql устарел во времена .NET 3.5 если не ошибаюсь, а любые генераторы кода — это в принципе зло и их необходимость, это признак того, что в проекте что-то не так с архитектурой.
EntityFramework 6 (кажется, EF Core до сих пор не умеет всего что умела прошлая версия)
Чего именно вам не хватает в EF Core?
Файла web.config, в котором можно было не меняя кода настроить много интересных вещей
appsettings.json также позволяет конфигурировать все то, что вы считаете необходимым сделать конфигурируемым. К тому же он значительно проще и в нем нету ада c bindingRedirect
mayorovp
25.04.2019 11:09WCF уже потихоньку уходит в прошлое, во многих проектах его уже давно и успешно заменил REST API.
Иногда REST просто не подходит, нужен RPC. А в этой области только веб-сервисы дают возможность сформировать машиночитаемую спецификацию (wsdl) и сгенерировать по ней клиент автоматически.
любые генераторы кода — это в принципе зло и их необходимость, это признак того, что в проекте что-то не так с архитектурой
Предложите альтернативу.
supcry
25.04.2019 13:38А в этой области только веб-сервисы дают возможность сформировать машиночитаемую спецификацию (wsdl) и сгенерировать по ней клиент автоматически.
gRPC также может генерировать «машиночитаемую спецификацию» через reflection для генерации клиента. Правда это не будет wsdl, но суть та же. Вообще, это не прерогатива одних только вёб-сервисов. И при желании можно экспозить gRCP как REST через автоматическую проксю.
Dansoid
25.04.2019 16:12+1любые генераторы кода — это в принципе зло и их необходимость, это признак того, что в проекте что-то не так с архитектурой
Кхм, можете развернуть сию мысль? Пока говорилось что генерится модель из базы, что я считаю единственно правильным способом работать с ней посредством LINQ.
EF Core + CodeFirst — опять же сами себе буратино. Надизайнят класов, намапят на базу, база как-то себе построится. Именно как-то, а не как надо. Потом через годик, когда данных в таблицы накидают, поймете где просчет и бегом это рефакторить.
Ужас берет от мысли какие после этого будут миграции и дай бог данные не потеряются.Ernado
25.04.2019 16:48Я видимо не совсем понял, что именно делает SqlMetal. Но если это просто инструмент для генерации простых моделей для ORM, то тогда мне в принципе не понятно, в чем проблема — EF Core это умеет.
В своем комментарии я больше говорил про подход, когда для решения каких-то задач используются инструменты для автоматического генерирования кода. Причем не моделей, а кусков логики. Встречал такие проекты. И это всегда было одним из серьезных симптомов того, что что-то явно не так в проекте.
Dansoid
25.04.2019 16:02Вообще-то я думал что вы скажете что в .NET нехватает для Linux разработки чтобы написать полноценное серверное приложение.
- Да WCF нету, да я как-то и не плачу, вот только старые системы без него не перевести под .NET Core. Есть голосовалка, что бы вы хотели от порта
- LinqToDB не надо SqlMetal, у него есть T4 шаблоны которые генерят модель.
- EntityFramework 6 — есть порт. Но думаю уже EF Core на 90% совместим
- Файла web.config — как то мимо кассы
mayorovp
25.04.2019 16:29LinqToDB не надо SqlMetal, у него есть T4 шаблоны которые генерят модель.
В БД за актуальной схемой шаблон T4 тоже сам полезет?
Dansoid
25.04.2019 17:45Именно так и делается, в шаблоне указываешь куда конектится, и все. Работает для всех поддерживаемых баз данных.
Плюс такого подхода, что есть еще возможность полной кастомизации того что будет сгенерировано.
mayorovp
После вступления — "Когда я высыпал на стол весь стек Windows-разработки, то понял, что ситуация — боль…" и КДПВ я ожидал какой-то жести. Вроде разработки солюшенов под Sharepoint (условие — на билд-севрере должны быть установлены Visual Studio и Sharepoint) или левых проприетарных тулчейнов (которые, конечно же, никто не додумался залить в NuGet).
А тут никакой жести, используются нормальные технологии на всех этапах...
Rast1234
У нас есть немного. Работаем с Dynamics CRM, было желание ходить к ее wcf "api" из .net core на линуксе. Получилось с помощью черной магии.
mayorovp
Чёрная магия тут — только в области программирования, и то лишь из-за недоработанности wcf в .net core. Всё еще не вижу проблем со сборкой и деплоем клиента.
Или вы пытаетесь саму Dynamics CRM поднимать автоматически?
Rast1234
Да, поэтому и написал, что немного)