Posted on 16. July 2024

The .NET MAUI Extension for Visual Studio Code is now Generally Available

Розширення .NET MAUI для Visual Studio Code тепер загальнодоступне


Сьогодні ми раді повідомити, що попереднього перегляду розширення .NET MAUI VS Code немає, і воно включає деякі довгоочікувані нові функції, зокрема XAML IntelliSense і Hot Reload!


Що таке розширення .NET MAUI?

Розширення .NET MAUI містить інструменти, необхідні для розробки програм .NET MAUI, у спрощений Visual Studio Code. Його створено на основі C# Dev Kit і розширення C#, які містять Solution Explorer, C# Hot Reload, потужний C# IntelliSense та багато іншого. Розширення .NET MAUI додає можливість орієнтуватися на мобільні та настільні пристрої, а також (з останніми версіями розширень) XAML IntelliSense та XAML Hot Reload, зберігаючи при цьому роботу з VS Code оптимізованою та простою.


Новий і покращений досвід редагування XAML

Попередня версія розширення .NET MAUI постачалася з базовим підсвічуванням синтаксису XAML і завершеннями, але це було далеко не повне враження, яке ми хотіли надати. Протягом останнього року ми модернізували наявну службу мови XAML у Visual Studio, запакували її та перенесли у VS Code для вашої розробки .NET MAUI. Це доповнення, яке також працює з Copilot, дає вам інтелектуальне автозаповнення, корисні підказки та безперебійну навігацію кодом під час створення інтерфейсів користувача.


https://devblogs.microsoft.com/dotnet/wp-content/uploads/sites/10/2024/06/IntellisenseDemo-1.mp4?_=1 


Гаряче перезавантаження тут 🔥

Можливість редагувати свій код без перезапуску програми є однією з найпотужніших функцій продуктивності, які є у розробників .NET. З останньою версією тепер ви можете гаряче перезавантажувати редагування файлів C# і XAML у Visual Studio Code. XAML Hot Reload уже ввімкнено – просто редагуйте свій XAML під час роботи програми та дивіться, як зміни автоматично відображаються у вашому інтерфейсі користувача!

https://devblogs.microsoft.com/dotnet/wp-content/uploads/sites/10/2024/06/XAML-hot-reload-1.mp4?_=2 


C# Hot Reload все ще перебуває в експериментальному стані, але ви можете ввімкнути його, відкривши VS Code Settings (CTRL/CMD + SHIFT + ,), знайшовши “hot reload” і встановивши прапорець “”[Experimental“ ] Вмикає «Hot Reload» під час налагодження».



Потім відредагуйте свій C# та збережіть або натисніть значок вогню на панелі інструментів налагодження, щоб застосувати зміни!



Почніть сьогодні

Сьогоднішній випуск є важливою віхою в нашій подорожі VS Code, але ми ще не закінчили! Ми продовжуватимемо прислухатися до ваших відгуків і працюватимемо над покращенням продуктивності, надійності та додаванням функцій, щоб зробити розробку вашої програми .NET MAUI більш оптимізованою. Щоб повідомити про помилку чи поділитися пропозицією, ви можете скористатися діалоговим вікном Help > Report Issue у VS Code. Так само, як C# і C# Dev Kit, ми будемо випускати щомісяця з щотижневим оновленням у попередньому каналі.

 

Щоб почати використовувати розширення, ви можете прочитати наш Посібник із початку роботи або завантажити розширення та виконати покрокове керівництво у VS Code!



Posted on 15. July 2024

Quantization with DirectML helps you scale further on Windows

Квантування за допомогою DirectML допомагає вам ще більше масштабувати в Windows



Підтримка DirectML для Phi 3 mini була запущена минулого місяця, і з тих пір ми внесли кілька покращень, розблокувавши більше моделей і навіть покращивши продуктивність!


Розробники можуть отримати вже квантовані версії Phi-3 mini (з варіантами для версій 4k і 128k). Тепер вони також можуть отримати середній Phi 3 (4k і 128k) і Mistral v0.2. Слідкуйте за додатковими попередньо квантованими моделями! Ми також надіслали інтерфейс gradio, щоб спростити тестування цих моделей за допомогою нового API ONNX Runtime Generate(). Дізнайтесь більше.


Обов’язково перегляньте наші сесії зі створення, щоб дізнатися більше. Подробиці дивіться нижче.


Дивіться тут, щоб дізнатися, що мають сказати наші партнери-постачальники обладнання:

Що таке квантування? 

Пропускна здатність пам’яті часто є вузьким місцем для запуску моделей на початковому та старішому обладнанні, особливо коли мова йде про мовні моделі. Це означає, що зменшення розмірів мовних моделей безпосередньо означає розширення діапазону пристроїв, на які розробники можуть орієнтуватися.


Було проведено багато досліджень щодо зменшення розміру моделі за допомогою квантування, процесу, який зменшує точність і, отже, розмір ваг моделі.


Наша мета — забезпечити масштабованість, зберігаючи при цьому точність моделі, тому ми інтегрували підтримку моделей, до яких застосовано  Activation-Aware Quantization  (AWQ). AWQ — це техніка, яка дає нам змогу отримати економію пам’яті від квантування з мінімальним впливом на точність. AWQ досягає цього, визначаючи 1% основних ваг, необхідних для підтримки точності моделі, а потім квантує решту 99% ваг. Це призводить до значно меншої втрати точності з AWQ порівняно з іншими методами.


Середня людина читає до 5 слів за секунду. Завдяки значним перевагам пам’яті від AWQ, Phi-3-mini працює з такою швидкістю або швидше на старих дискретних GPUs і навіть інтегрованих GPUs у ноутбуки. Це означає можливість запускати Phi-3-mini на сотнях мільйонів пристроїв!


Щоб побачити це в дії, ознайомтеся з нашою розмовою про збірку нижче!


Вимірювання здивування


Здивування – це показник, який використовується для кількісного визначення того, наскільки добре модель прогнозує вибірку. Не вдаючись у математику всього цього, нижча оцінка здивування означає, що модель є більш впевненою щодо своїх прогнозів і припускає, що розподіл ймовірностей моделі ближчий до справжнього розподілу даних.


Здивування можна розглядати як спосіб кількісного визначення середньої кількості гілок перед моделлю в кожній точці прийняття рішення. На кожному кроці менша плутанина означатиме, що модель має менше, більш впевнених виборів, що відображає більш витончене розуміння теми. Вища збентеженість означатиме більше, менш впевнений вибір і, отже, вибір, який є менш передбачуваним, релевантним та/або різноманітним за якістю.

 

Як ви бачите нижче, наші дані показують, що AWQ призводить до невеликої втрати точності моделі з лише невеликим збільшенням здивування. Натомість використання AWQ означає зменшення ваги моделі в 4 рази, що призводить до різкого збільшення кількості пристроїв, які можуть працювати з Phi-3-mini!

Дізнайтесь більше

Перегляньте ці сесії на Build, щоб дізнатися більше:

Почати


Перегляньте репозиторій ONNX Runtime Generate() API, щоб почати вже сьогодні:

https://github.com/microsoft/onnxruntime-genai


Перегляньте тут наш додаток для чату зі зручним інтерфейсом Gradio:

https://github.com/microsoft/onnxruntime-genai/tree/main/examples/chat_app 


Це дозволяє розробникам вибирати з різних типів мовних моделей, які найкраще підходять для їх конкретного випадку використання. Слідкуйте за новинами, щоб дізнатися більше!


Драйвери 


Ми рекомендуємо оновити драйвери до останніх версій для найкращої продуктивності. 


  • AMD: покращене прискорення драйвера для генеративного AI, включаючи великі мовні моделі 

  • (AMD Software: Adrenalin Edition 23.40.27.06 for DirectML)

  • Intel рада співпрацювати з Microsoft і надати драйвер, оптимізований для цих сценаріїв AWQ для широкого діапазону апаратного забезпечення. Будь ласка, завантажте наш загальнодоступний сертифікований WHQL драйвер із повною підтримкою сьогодні, доступний тут.

  • NVIDIA: R555 Game Ready, Studio or NVIDIA RTX Enterprise




Posted on 15. July 2024

Створіть наступну хвилю AI у Windows із підтримкою DirectML для PyTorch 2.2

Створіть наступну хвилю AI у Windows із підтримкою DirectML для PyTorch 2.2


Сьогодні розробники Windows можуть використовувати PyTorch, щоб запускати висновки на останніх моделях у всіх графічних процесорах в екосистемі Windows завдяки DirectML. Ми оновили Torch-DirectML для використання DirectML 1.13 для прискорення та підтримки PyTorch 2.2. PyTorch із DirectML спрощує процес налаштування за допомогою інсталяції в одному пакеті, що полегшує випробування технологій штучного інтелекту та підтримує вашу здатність масштабувати штучний інтелект для ваших клієнтів у Windows.


Щоб побачити ці оновлення в дії, ознайомтеся з нашим сеансом збірки. Додайте можливості AI на всі свої Windows Devices. 


Перегляньте тут, щоб дізнатися, як наші партнери-постачальники апаратного забезпечення покращують цей досвід:


  • AMD: AMD рада, що PyTorch із DirectML дозволяє ще більшій кількості розробників запускати LLM локально. Дізнайтеся більше про те, куди ще AMD інвестує за допомогою DirectML.

  • Intel: Intel із задоволенням підтримує PyTorch від Microsoft із цілями DirectML. Перегляньте наш блог, щоб дізнатися більше про повну підтримку, доступну сьогодні.

  • NVIDIA: NVIDIA з нетерпінням чекає на розробників, які використовують пакет torch-directml, прискорений RTX GPUs. Ознайомтеся з усіма оголошеннями Microsoft Build, пов’язаними з NVIDIA, щодо RTX AI PCs і їх розширеною співпрацею з Microsoft.


PyTorch із DirectML простий у використанні з останніми моделями Generative AI


PyTorch із DirectML надає розробникам простий у використанні спосіб випробувати найновіші та найкращі моделі штучного інтелекту на своїй машині Windows. Це оновлення базується на платформі інференційного висновку світового класу DirectML, яка гарантує, що ці оптимізації забезпечують масштабований і ефективний досвід для останніх моделей Generative AI. Наша мета в цьому оновленні — забезпечити безперебійну роботу з відповідними моделями Gen AI, такими як Llama 2, Llama 3, Mistral, Phi 2 і Phi 3 Mini, і ми розширимо наше покриття ще більше в найближчі місяці!


Найкраще те, що використовувати останній пакет Torch-DirectML із Windows GPU так само просто, як запустити: 


pip install torch-directml


Після встановлення перегляньте наш зразок мовної моделі, який миттєво допоможе вам запустити мовну модель локально! Почніть із встановлення кількох вимог і входу в Hugging Face CLI:


pip install –r requirements.txt 

huggingface-cli login



Далі виконайте таку команду, яка завантажить вказану модель Hugging Face, оптимізує її для DirectML і запустить модель в інтерактивному сеансі Gradio на основі чату!


python app.py —model_repo “microsoft/Phi-3-mini-4k-instruct”


Phi 3 Mini 4K працює локально за допомогою DirectML через інтерфейс Gradio Chatbot.


Ці найновіші зразки PyTorch із DirectML працюють на різних машинах і найкраще працюють на останніх GPUs, обладнаних найновішими драйверами. Перегляньте розділ Supported Models  зразка, щоб дізнатися більше про вимоги до пам’яті GPU для кожної моделі.


Цей бездоганний досвід інференції забезпечується нашими тісними відносинами спільного проектування з нашими апаратними партнерами, щоб переконатися, що ви отримуєте максимум від свого Windows GPU під час використання DirectML.


Спробуйте PyTorch із DirectML сьогодні

Випробувати це оновлення справді так само просто, як запустити «pip install torch-directml» у вашому існуючому середовищі Python і виконати вказівки в одному з наших зразків. Щоб отримати додаткові вказівки щодо встановлення, відвідайте сторінку «Увімкнути PyTorch із DirectML у Windows» на сайті Microsoft Learn.


Це лише початок наступної глави з DirectML і PyTorch! Слідкуйте за оновленнями, щоб отримати ширший охоплення випадків використання, розширення до інших локальних прискорювачів, як-от NPU, тощо. Наша мета — зустріти розробників там, де вони є, щоб вони могли використовувати правильні інструменти для створення наступної хвилі інновацій ШІ.

 

Ми раді, що розробники продовжуватимуть впроваджувати інновації з передовим Generative AI у Windows і створювати програми AI майбутнього!



Posted on 9. July 2024

Microsoft Photos: Migrating from UWP to Windows App SDK

Microsoft Photos: перехід від UWP до Windows App SDK



Команда Microsoft Photos App нещодавно випустила велике оновлення, змінивши платформу з UWP на Windows App SDK. Ця публікація в блозі документує наш досвід зміни платформи, включаючи деякі вражаючі переваги та цікаві технічні проблеми.


Нова програма «Фотографії» вже повністю розгорнута для Windows Insiders і тепер розгортається для роздрібних клієнтів, починаючи з версії 2024.11050.3002.0 і вище.


Паралельна розробка та переформатування


Будучи однією з найбільш часто використовуваних програм, ми постійно випускаємо нові функції, такі як Slideshow, Background Removal та Generative Erase. Збереження можливості надсилати нові функції, подібні до цих, на UWP, а також прогрес у переході платформи на Windows App SDK було першорядним. Простіше кажучи, це означало, що всі зміни – як нові функції, так і зміни SDK для додатків Windows – повинні були вноситися в нашу основну галузь розробки. Щоб зробити це з найменшими збоями, ми прийняли деякі стратегії, щоб забезпечити сумісність змін коду з обома платформами одночасно:


  1. Перевірка складання Parallel Pull Request для варіантів програми UWP і Windows App SDK

  2. Умовна компіляція (ifdefs) для схожих, але несумісних API

  3. Псевдоніми простору імен для еквівалентних Windows:: і Microsoft:: API


#ifdef WIN_APP_SDK

namespace WUXM = winrt::Microsoft::UI::Xaml::Media;

#else

namespace WUXM = winrt::Windows::UI::Xaml::Media;

#endif

  1. Умовне включення вихідних файлів XAML, оскільки умовна компіляція не підтримується.


Процеси та рівень цілісності


У програмах UWP процеси виконуються на низькому рівні цілісності (lowIL), також відомому як «AppContainer», що означає, що певні API обмежені або можуть вимагати додаткових запитів на підтвердження користувача. У програмах Win32, включаючи Windows App SDK, процеси зазвичай виконуються на середньому рівні цілісності (medium IL), тобто програма має вищий рівень привілеїв.


Використовуючи Windows App SDK, тепер ми можемо зберегти відредагований файл у тій же папці, що й оригінальний файл (наприклад, «foo_edited.jpg»), не вимагаючи від користувача вибору папки призначення.


Через такі причини, як кросплатформна сумісність і перевірка привілеїв, еквівалентні API UWP, такі як StorageFolder.GetFilesAsync, можуть бути на порядки повільнішими, ніж відповідні API Win32, такі як FindNextFile. Це особливо вірно для API файлової системи, і коли ви маєте справу з великими колекціями фотографій, що охоплюють понад 100 000 файлів, різниця в продуктивності може бути значною – секунди проти хвилин.

 

 

PhotosService.exe

Вимагати від користувачів чекати кілька хвилин, щоб переглянути всі їхні медіафайли, не буде чудовим користуванням. Щоб досягти прийнятної продуктивності з версією  Photos App UWP, ми використали багатопроцесну архітектуру, яка включає як основний процес lowIL, так і фоновий процес mediumIL «PhotosService.exe» – обмежена можливість, доступна лише для перевірених видавців.


Реалізація цього вимагала значної складності:


  1. Використання WAP (пакування програм Windows) для упаковки програм UWP і Win32 для розгортання

  2. Додавання обмеженої можливості «runFullTrust» у AppxManifest, щоб дозволити включення виконуваного файлу mediumIL у пакет

Побудова системи IPC (міжпроцесового зв’язку) з використанням Named Pipes для дозволу викликів RPC між двома процесами:

З переходом на Windows App SDK цю складну логіку було видалено та інтегровано в єдиний процес, що значно спростило архітектуру нашої програми та покращило продуктивність завдяки видаленню міжпроцесного зв’язку.


Одним із важливих моментів нового підходу є те, що Photos все ще є багатопотоковою програмою, і для отримання подій сповіщень File System необхідно було реалізувати безголове вікно в окремому потоці, щоб ізолювати його від потоку XAML UI.

 

Windows App SDK Photos Архітектура процесу програми

 

WebView2

Ще однією великою перевагою Windows App SDK є додавання WebView2, побудованого на новому браузері Edge на основі Chromium. Photos App використовує веб-технології в кількох місцях, у тому числі з нашим кросплатформним редактором зображень, який використовується як у OneDrive, так і в Photos App. Серед ключових переваг WebView2:


  1. Підтримка WebGL забезпечує покращену якість візуалізації зображень.

  2. Чудова продуктивність під час обміну високоякісними зображеннями між нативним і веб-шарами за допомогою SharedBuffer.

  3. Підтримка найновішої версії Chromium, яка містить останні вдосконалення та оновлення безпеки.

  4. Дозволяє нам оптимізувати продуктивність нашої служби  AI, яка вимагає надсилання піксельних буферів туди й назад із нашого Web Editor до нашої Native App для визначення  AI


Технічне обслуговування та підтримка

Як програма Inbox (входить до складу Windows), ми маємо переконатися, що Photos працює надійно для користувачів у всіх підтримуваних версіях Windows. У Windows App SDK більшість коду платформи постачається як частина пакета WindowsAppRuntime, на відміну від UWP, де все це постачається як частина операційної системи Windows.


Ключова відмінність між цими двома моделями полягає в тому, що користувачі автоматично отримують найновіші оновлення платформи для Photos App на Windows App SDK, тоді як в UWP їм доведеться чекати, поки ці зміни будуть включені в сервісні виправлення Windows Update.


На практиці це означає, що нам часто доводилося використовувати полізаповнення для виправлення помилок, повторної реалізації відсутніх API або навіть повного відключення функцій у старіших версіях ОС. З Windows App SDK це більше не потрібно, що економить дорогоцінний час розробки та зменшує витрати на тестування, необхідні для різних версій ОС.

Технічні виклики

ASTA vs STA

В UWP модель потоків ґрунтувалася на ASTA (Application Single-Threaded Apartment), яка має механізм захисту потоку інтерфейсу користувача XAML від повторного входу. На відміну від цього, Windows App SDK використовує звичайну модель STA, яка потребує особливої ​​обережності під час виконання певних викликів із потоку інтерфейсу користувача XAML, що інакше може спричинити повторне входження та Stowed Exceptions.


У більшості випадків виправлення полягало б у повторному поставленні в чергу проблемного виклику за допомогою DispatcherQueue, якщо його потрібно виконати в потоці інтерфейсу користувача. Інший підхід полягає в тому, щоб перевантажити певні завдання у фоновий потік, щоб відокремити логіку повторного входу від потоку інтерфейсу користувача.

Підтримка AutoPlay


Однією з головних особливостей Photos є можливість для користувачів підключати флеш-накопичувачі та мобільні телефони, щоб імпортувати свої мультимедійні файли. У Windows App SDK ця функція ще не реалізована, але є хороша альтернатива, використовуючи API оболонки Win32 і desktop3:AutoPlayHandler.


Ця функція працює шляхом розгортання та запуску окремого процесу COM-сервера, який обробляє активацію автоматичного відтворення та запускає робочий процес імпорту Photos App.

Дивлячись вперед


Перехід на Windows App SDK дозволив додатку Photos продовжувати використовувати красиві, згуртовані компоненти рідного інтерфейсу користувача, включені в WinUI, додавши можливість безпосереднього виклику API Win32 і зберігаючи сумісність з більшістю API UWP. З боку платформи перехід на Windows App SDK дає змогу всім користувачам Photos App негайно отримати найновіші покращення стабільності та продуктивності, оскільки Windows App Runtime оновлюється залежно від встановлення пакета Photos App.


Оновлення з UWP на Windows App SDK представляє більшу зміну, ніж попередні оновлення платформи Windows, однак відповідні переваги значно перевищують вартість розробки.



https://i.ytimg.com/vi/-72BHXxS2os/maxresdefault.jpg 


У майбутньому ми скористаємося перевагами Windows App SDK, створивши кожне вікно Photos App, що запускається в окремому процесі – архітектура, яка вже використовується з приголомшливим успіхом у веб-переглядачах на базі Chromium, таких як Microsoft Edge. Насолоджуйтеся цим коротким оглядом майбутніх покращень продуктивності!

 

Ресурси

Щоб дізнатися більше про початок роботи з WinUI & Windows App SDK, відвідайте https://aka.ms/windev і перегляньте ці відео:


Навігація у розробці програм Win32 за допомогою WinUI та WPF | BRK241


Як створити чудовий досвід за допомогою WinUI та WPF | BRK244




Posted on 6. June 2024

Рефакторинг коду з використанням псевдонімів будь-якого типу

Рефакторинг коду з використанням псевдонімів будь-якого типу

Ця стаття є третьою в серії з чотирьох частин, в яких ми розглянемо різні можливості C# 12. У цій частині ми зануримося у функцію «псевдонім будь-якого типу», яка дозволяє створювати псевдонім для будь-якого типу за допомогою директиви using. Ця серія статей дійсно починає набувати гарних рис:


  1. Рефакторинг вашого C# коду за допомогою первинних конструкторів

  2. Рефакторинг вашого C# коду за допомогою виразів колекцій

  3. Рефакторинг C# коду за допомогою псевдонімів для будь-яких типів (ця стаття)

  4. Рефакторинг вашого C# коду для використання лямбда-параметрів за замовчуванням

 

Всі ці можливості продовжують наш шлях до того, щоб зробити наш код більш читабельним і зручним для супроводу, і вважаються «повсякденними можливостями C#», які повинні знати розробники. Давайте зануримося!

Псевдонім будь-якого типу *️⃣

У C# 12 з’явилася можливість псевдонімізувати будь-який тип за допомогою директиви using. Ця функція дозволяє вказувати псевдоніми, які відображаються на інші типи. Це стосується типів кортежів, вказівників, масивів і навіть не відкритих узагальнених типів, і всі вони будуть доступні у вашому коді. Ця можливість є особливо корисною:


  • При роботі з довгими або складними іменами типів.

  • Коли вам потрібно розмежувати типи і вирішити потенційні конфлікти імен.

  • При визначенні типів кортежів значень, які ви маєте намір спільно використовувати у збірці.

  • Коли ви хочете додати ясності до вашого коду, використовуючи більш описові імена.

Офіційна документація C# містить багато прикладів використання цієї можливості, але замість того, щоб повторювати ці приклади тут, я вирішив написати демонстраційну програму, яка ілюструє різні аспекти цієї можливості.

Типи посилань з нульовим значенням

_________________________________________________________________________

 

Ця функція підтримує більшість типів, за єдиним винятком типів посилань, які можна обнулити. Тобто, ви не можете створити псевдонім для nullable reference type, і компілятор C# повідомить про помилку CS9132: Using alias cannot be a nullable reference type. Наступні біти були вилучені зі специфікації функції, щоб допомогти прояснити цей момент:

Зразок додатку: Спостереження НЛО 🛸 

Демонстраційний додаток доступний на GitHub за адресою IEvangelist/alias-any-type. Це простий консольний додаток, який імітує спостереження за непізнаними літаючими об’єктами (НЛО). Якщо ви хочете приєднатися до нього локально, ви можете зробити це будь-яким з наведених нижче способів у робочій директорії на ваш вибір:

За допомогою Git CLI:

git clone https://github.com/IEvangelist/alias-any-type.git


За допомогою GitHub CLI:

gh repo clone IEvangelist/alias-any-type

Завантажте zip-файл:


Якщо ви бажаєте завантажити вихідний код, zip-файл доступний за наступною URL-адресою:

Щоб запустити програму, з кореневого каталогу виконайте наступну команду .NET CLI:

dotnet run —project ./src/Alias.AnyType.csproj


Коли програма запускається, вона друкує вступ до консолі і чекає на введення даних користувачем, перш ніж продовжити роботу.


Після натискання будь-якої клавіші, наприклад, клавіші Enter, програма випадковим чином генерує дійсні координати (широту і довготу), а потім, використовуючи ці координати, отримує метадані геокоду, пов’язані з координатами. Координати представлені у форматі градусів-хвилин-секунд (включаючи кардинальність). Під час роботи програми обчислюються відстані між згенерованими координатами, які подаються як спостереження НЛО.



Щоб зупинити програму, натисніть клавіші Ctrl + C.


Хоча цей додаток простий, він включає в себе інші частини C#, які не обов’язково мають відношення до нашої теми в цій статті. Я намагатимусь не зачіпати периферійні теми, але торкатимусь їх, коли вважатиму їх важливими.

Покрокове ознайомлення з кодом 👀

 

Ми використаємо цей розділ, щоб разом пройтися по коду. Є кілька цікавих аспектів коду, які я хотів би висвітлити, включаючи файл проекту, GlobalUsings.cs, деякі розширення та файл Program.cs. З наявного коду є кілька речей, які ми не будемо розглядати, наприклад, моделі реагування та деякі утилітарні методи.


Почнемо з розгляду файлу проекту:
Перше, на що слід звернути увагу, це те, що властивість ImplicitUsings має значення enable. Ця властивість з’явилася у C# 10 і дозволяє цільовому SDK (у цьому випадку Microsoft.NET.Sdk) неявно включати набір просторів імен за замовчуванням. Різні SDK включають різні простори імен за замовчуванням, для отримання додаткової інформації див. документацію про неявне використання директив.

Директиви неявного використання 📜


Елемент ImplicitUsing є особливістю MS Build, тоді як ключове слово global є особливістю мови C#. Оскільки ми обрали глобальне використання, ми також можемо скористатися цією можливістю, додавши наші власні директиви. Одним із способів додавання цих директив є додавання елементів Using у групу ItemGroup. Деякі директиви використання додаються з атрибутом Static, встановленим у true, що означає, що всі їхні static члени доступні без обмежень – докладніше про це пізніше. Атрибут Alias використовується для створення псевдоніма для типу, у цьому прикладі ми вказали псевдонім AsyncCancelable для типу System.Runtime.CompilerServices.EnumeratorCancellationAttribute. У нашому коді тепер ми можемо використовувати AsyncCancelable як псевдонім типу для атрибуту EnumeratorCancellation. Інші елементи Using створюють нестатичні та неалієсовані директиви global using для відповідних просторів імен.

 

Закономірність, що з’являється 🧩 

 

Ми починаємо спостерігати, як у сучасних кодових базах .NET з’являється загальний шаблон, коли розробники визначають файл GlobalUsings.cs для інкапсуляції всіх (або більшості) директив використання в одному файлі. Ця демонстраційна програма слідує цьому шаблону, давайте подивимось на файл далі:


Все у цьому файлі є директивою global using, що робить типи псевдонімів, статичні члени або простори імен доступними у всьому проекті. Перші три директиви призначені для загальних просторів імен, які використовуються у багатьох місцях програми. Наступна директива – це директива global using static для простору імен System.Math, яка робить всі статичні члени Math доступними без обмежень. Решта директив – це директиви global using, які створюють псевдоніми для різних типів, включаючи кілька кортежів, потік координат і CancellationTokenSource, на яке тепер можна просто посилатися через Signal.


Варто врахувати, що коли ви визначаєте тип псевдоніма кортежу, ви можете легко перейти до типу record, якщо вам потрібно додати поведінку або додаткові властивості. Наприклад, пізніше ви можете вирішити, що дійсно хочете додати деяку функціональність до типу Coordinates, ви можете легко змінити його на тип record:


 

Коли ви визначаєте псевдонім, ви фактично створюєте не тип, а ім’я, яке посилається на існуючий тип. У випадку визначення кортежів, ви визначаєте форму кортежу значень. Коли ви називаєте тип масиву псевдонімом, ви не створюєте новий тип масиву, а скоріше називаєте його псевдонімом, можливо, з більш описовою назвою. Наприклад, коли я визначаю API, який повертає IAsyncEnumerable, це дуже багато для написання. Натомість тепер я можу посилатися на тип, що повертається, як CoordinateStream у своїй кодовій базі.

Посилання на псевдоніми 📚

 

Було визначено декілька псевдонімів, деякі у файлі проекту, а інші у файлі GlobalUsings.cs. Давайте подивимося, як ці псевдоніми використовуються у коді. Почнемо з розгляду файлу верхнього рівня Program.cs:

 

У попередньому фрагменті коду показано, як псевдонім Signal використовується для створення екземпляру CancellationTokenSource. Як ви знаєте, клас CancellationTokenSource є реалізацією IDisposable, тому ми можемо використовувати інструкцію using, щоб гарантувати, що екземпляр Signal буде належним чином утилізовано, коли він вийде за межі області видимості. Ваша IDE розуміє ці псевдоніми, і коли ви наведете на них курсор, ви побачите фактичний тип, який вони представляють. Погляньте на наступний знімок екрана:


Вступ записується на консоль з виклику WriteIntroduction, безпосередньо перед входом в try / catch. Блок try містить цикл await foreach, який перебирає IAsyncEnumerable. Метод GetCoordinateStreamAsync визначено в окремому файлі. Я частіше використовую функціональність partial class, коли пишу програми верхнього рівня, оскільки це допомагає ізолювати проблеми. Уся функціональність, що базується на HTTP, визначена у файлі Program.Http.cs, давайте зосередимося на методі GetCoordinateStreamAsync:


 

Ви помітите, що він повертає псевдонім CoordinateStream, який є IAsyncEnumerable. Він приймає атрибут AsyncCancelable, який є псевдонімом для типу EnumeratorCancellationAttribute. Цей атрибут використовується для оформлення маркера скасування таким чином, щоб він використовувався разом з IAsyncEnumerable для підтримки скасування. Поки скасування не запитується, метод генерує випадкові координати, отримує метадані геокоду і повертає новий екземпляр CoordinateGeoCodePair. Метод GetGeocodeAsync запитує метадані геокоду для заданих координат, і у разі успіху повертає модель відповіді GeoCode. Наприклад, Microsoft Campus має такі координати:

Щоб переглянути JSON, відкрийте це посилання у вашому браузері. Тип CoordinateGeoCodePair не є псевдонімом, але це readonly record struct, яка містить Coordinates та GeoCode:

Повертаючись до класу Program, коли ми повторюємо кожну пару координати-геокод, ми деконструюємо кортеж на екземпляри типу Coordinates і GeoCode. Тип Coordinates є псевдонімом для кортежу з двох double значень, що представляють широту і довготу. Знову ж таки, наведіть курсор на цей тип у вашому IDE, щоб швидко побачити тип, подивіться на наступний знімок екрана:


Тип GeoCode  - це модель відповіді, яка містить інформацію про метадані геокоду. Потім ми використовуємо метод розширення, щоб перетворити Coordinates в кардиналізований рядок, який є рядковим представленням координат у форматі градусів-хвилин-секунд. Особисто мені подобається, як легко використовувати псевдоніми у вашій кодовій базі. Давайте розглянемо деякі методи розширення, які розширюють або повертають псевдонімні типи:

 

 

Цей метод розширення розширює тип псевдоніма Coordinates і повертає рядкове представлення координат. Він використовує метод розширення ToDMS для перетворення широти і довготи у формат градусів-хвилин-секунд. Метод розширення ToDMS визначається наступним чином:

Якщо ви пам’ятаєте, псевдонім DMS – це кортеж з трьох значень, що представляють градуси, хвилини та секунди. Метод розширення ToDMS приймає значення double і повертає кортеж DMS. Метод розширення ToCardinal використовується для визначення кардинального напрямку координат і повертає значення N, S, E або W. Методи Abs, Sign і Floor є статичними членами простору імен System.Math, псевдонім якого міститься у файлі GlobalUsings.cs.


Крім того, програма відображає деталі спостереження НЛО на консолі, включаючи координати, метадані геокоду та відстань, пройдену між спостереженнями. Це відбувається постійно, доки користувач не зупинить програму комбінацією клавіш Ctrl + C.

Наступні кроки 🚀

Не забудьте спробувати це у своєму власному коді! Поверніться до останньої частини цієї серії статей, де ми розглянемо параметри лямбда за замовчуванням. Щоб продовжити дізнаватися більше про цю функцію, відвідайте наступні ресурси:

 




Posted on 2. May 2024

Захистіть збірку контейнера та публікуйте за допомогою .NET 8

Захистіть збірку контейнера та публікуйте за допомогою .NET 8


.NET 8 піднімає планку безпеки контейнерів для образів контейнерів .NET та інструментів SDK. За замовчуванням SDK створює образи додатків, які відповідають найкращим галузевим практикам і стандартам. Ми також пропонуємо додаткове посилення безпеки за допомогою образів Chiseled для додаткового рівня захисту.


dotnet publish створить для вас образ контейнера і за замовчуванням налаштує його як non-root. За допомогою .NET дуже просто швидко покращити безпеку ваших виробничих додатків.


У цій статті ви дізнаєтеся, як це зробити:

  • Створення образів non-root контейнерів

  • Налаштуйте Kubernetes, щоб вимагати non-root образи

  • Перевірка образів і контейнерів

  • Використання root  (або інших користувачів)


Ця стаття є продовженням статті Оптимізуйте збірку та публікацію контейнерів за допомогою .NET 8, опублікованої раніше цього місяця. Вона базується на статтях Захистіть свої хмарні додатки .NET за допомогою безкореневих Linux Containers та Запуск non-root контейнерів .NET за допомогою Kubernetes, опублікованих минулого року.


Модель загроз 

Будь-яку розмову про безпеку варто починати з чіткого уявлення про існуючі загрози.


Існує дві основні загрози, які слід враховувати:



Незважаючи на те, що Docker не продається як програмне забезпечення для пісочниці, його налаштування за замовчуванням призначене для захисту ресурсів хоста від доступу до них процесів всередині контейнера.


Це чудовий опис ситуації, від втечі з контейнерів Docker та Kubernetes до root на хості (з посиланням на CVE-2019-5736). Автор говорить, що ми всі разом дуже покладаємося на «налаштування за замовчуванням» різних контейнерних рішень, які ми використовуємо, маючи на увазі, що прорив контейнера є реальною загрозою.


З тієї ж публікації, в розділі «Mitigations»:


Використовуйте низькопривілейованого користувача всередині контейнера


Тут автор фактично говорить про те, що вам потрібно зробити свій внесок, щоб безпечніше покладатися на псевдо-пісочницю контейнерних рішень. Якщо ви цього не зробите, і буде виявлено чергову вразливість контейнерів, то частина тягаря ляже на розробників, які розміщують свої додатки з правами root. Інакше кажучи, «caveat emptor».


У ландшафті безпеки та вразливостей може бути важко орієнтуватися навіть у найкращі часи. Актуалізація залежностей – це перший і найважливіший спосіб зменшити ці ризики, як для хоста, так і для гостя контейнера. Non-root хостинг є чудовим заходом глибокого захисту, який може захистити від невідомих майбутніх вразливостей.

Контейнерна екосистема: root за замовчуванням

 

Базові образи за замовчуванням налаштовано під користувачем root .

Після того, як я пояснив, що образи слід налаштовувати як non-root як важливий захід безпеки, я демонструю, що більшість базових образів публікуються з правами root, в тому числі і ті, які публікуємо ми. Чому?


Зручність використання переважає над безпекою для базових образів загального призначення і завжди буде переважати. Важливо, щоб керування пакунками та інші привілейовані операції були простими і щоб образи вищих рівнів могли вибирати потрібного користувача.


Однак, залишається вірним, що зловмисник з активною RCE-уразливістю зможе робити все, що завгодно, маючи привілеї root.


На відміну від них, базові образи Ubuntu Chiseled і Chainguard орієнтовані на пристрої і використовують інший підхід, ніж образи загального призначення. Вони обмінюють зручність використання і сумісність на безпеку. Ми підтримуємо цю точку зору.


Примітка: див. Образи захищених контейнерів: Зображення для безпечного ланцюга постачання.


Це багато контексту про базові образи і відмінний перехід до образів додатків, які (на нашу думку) повинні бути побудовані з філософією безпеки в першу чергу.

.NET екосистеми: Non-root за замовчуванням

За замовчуванням dotnet publish створює образи без права доступу до кореневого каталогу. Давайте подивимося на це за допомогою простої консольної програми. Я пропущу ряд кроків, які описано у статті Спрощення збірки контейнера та публікації за допомогою .NET 8.


Це вихідний код програми.

Створити зображення контейнера дуже просто.

 

 

Додаток привітається з користувачем, який запускає процес, як ви можете бачити з вихідного коду.

 

Як і очікувалося, ми бачимо Hello app.


Ми також можемо запустити whoami так само, як це було зроблено з базовими зображеннями.

 

Як видно, цей образ не використовує root, на відміну від базових образів, які ми розглянули.


Запуск whoami вимагає запуску образу. Kubernetes не робить цього; він дивиться на метадані зображення контейнера, щоб визначити користувача.


Давайте подивимося на метадані контейнера.

 


SDK встановлює користувача за допомогою UID, оскільки це вимагається Kubernetes для застосування властивості runAsNonRoot.


Ми можемо зазирнути трохи глибше, щоб побачити, звідки береться значення 1654.

 

 

Ми визначаємо користувача з ім’ям app і даємо йому UID > 1000, щоб уникнути зарезервованих діапазонів. 1654 - це 1000  + ASCII-значення кожного з символів у dotnet. Ми також встановлюємо змінну оточення – APP_UID – з таким самим значенням. Це дозволяє уникнути необхідності запам’ятовувати або використовувати це значення (без змінної оточення) для звичайних сценаріїв.


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

Non-root Dockerfiles

Модель з Dockerfiles схожа, але вимагає одного додаткового кроку – встановлення інструкції USER .


Я покажу вам, як це виглядає, використовуючи цей приклад Dockerfile.


Цей Dockerfile використовує змінну оточення, яку ми щойно розглянули, для визначення користувача. Це шаблон, який ми хочемо, щоб усі використовували для переходу до користувача без прав суперкористувача за допомогою Dockerfiles. Знову ж таки, цей шаблон дозволяє уникнути повсюдного використання магічних чисел і найкраще працює у Kubernetes.

Примітка: Багато розробників вже створили власного користувача. Продовження роботи з власним користувачем або перемикання на вбудованого – обидва варіанти є чудовими.


Після цього ми можемо створити і запустити образ.

 

 

Як бачите, програма працює від імені користувача app.

Перемикач для увімкнення non-root  хостингу (у Dockerfiles) – це лише зміна одного рядка.

Ubuntu Chiseled образи

Образи Ubuntu Chiseled схожі на пристрої, що надають заблокований досвід роботи за замовчуванням. Вони сумісні зі звичайною Ubuntu, проте мають гострі краї, де вирізані цілі розділи операційної системи. Примітно, що вони налаштовані як non-root. Це означає, що вам навіть не потрібно налаштовувати користувача, оскільки він вже налаштований.


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

 

 

У нас є інший приклад Dockerfile, який покладається на користувача, встановленого в цих зображеннях.

 

Як ви можете бачити, у цьому Dockerfile не задано USER. Давайте зберемо і запустимо його.