Syntax | سینتکس – Telegram
Freak
Maslak
5👍2👎2🔥1🥰1
چند نکته درباره Dockerfile

۱. بدون دسترسی روت:
- اجرای کانتینر با کاربر غیر روت برای امنیت بیشتر

۲. ساخت چند مرحله‌ای (Multistage Build):
- کاهش حجم نهایی ایمیج
- جداسازی محیط build از محیط اجرا
مثال:
FROM golang:1.23 AS build
WORKDIR /src
COPY main.go .
RUN go build -o /bin/hello ./main.go

FROM scratch
COPY --from=build /bin/hello /bin/hello

CMD ["/bin/hello"]


۳. استفاده از Distroless یا From Scratch:
- حذف ابزارهای غیرضروری برای کاهش سطح حمله
- استفاده از ایمیج‌های پایه حداقلی
مثال:
FROM gcr.io/distroless/nodejs
COPY --from=builder /app/dist .
CMD ["app.js"]


۴. استفاده از ایمیج‌های مطمئن:
- استفاده از ایمیج‌های رسمی از Docker Hub
- بررسی منبع و تاریخچه ایمیج‌ها

۵. به‌روزرسانی منظم ایمیج:
- به‌روزرسانی مرتب پایه ایمیج برای دریافت پچ‌های امنیتی
- استفاده از CI/CD برای ساخت خودکار ایمیج‌های جدید

۶. پورت‌های در معرض (Exposed Ports):
- فقط پورت‌های ضروری را expose کنید
- مستندسازی پورت‌های مورد نیاز
مثال:
EXPOSE 8080


۷. عدم قرار دادن کلیدها و رمزها در Dockerfile
- استفاده از secrets یا متغیرهای محیطی
مثال:
# bad idea
ENV DB_PASSWORD=secretpass

# recommended
ARG DB_PASSWORD


۸. مدیریت لایه‌ها (Layer Sanity):
- ترکیب دستورات مرتبط برای کاهش تعداد لایه‌ها
- حذف فایل‌های موقت در همان لایه
مثال:
RUN apt-get update && \
apt-get install -y package1 package2 && \
rm -rf /var/lib/apt/lists/*


۹. برچسب‌های متادیتا:
- افزودن اطلاعات مفید درباره ایمیج
مثال:
LABEL maintainer="email@example.com"
LABEL version="1.0"
LABEL denoscription="Application denoscription"


نکات تکمیلی:
- همیشه از .dockerignore برای ایگنور شدن فایل‌های غیرضروری استفاده کنید
- دستورات را به ترتیب بهینه قرار دهید (از کمترین تغییر به بیشترین)
- از کش Docker به درستی استفاده کنید

#docker

@Syntax_fa
👍12🔥31🥰1
سوال درباره داکر و داکر کمپوز

سوال:

فرض کنید ما چند سرویس داریم که در یک پروژه با استفاده از Docker Compose مدیریت می‌شوند. این سرویس‌ها نیازی به ارتباط با خارج از شبکه داخلی داکر (مانند شبکه هاست یا اینترنت) ندارند و فقط باید به‌صورت داخلی با یکدیگر ارتباط برقرار کنند. حتی اگر به اشتباه پورت‌هایی برای آن‌ها در فایل Docker Compose تعریف شود (مانند ports)، نباید این پورت‌ها از بیرون شبکه داکر در دسترس باشند.

چگونه می‌توانیم چنین محدودیتی اعمال کنیم و اطمینان حاصل کنیم که سرویس‌ها کاملاً ایزوله هستند و فقط در شبکه داخلی داکر قابل دسترسی‌اند؟
(جواب و راه حلی پیشنهادی پست بعدی گذاشته میشه)

#docker #docker_compose

@Syntax_fa
🤔6👍51🔥1
Syntax | سینتکس
سوال درباره داکر و داکر کمپوز سوال: فرض کنید ما چند سرویس داریم که در یک پروژه با استفاده از Docker Compose مدیریت می‌شوند. این سرویس‌ها نیازی به ارتباط با خارج از شبکه داخلی داکر (مانند شبکه هاست یا اینترنت) ندارند و فقط باید به‌صورت داخلی با یکدیگر ارتباط…
داکیومنت داکر اینو میگه:
internal
By default, Compose provides external connectivity to networks. internal, when set to true, lets you create an externally isolated network.


برای حل این مسئله، می‌توانیم از شبکه‌های داخلی (internal network) در Docker Compose استفاده کنیم. شبکه داخلی یک شبکه‌ای است که داکر فراهم می‌کند و ارتباط سرویس‌ها فقط در داخل همان شبکه امکان‌پذیر است. به این ترتیب، سرویس‌ها کاملاً ایزوله می‌شوند و هیچ ارتباطی با خارج از شبکه داکر (مانند هاست یا اینترنت) برقرار نمی‌کنند، حتی اگر به اشتباه پورت‌هایی در فایل Compose تعریف شود.

1. ایجاد شبکه داخلی در فایل `docker-compose.yml`:

در فایل Docker Compose، می‌توانید یک شبکه داخلی تعریف کنید. در این شبکه، سرویس‌ها فقط می‌توانند با یکدیگر ارتباط برقرار کنند و هیچ ارتباطی با شبکه هاست یا اینترنت ندارند.

مثال:

   version: '3.9'
services:
service1:
image: my-image-1
networks:
- internal_network
service2:
image: my-image-2
networks:
- internal_network

networks:
internal_network:
internal: true


توضیحات:
- در بخش networks`، یک شبکه به نام `internal_network تعریف شده و ویژگی internal: true به آن اضافه شده است.
- این شبکه فقط برای ارتباط داخلی بین سرویس‌های تعریف‌شده در Docker Compose در دسترس است.
- هیچ پورت خارجی (حتی اگر در بخش ports تعریف شده باشد) از خارج شبکه داکر قابل دسترسی نخواهد بود.

#docker #docker_compose

@Syntax_fa
👍19👎1
interpolation vs concatenation

Interpolation

در برنامه‌نویسی، "interpolated" به معنای "درون‌گذاری" است و به تکنیکی اشاره دارد که در آن مقادیر متغیرها یا عبارات درون یک رشته (string) قرار می‌گیرند. این تکنیک به برنامه‌نویسان این امکان را می‌دهد که به راحتی مقادیر متغیرها را درون رشته‌ها قرار دهند بدون اینکه نیاز به استفاده از عملگرهای الحاق (concatenation) باشد.

به عنوان مثال، در زبان‌های برنامه‌نویسی مانند Python، می‌توان از f-strings برای درون‌گذاری استفاده کرد:

name = "ممد"
age = 22
greeting = f"سلام، نام من {name} است و من {age} سال دارم."
print(greeting)


در این مثال، مقادیر متغیرهای name و age به طور مستقیم درون رشته قرار می‌گیرند و خروجی به صورت زیر خواهد بود:

سلام، نام من ممد است و من 22 سال دارم.


در زبان‌های دیگر نیز تکنیک‌های مشابهی برای درون‌گذاری وجود دارد، مانند استفاده از fmt.PrintF در Go یا Template Literals در JavaScript.

Concatenation

به معنای ترکیب دو یا چند رشته (string) به یک رشته واحد است. در این روش، معمولاً از عملگر + یا متدهای خاصی برای Concatenation استفاده می‌شود. به عنوان مثال، در زبان Python می‌توان به این شکل عمل کرد:

name = "ممد"
age = 22
greeting = "سلام، نام من " + name + " است و من " + str(age) + " سال دارم."
print(greeting)


در این مثال، رشته‌ها با استفاده از عملگر + به هم متصل شده‌اند.

تفاوت‌ها:


1. خوانایی:
-ا Interpolation معمولاً خواناتر است، زیرا مقادیر متغیرها به وضوح درون رشته قرار می‌گیرند و نیازی به استفاده از عملگرهای concatenation نیست.
- در concatenation ممکن است رشته‌ها به هم چسبیده شوند و خوانایی کمتری داشته باشند.

2. عملکرد:
-ا Interpolation معمولاً بهینه‌تر است، زیرا در بسیاری از زبان‌ها، موتور زبان می‌تواند به طور بهینه‌تری رشته‌ها را پردازش کند.
- در concatenation به ویژه اگر تعداد زیادی رشته را به هم متصل کنید، ممکن است عملکرد کاهش یابد، زیرا هر بار که یک رشته جدید ایجاد می‌شود، حافظه جدیدی تخصیص داده می‌شود.

#tips

@Syntax_fa
👍13
فایل داکر کمپوز «ساختار پروژه سینتکس» رو آپدیت کردیم:
https://github.com/syntaxfa/django-structure/blob/main/compose.yml

میشه بعضی قسمت هارو خیلی کوتاه ترش کرد مثل تعریف والیوم ها ولی از وربوس بودن بیشتر خوشم میاد و با چند خط بیشتر کد زدن مشکلی ندارم.
همچنین بعضی ویژگی هایی که تعریف شده جنبه آموزشی داره مثل lables هایی که برای سرویس ها تعریف شده.
میشه داخل Dockerfile هم اینکار رو انجام داد.

#docker

@Syntax_fa
👍8🔥3
Forwarded from Python Hints
می‌خوام راجب این صحبت کنم (از پروفایل خودم).

من پیغمبر مخالفت با اهمیت تعداد کامیت بودم و هستم؛ حداقل ۳-۴ ساله دارم این حرف رو میزنم و دلیلش رو هم گفتم (اینکه چندتا گیت‌هاب خودم به اینو اون دادم و ...)

ولی یک جو احمقانه توی لینکدین و توییتر راه افتاده ضد این بخش؛ ببین از من که گذشته ولی این صحبت‌های احمقانه برای کل جامعه برنامه‌نوبسی بد هست چند مورد :

۱- کسی که پروفایلش انقدر کامیت داره؛ حرفه‌ای نیست چون شرکت‌های بزرگ خودشون گیت‌لب دارند و ...

همینجا جواب این رو میدم:
احمق جون تو تازه‌کاری گیت‌لب زمانی به یک سری باگ‌ها خورد (توی یوتیوب سرچ کنید) که خیلی شرکت‌ها برگشتند روی گیت‌هاب و نسخه organization رو خرید زدند.
خیلی از فعالیت‌های گیت‌هاب من ازونجا شروع شد.

۲- اینا همش ادا بازیه و ...

حماقت محض
هست این حرف؛ اگر به اینجا رسیدی که این حرف رو زدی (شما تا حالا کسی رو دیدی عکس این کاشی‌کاری رو توی رزومه‌اش بذاره ؟)
هیچ شرکت و یا شخص با سوادی رو نمی‌شناسم که حتی ۱ درصد این موزاییک براش مهم باشه (مگر بچه‌هایی که روش نقاشی می‌کشند. اونم کل کل برنامه نویسی هست البته)

و چیزهای از این دست.
در نهایت اینکه؛ من خودم بیشتر کامیت‌های گیت‌هابم برای کارهای شخصی (اسکریپت؛ ایده؛ داکیومنت؛ کانفیگ و حتی تمرین هست)

از این 2176 تا کامیت شاید 700-800 تاش برای شرکت‌هایی هست که روی گیت‌هاب هستند؛ باقیش کارهای خودمه؛ و حتی اگر یک روز تا ۱۰ شب هم سرکار باشم هرطور شده باید تا آخر شب ۲-۳ تا مطلب کتابی که خوندم رو برای خودم تمرین کنم (این بدترین حالت هست).

ولی خیلی وقتا تیکه کدی زده شده توی شرکت که بنظرم راه خوبی نبوده و باگ میخوره؛ روی گیت‌هاب خودم یک سناریو مشابه براش درست می‌کنم و سعی می‌کنم اون مشکل رو حل کنم یا پروفایلینگ براش بگیرم و اپتیمایز کنم چون من خالق همه پروژه‌های شرکت‌ها نیستم و خیلی وقتا بیزینس بهم اجازه نمیده روش رو تغییر بدم.

خلاصه که وظیفه ما :
هشدار دادن راجب افراد سودجو بود؛ که نیروی HR به این کاشی کاری گیت‌هاب اهمیتی نده برای دعوت به مصاحبه.
اما این موج تخریب افراد تازه‌کار و با انگیزه بالا هم کاری بس کثیف‌تر هست که مطمئنم از جامعه توسعه دهنده شروع نشده.
مثال از خودم زدم برای حمایت از تمام دولوپرهای تازه‌کار و با انگیزه دمتون
گرم ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
👏25👍9👎1
این Swap Memory خبیث چیه و چرا بهتره غیرفعالش کنیم؟

در سیستم‌عامل‌های لینوکسی (و سایر سیستم‌های مشابه)، Swap Memory به عنوان یک حافظه‌ی مجازی مورد استفاده قرار می‌گیرد. وقتی رم (RAM) سیستم پر می‌شود، سیستم از بخشی از فضای دیسک (HDD یا SSD) به عنوان حافظه‌ی موقت استفاده می‌کند. این فضای موقت همان Swap است. اگرچه این ویژگی در مواقع خاص مفید است، اما در برخی موارد می‌تواند مشکلاتی ایجاد کند که به همین دلیل به Swap Memory خبیث مشهور شده است.

چرا Swap Memory مشکل‌ساز می‌شود؟


1. کندی عملکرد سیستم
وقتی سیستم به جای رم از Swap استفاده می‌کند، سرعت به شدت کاهش می‌یابد. دلیل این امر این است که هارد دیسک یا SSD به مراتب کندتر از رم است. به همین دلیل، اجرای برنامه‌ها و پردازش‌ها به شدت کند می‌شود.

2. افزایش فشار بر هارد دیسک یا SSD
استفاده مداوم از Swap باعث فشار زیاد بر دیسک می‌شود. در مورد SSD، این موضوع می‌تواند عمر دیسک را به شدت کاهش دهد.

3. مدیریت نامناسب حافظه
در برخی موارد، سیستم به جای آزاد کردن رم‌های غیرضروری به Swap منتقل می‌شود. این موضوع می‌تواند باعث شود که حتی وقتی رم کافی دارید، سیستم همچنان کند عمل کند.

آیا باید Swap Memory را غیرفعال کنیم؟


در سیستم‌هایی که رم کافی دارند (مثلاً 12 گیگابایت یا بیشتر)، معمولاً نیازی به Swap نیست و می‌توان آن را غیرفعال کرد. با این کار، سیستم مجبور می‌شود مدیریت حافظه را بهینه‌تر انجام دهد و از منابع رم به شکل بهتری استفاده کند.

اما اگر سیستم شما رم محدودی دارد (مثلاً کمتر از 12 گیگابایت)، غیرفعال کردن Swap می‌تواند باعث کرش برنامه‌ها در صورت پر شدن رم شود. در این حالت، باید با احتیاط عمل کنید.

چطور Swap Memory را غیرفعال کنیم؟


برای غیرفعال کردن Swap Memory در سیستم‌های لینوکسی، می‌توانید مراحل زیر را دنبال کنید:

1. بررسی وضعیت فعلی Swap
ابتدا بررسی کنید که آیا Swap فعال است یا خیر:

swapon --show

اگر خروجی نمایش داده شود، یعنی Swap فعال است.

2. غیرفعال کردن موقتی Swap

برای غیرفعال کردن موقتی Swap (تا زمان بوت بعدی):

sudo swapoff -a

این دستور تمام Swapهای فعال را غیرفعال می‌کند.

3. غیرفعال کردن دائمی Swap

برای غیرفعال کردن دائمی، باید Swap را از فایل تنظیمات سیستم حذف کنید. مراحل زیر را انجام دهید:

- فایل /etc/fstab را ویرایش کنید:

sudo nano /etc/fstab

- خط مربوط به Swap را پیدا کنید. معمولاً چیزی شبیه به این است:

/swapfile none swap sw 0 0

- آن خط را کامنت کنید (با اضافه کردن # در ابتدای خط) یا حذف کنید:

#/swapfile none swap sw 0 0

- فایل را ذخیره کنید و خارج شوید.

در نهایت پس از ریبوت، بررسی کنید که دیگر Swap فعال نیست:

swapon --show


#swap_memory

@Syntax_fa
👍14🔥5👎4😁1
دوستان این کتاب دارای مطالبی هست که توی منابع فارسی پیدا نمیشه..
حتی اگر جنگو رو فول هستین بازم نیم نگاهی بهش بندازید🔥

@Syntax_fa
🔥7👍1
Media is too big
VIEW IN TELEGRAM
قدیمی ترین وب سایت هایی که هنوزم آنلاینن!

#fun

@Syntax_fa
👍91
ران کردن پرایوت داکر رجیستری بصورت سلف هاست خیلی ساده و راحت:
https://github.com/syntaxfa/docker-registry

#docker

@Syntax_fa
🔥9👍21
🔍 ا- Forward Proxy و Reverse Proxy چیست؟

💡 Forward Proxy (پروکسی فوروارد)
ا. Forward Proxy، به زبان ساده، یک واسطه بین کاربر (Client) و اینترنت است. وقتی شما از یک Forward Proxy استفاده می‌کنید، در واقع درخواست‌های خودتون رو از طریق این سرور واسطه به مقصد (سرور اصلی) می‌فرستید.

🔑 ویژگی‌ها و کاربردها:
1. ناشناس‌سازی (Anonymity): IP اصلی شما مخفی میشه و سرور مقصد فقط IP پروکسی رو می‌بینه.
2. دور زدن محدودیت‌ها: برای دسترسی به سایت‌هایی که در منطقه‌ی شما فیلتر یا محدود هستن، می‌تونید از Forward Proxy استفاده کنید.
3. کشینگ (Caching): این پروکسی می‌تونه درخواست‌های تکراری رو کش کنه و سرعت دسترسی رو افزایش بده.
4. کنترل دسترسی: مدیران شبکه از Forward Proxy برای محدود کردن دسترسی به اینترنت یا نظارت بر ترافیک استفاده می‌کنن.

📊 نحوه کار Forward Proxy:
- کاربر درخواست خودش رو به پروکسی می‌ده.
- پروکسی درخواست رو به سرور مقصد می‌فرسته.
- سرور مقصد پاسخ رو به پروکسی می‌ده و پروکسی پاسخ رو به کاربر برمی‌گردونه.

> مثال: فرض کنید در یک سازمان هستید و می‌خواهید به سایتی دسترسی داشته باشید. درخواست شما از طریق سرور Forward Proxy سازمان عبور می‌کنه.


💡 Reverse Proxy (پروکسی معکوس)
دقیقاً برعکس Forward Proxy عمل می‌کنه. در اینجا سرور Reverse Proxy یک واسطه بین کاربر (Client) و یک یا چند سرور داخلی (Backend Servers) است.

🔑 ویژگی‌ها و کاربردها:
1. افزایش امنیت: سرورهای بک‌اند پشت Reverse Proxy پنهان می‌شن و از دید کاربران مخفی هستن.
2. توزیع بار (Load Balancing): درخواست‌ها بین چندین سرور توزیع می‌شن تا ترافیک بهینه بشه.
3. کشینگ: Reverse Proxy می‌تونه محتوای استاتیک رو کش کنه و فشار روی سرورهای اصلی رو کاهش بده.
4. SSL Termination: رمزنگاری و رمزگشایی SSL می‌تونه توسط Reverse Proxy انجام بشه، که بار پردازشی سرورهای اصلی رو کم می‌کنه.

📊 نحوه کار Reverse Proxy:
- کاربر درخواست خودش رو به Reverse Proxy می‌فرسته.
- Reverse Proxy درخواست رو به یکی از سرورهای داخلی هدایت می‌کنه.
- سرور داخلی پاسخ رو به Reverse Proxy می‌ده و سپس Proxy جواب رو به کاربر برمی‌گردونه.


🛠 کاربردهای عملی
- Forward Proxy:
استفاده از VPN یا سرویس‌های پروکسی عمومی برای دسترسی به سایت‌های محدود.
- Reverse Proxy:
استفاده از Nginx یا HAProxy برای توزیع بار و افزایش امنیت در سرورهای وب.


📌 اگر این پست براتون مفید بود، حتماً با دوستاتون به اشتراک بذارید! 😊

#proxy

@Syntax_fa
👍13🔥5
This media is not supported in your browser
VIEW IN TELEGRAM
وقتی بعد یه هفته میشینی پای سیستم کار کنی😁

#fun

@Syntax_fa
😁31
معرفی پکیج `axel`

پکیج axel یک ابزار کامند لاینی برای دانلود فایل‌ها از اینترنت است. این ابزار با استفاده از تکنیک‌های چندرشته‌ای (multi-threading) و تقسیم فایل به بخش‌های کوچک‌تر، می‌تواند سرعت دانلود را بهبود بخشد.

ویژگی‌های کلیدی `axel`:


1. چندرشته‌ای: axel می‌تواند یک فایل را به چندین بخش تقسیم کند و هر بخش را به‌طور همزمان دانلود کند.

2. پشتیبانی از پروتکل‌های مختلف: axel از پروتکل‌های HTTP, HTTPS و FTP پشتیبانی می‌کند.

3. قابلیت ادامه دانلود: اگر دانلود به هر دلیلی متوقف شود، axel می‌تواند دانلود را از نقطه‌ای که متوقف شده ادامه دهد.

4. سازگاری با اسکریپت‌ها: به‌عنوان یک ابزار خط فرمان، axel به راحتی می‌تواند در اسکریپت‌ها و اتوماسیون‌ها استفاده شود.

5. سبک و سریع: axel به‌طور کلی سبک‌تر و سریع‌تر از برخی دیگر از ابزارهای دانلود است.

نصب axel در توزیع‌های مبتنی بر Debian (مانند اوبونتو):

  sudo apt-get update
sudo apt-get install axel


نحوه استفاده از axel
اول axel —help رو میزنیم تا راهنمایی پکیج رو ببینیم.
اپشن های مختلفی داره مثل:
-s (Specify maximum speed (bytes per second))
حداکثر سرعت دانلود بر حسب بایت
-n (Specify maximum number of connections)
تعداد ترد ها


برای دانلود یک فایل با استفاده از axel با پنج ترد می‌توانید از دستور زیر استفاده کنید:
axel -n 5 <URL> .


#axel

@Syntax_fa
👍12
ادایی ترین برنامه نویس دنیا رو پیدا کردیم

Source

#fun

@Syntax_fa
😁41👍4
استفاده از دستور chattr در لینوکس

اگر شما مدیر یک سیستم لینوکسی هستید که چندین کاربر از آن استفاده می‌کنند، احتمالاً یکی از چالش‌های شما مربوط به استفاده از فایل‌های مشترک و ویرایش ناخواسته و حذف تصادفی آنهاست. فایل‌ها در لینوکس دارای ویژگی‌هایی مانند مجوزها، محتوای خواندنی/نوشتنی و غیره هستند که امنیت و کنترل فایل‌ها را فراهم می‌کنند.

لینوکس از ابزارهای قدرتمندی برای مدیریت بهینه فایل‌ها پشتیبانی می‌کند که ابزار خط فرمان chattr یکی از آنهاست. chattr (تغییر ویژگی) یک ابزار خط فرمان همه‌کاره در لینوکس است که برای تغییر ویژگی‌های فایل در سطح سیستم فایل استفاده می‌شود. این ابزار به کاربر اجازه می‌دهد تا ویژگی‌های فایل‌ها را در سطح سیستم فایل تنظیم کند که تغییرناپذیر است؛ بنابراین، مدیران سیستم لینوکس می‌توانند از دستور chattr برای جلوگیری از تغییر یا حذف فایل‌های ضروری در سیستم‌های فایل مانند ext2، ext3، ext4 یا XFS استفاده کنند و امنیت و کنترل بیشتری برای فایل‌های مهم فراهم کنند.

چگونه ویژگی‌های تنظیم شده برای یک فایل را بررسی کنیم؟
برای تنظیم ویژگی‌های یک فایل و تغییرناپذیر کردن ویژگی‌های فایل در لینوکس، بهتر است ابتدا ویژگی‌های از پیش تنظیم شده برای فایل‌های مبتنی بر سیستم فایل در دایرکتوری فعلی را بررسی کنید؛ برای این منظور از دستور زیر استفاده کنید:

lsattr

خروجی:
----------------------e----------- ./writer-doc.odt
----------------------e-----------./opera-app.c
----------------------e-----------./opera-app
----------------------e-----------./text-file.txt
----------------------e-----------./bash-noscript.sh
----------------------e-----------./image-file.jpg


خطوط حاوی توالی‌های خط تیره نشان‌دهنده ویژگی‌هایی هستند که برای یک فایل تنظیم شده‌اند. این خروجی به معنای تنظیم ویژگی e (extents) برای فایل‌هاست. این نشان می‌دهد که inodeهای سیستم فایل از extents استفاده می‌کنند تا به کل فایل روی هارد دیسک اشاره کنند.

چگونه از دستور chattr در لینوکس استفاده کنیم؟
دستور chattr در لینوکس به شما اجازه می‌دهد تا ویژگی فایل‌ها و دایرکتوری‌ها را تغییر دهید تا تغییرناپذیر شوند و هیچ کس دیگری، حتی کاربر root، نتواند فایل‌ها را در سیستم فایل تغییر دهد. در ادامه نحوه استفاده از دستور chattr برای تغییرناپذیر کردن فایل‌ها و دایرکتوری‌ها را آموزش خواهیم داد.

ویژگی‌های رایج مورد استفاده با دستور chattr:

1. بدون کنترل دسترسی (A): کنترل و دسترسی به فایل را غیرفعال می‌کند و برای مدیریت ویژگی‌های دسترسی جداگانه استفاده می‌شود. همچنین از به‌روزرسانی رکورد زمان دسترسی جلوگیری می‌کند.

2. فقط-افزودنی (a): تنظیم a برای یک فایل از حذف و هرگونه تغییر جلوگیری می‌کند و نوشتن را فقط در حالت افزودن مجاز می‌کند. این ویژگی معمولاً برای فایل‌های لاگ استفاده می‌شود.

3. فشرده‌سازی (c): فایل را فشرده می‌کند.

4. بدون پشتیبان‌گیری (d): فایلی که ویژگی d برای آن تنظیم شده در پشتیبان‌گیری گنجانده نمی‌شود.

5. به‌روزرسانی همزمان دایرکتوری (D): همه تغییرات در فایل را به طور همزمان روی هارد دیسک به‌روزرسانی می‌کند.

6. فرمت extent (e): این ویژگی سیستم فایل را طوری تنظیم می‌کند که از extents برای مدیریت فایل‌های بزرگ استفاده کند.

7. فشرده‌سازی (E): فایل را بر اساس الگوریتم خاصی فشرده می‌کند.

8. ژورنال‌سازی (j): ژورنال‌سازی را برای فایل فعال یا غیرفعال می‌کند.

9. تغییرناپذیر (i): ویژگی‌های فایل مانند نام، حذف، ایجاد لینک و قابلیت اجرا و نوشتن را تغییرناپذیر می‌کند.

10. حذف امن (S): با تنظیم این ویژگی، هنگام حذف فایل، بلوک‌های داده با صفر بازنویسی می‌شوند.

11. حذف فایل با کپی (u): وقتی ویژگی u تنظیم شود، هنگام حذف فایل یک کپی ایجاد می‌شود.

نحو پایه chattr:
chattr [operator] [flags] [filename]


عملگرها:
+ (تنظیم): برای اعمال ویژگی مورد نظر
- (حذف): برای حذف ویژگی‌ها
= (فقط تنظیم): ویژگی مشخص شده را تنظیم می‌کند و ویژگی‌های موجود را حفظ می‌کند

تنظیم فایل به صورت تغییرناپذیر:
sudo chattr +i filename


مثال:
sudo chattr +i testfile.txt
rm testfile.txt
rm: cannot remove 'testfile.txt' : Operation not permitted

غیرفعال کردن ایجاد حساب کاربری با تغییرناپذیر کردن فایل:
sudo chattr +i /etc/passwd
sudo chattr +i /etc/shadow

حذف ویژگی تغییرناپذیر از فایل:
sudo chattr -i filename

تنظیم محدودیت‌ها در دایرکتوری:
sudo chattr -R +i ./mydir/

تنظیم ویژگی فقط-افزودنی برای جلوگیری از حذف یا تغییر:
sudo chattr +a filename

Source

#linux

@Syntax_fa
👍6🔥2👏1
مقایسه GitHub و GitLab

1. مالکیت:
- GitHub: متعلق به شرکت مایکروسافت.
- GitLab: متعلق به شرکت GitLab Inc.

2. جامعه (Community & Publicity):
- GitHub: بیش از 100 میلیون کاربر و سطح تبلیغات و شناخت عمومی بالا.
- GitLab: حدود 30 میلیون کاربر (تخمین زده‌شده) و سطح شناخت عمومی کمتر از GitHub.

3. فضای ذخیره‌سازی مخازن عمومی:
- GitHub: فضای ذخیره‌سازی نامحدود.
- GitLab: پنج گیگابایت (تخمینی).

4. فضای ذخیره‌سازی مخازن خصوصی:
- GitHub: پانصد مگابایت
-GitLab: پنج گیگابایت

5. دقیقه‌های محاسباتی CI برای پروژه‌های عمومی:

- GitHub: نامحدود.
- GitLab: چهارصد دقیقه (اگرچه در مستندات رسمی 50,000 دقیقه ذکر شده است، اما معمولاً 400 دقیقه ارائه می‌شود)

6. دقیقه‌های محاسباتی CI برای پروژه‌های خصوصی در ماه:
- GitHub: دوهزار دقیقه
- GitLab: چهارصد دقیقه

7. حداکثر تعداد همکاران برای مخازن عمومی:
- GitHub:
نامحدود.
- GitLab: نامحدود.

8. حداکثر تعداد همکاران برای مخازن خصوصی:
- GitHub:
نامحدود.
- GitLab: محدود به 5 نفر.

#github #gitlab

@Syntax_fa
👍18🔥2
تاریخچه کوبرنتیز

کوبرنتیز (Kubernetes) یکی از پیشروترین ابزارهای مدیریت کانتینرها در دنیای فناوری امروز است. اما برای درک بهتر تاریخچه کوبرنتیز، لازم است ابتدا نگاهی به ریشه‌های آن و پیشرفت‌هایی که به خلق این ابزار انجامید بیندازیم.

2006: آغاز راه در گوگل با cgroup

در سال 2006، گوگل به‌دنبال بهینه‌سازی منابع خود بود، چرا که نیاز داشت حجم عظیمی از داده‌ها و اپلیکیشن‌ها را در مقیاس بالا مدیریت کند. در این راستا، پروژه‌ای را با هدف ایجاد ابزارهایی برای جداسازی و تخصیص منابع سیستم آغاز کرد. این پروژه که ابتدا با نام "Process Container" شناخته می‌شد، بعدها به cgroup (Control Groups) تغییر نام یافت. cgroup قابلیتی بود که اجازه می‌داد منابع مختلف سیستم (CPU، حافظه، دیسک و ...) به صورت کنترل‌شده و محدود بین فرآیندها تقسیم شوند.

سال 2007: cgroup وارد هسته لینوکس می‌شود

در سال 2007، گوگل کد مربوط به cgroup را به هسته لینوکس ارسال کرد و این قابلیت به عنوان بخشی از هسته اصلی لینوکس پذیرفته و ادغام شد. این گام مهمی بود، زیرا cgroup به توسعه‌دهندگان اجازه می‌داد که از امکانات جداسازی منابع در سیستم‌عامل لینوکس بهره ببرند و پایه‌ای قدرتمند برای مدیریت کانتینرها ایجاد کردند.

معرفی Namespaces توسط Red Hat

همزمان با توسعه cgroup، مفهوم دیگری به نام Namespaces توسط شرکت Red Hat معرفی شد. Namespaces امکان ایزوله‌سازی بخش‌های مختلف سیستم (مانند شبکه، فایل‌سیستم و موارد دیگر) را فراهم کرد. ترکیب cgroup و Namespaces، اساس فناوری کانتینرها را شکل داد و بستر لازم برای مدیریت اپلیکیشن‌ها در محیط‌های ایزوله را فراهم کرد.

سال 2013: معرفی Docker

کانتینرها به لطف cgroup و Namespaces به ابزاری بسیار قدرتمند تبدیل شدند، اما هنوز استفاده از آن‌ها پیچیده بود. در سال 2013، شرکت Docker با معرفی پلتفرم خود، این پیچیدگی‌ها را ساده کرد. Docker فناوری کانتینر را به یک ابزار قابل‌دسترس برای توسعه‌دهندگان تبدیل کرد و مفهوم کانتینری‌شدن اپلیکیشن‌ها را به جریان اصلی دنیای فناوری وارد کرد.

سال 2014: تولد کوبرنتیز در گوگل

گوگل که سال‌ها تجربه مدیریت کانتینرها را در مقیاس بالا داشت، تصمیم گرفت تا ابزار داخلی خود برای مدیریت کانتینرها را به یک پروژه متن‌باز تبدیل کند. این ابزار که به نام Kubernetes شناخته شد، در سال 2014 به عنوان یک پروژه متن‌باز معرفی گردید. کوبرنتیز با الهام از ابزار داخلی گوگل به نام Borg طراحی شده بود و هدف آن مدیریت خودکار کانتینرها، مقیاس‌گذاری، و هماهنگی بین آن‌ها بود.

نکته:
کوبرنتیز (Kubernetes) در ابتدا با زبان C توسعه داده شده بود. اما در سال 2014 تیم گوگل تصمیم گرفت آن را با زبان Go بازنویسی کند. دلیل این تغییر، توانایی‌های Go در مدیریت هم‌زمانی (Concurrency)، عملکرد بالا، و سهولت توسعه و نگهداری بود که برای یک سیستم توزیع‌شده مدرن مانند Kubernetes بسیار ضروری است.

این بازنویسی بخشی از تلاش برای ارائه یک پلتفرم متن‌باز و مدرن‌تر بود که بتواند به‌خوبی نیازهای زیرساخت‌های ابری را برآورده کند.


2015: کوبرنتیز و CNCF

برای گسترش و پذیرش بیشتر کوبرنتیز در جامعه متن‌باز، گوگل تصمیم گرفت این پروژه را به بنیاد جدیدی به نام Cloud Native Computing Foundation (CNCF) اهدا کند. CNCF که یک زیرمجموعه از بنیاد Linux Foundation است، وظیفه داشت تا به توسعه و گسترش اکوسیستم ابزارهای مدرن ابری کمک کند. این حرکت باعث شد کوبرنتیز از زیر چتر گوگل خارج شود و به یک پروژه مستقل و جهانی تبدیل شود که توسط جامعه متن‌باز هدایت می‌شود.

رشد و محبوبیت کوبرنتیز

پس از اهدا به CNCF، کوبرنتیز به سرعت به استانداردی برای مدیریت کانتینرها تبدیل شد. ابزارهای بسیاری برای تکمیل اکوسیستم کوبرنتیز توسعه یافتند و شرکت‌های بزرگی مانند
Red Hat، IBM، Microsoft💩, AWS
از آن پشتیبانی کردند. کوبرنتیز به دلیل انعطاف‌پذیری، مقیاس‌پذیری، و قابلیت اتوماسیون، به یکی از محبوب‌ترین ابزارها برای مدیریت زیرساخت‌های ابری تبدیل شده است.

#kubernetes

@Syntax_fa
14👍6🔥1💩1
استراتژی Deployment در Kubernetes چیست؟

برای درک مفهوم استراتژی Deployment در Kubernetes، ابتدا باید دو معنای ممکن "deployment" در محیط Kubernetes را توضیح دهیم:

1. deployment

به فرآیند نصب یک نسخه جدید از یک اپلیکیشن یا workload روی pods در Kubernetes اشاره دارد.
2. Deployment
(با D بزرگ)، یک Kubernetes object است که دارای فایل تنظیمات YAML مخصوص به خود می‌باشد و به شما این امکان را می‌دهد که تعیین کنید:
- فرآیند deployment چگونه باید انجام شود،
- دقیقاً چه چیزی باید deploy شود،
- و همچنین چگونه درخواست‌ها به اپلیکیشن جدید هدایت شوند.

استراتژی deployment تعیین می‌کند که چگونه pods باید به نسخه جدید اپلیکیشن به‌روزرسانی شوند. به‌عنوان مثال، یک گزینه این است که تمامی pods حذف شوند و با نسخه جدید جایگزین شوند؛ این روش باعث downtime می‌شود. اما گزینه‌های پیشرفته‌تری نیز وجود دارند که اپلیکیشن را به‌صورت تدریجی با کمترین اختلال در خدمات به‌روزرسانی می‌کنند.

1. Recreate Deployment
این روش یک فرآیند همه یا هیچ است که اپلیکیشن را فوراً به‌روزرسانی می‌کند، اما با مقداری downtime همراه است.

- در این استراتژی، pods موجود حذف می‌شوند و نسخه جدید جایگزین آن‌ها می‌شود.
- این روش باعث می‌شود که از زمان خاموش شدن نسخه قدیمی تا شروع به کار نسخه جدید، اپلیکیشن downtime داشته باشد.
- موارد استفاده مناسب:
- محیط‌های توسعه (development environments).
- زمانی که کاربران ترجیح می‌دهند یک دوره کوتاه downtime به جای کاهش عملکرد یا خطاهای طولانی‌مدت (در rolling deployment) داشته باشند.
- زمانی که دلایل فنی اجازه اجرای دو نسخه همزمان از یک اپلیکیشن را نمی‌دهند(برای مثال statefull بودن برنامه).

2. Rolling Deployment
در این استراتژی، نسخه جدید اپلیکیشن به‌صورت تدریجی روی pods مستقر می‌شود.

- مزایا:

- امکان بازگشت (rollback) آسان‌تر.
- ریسک کمتری نسبت به روش Recreate دارد.
- نسبتا راحت پیاده‌سازی می‌شود.
- معایب:
- ممکن است کند باشد.
- در صورت بروز مشکل، بازگشت به نسخه قبلی دشوارتر است.
- اجرای همزمان چند نسخه از اپلیکیشن ممکن است برای اپلیکیشن‌های قدیمی مشکل‌ساز باشد.

3. Blue/Green Deployment (Red/Black Deployment)
این استراتژی به شما امکان می‌دهد که نسخه جدید اپلیکیشن را بدون downtime مستقر کنید.

- در این روش، نسخه فعلی (آبی) فعال است و نسخه جدید (سبز) در کنار آن اجرا می‌شود.
- پس از آزمایش نسخه سبز، ترافیک به آن سویچ می‌شود.
- مزایا:
- حذف کامل downtime.
- ریسک کمتر (به‌دلیل امکان بازگشت فوری به نسخه قبلی).
- عدم وجود مشکلات نسخه‌بندی، زیرا کل اپلیکیشن در یک حالت تغییر می‌کند.
- معایب:
- نیاز به منابع دوبرابر برای نسخه‌های آبی و سبز.
- نیاز به مکانیزمی برای تغییر سریع ترافیک.

4. Canary Deployment
این استراتژی به شما امکان می‌دهد نسخه جدید اپلیکیشن را روی گروه کوچکی از کاربران واقعی آزمایش کنید.

- به صورت تدریجی نسخه جدید در cluster مستقر شده و روی مقدار کمی از ترافیک زنده آزمایش می‌شود.
- پس از اطمینان از عملکرد صحیح، نسخه جدید به طور کامل جایگزین نسخه قبلی می‌شود.
- مزایا:
- ریسک کمتر برای انتشار تغییرات بزرگ یا ویژگی‌های آزمایشی.
- امکان rollout تدریجی.
- معایب:
- نیاز به اجرای همزمان چند نسخه از اپلیکیشن.
- نیاز به مکانیزم هوشمند برای هدایت بخشی از ترافیک به نسخه جدید.


5. A/B Testing

در Kubernetes، A/B Testing نوعی از canary deployment است که ترافیک را بر اساس پارامترهای خاص (مانند کوکی‌ها یا user agents) بین نسخه‌های مختلف اپلیکیشن توزیع می‌کند.

- این روش برای آزمایش گزینه‌های مختلف یک ویژگی جدید و انتخاب نسخه‌ای که کاربران بیشتر می‌پسندند، مناسب است.
- تفاوت اصلی با canary deployment در نحوه توزیع کاربران است.

6. Shadow Deployment
در این روش، نسخه جدید اپلیکیشن روی production workloads آزمایش می‌شود، اما بدون اینکه کاربران نهایی متوجه شوند.

- ترافیک بین نسخه فعلی و نسخه جدید تقسیم می‌شود.
- مزایا:
- امکان آزمایش جنبه‌های غیرفنی (مانند عملکرد و پایداری) نسخه جدید.
- معایب:
- پیچیدگی مدیریت بالا.
- نیاز به منابع دوبرابر برای اجرای همزمان نسخه‌های مختلف

نکته:
توجه داشته باشید که فقط دو استراتژی Recreate و Rolling به‌صورت پیش‌فرض توسط Kubernetes Deployment object پشتیبانی می‌شوند. سایر استراتژی‌ها نیازمند سفارشی‌سازی یا استفاده از ابزارهای تخصصی هستند.

source

#deployment_strategy

@Syntax_fa
👍10
انحصارطلبی غول‌های فناوری: «ما حامی هستیم، اما فقط وقتی مال خودمون باشی!»

غول‌های فناوری همیشه ادعا می‌کنن که حامی نوآوری، خلاقیت، و پیشرفت هستن. روی کاغذ، خیلی قشنگه: شعار میدن که می‌خوان دنیا رو جای بهتری کنن، به استارت‌آپ‌ها و پروژه‌های نوپا کمک کنن و منابع بیشتری در اختیارشون بذارن. اما وقتی دقیق‌تر نگاه کنیم، متوجه می‌شیم که این حمایت‌ها فقط یه هدف داره: تصاحب، حذف یا نابودی هر چیزی که ممکنه تهدیدی برای انحصار و سلطه‌شون بشه.

کافیه یه پروژه اوپن‌سورس یا یه استارت‌آپ کوچیک یه ذره رشد کنه و توجه‌ها رو به خودش جلب کنه. سریع یکی از این غول‌ها میاد، قربون‌صدقه میره و یه قلب بزرگ (❤️) پای پروژه می‌ذاره. اما این قلب زدن فقط یه راه مودبانه برای گفتن این جمله‌ست: "ما این رو می‌خریم!" و اگه نتونن بخرنش، وارد یه فاز تهاجمی‌تر میشن: نابودش کن!

فاز اول: قلب بزن، قربون‌صدقه برو
وقتی یه استارت‌آپ یا یه پروژه اوپن‌سورس داره رشد می‌کنه، اول از همه غول‌های فناوری میان و با لبخند ازش تعریف می‌کنن. مثلاً توییت می‌زنن:
"این پروژه واقعاً الهام‌بخشه. ما عاشق نوآوری هستیم و از این پروژه حمایت می‌کنیم!"
اما پشت این تعریف‌ها، مدیرای اجرایی و تیم‌های حقوقی شرکت دارن بررسی می‌کنن که چطور این پروژه رو تصاحب کنن. چون تو دنیای غول‌ها، کلمه «حمایت» معمولاً به معنی «ادغام در امپراتوری ما» است.

فاز دوم: چند ماه بعد، خبر میاد که:
"مایکروسافت/گوگل/آمازون این استارت‌آپ را با مبلغ X میلیون دلار خریداری کرد."
ظاهرش خیلی جذابه: استارت‌آپ حالا منابع بیشتری داره و می‌تونه سریع‌تر رشد کنه. ولی در واقعیت، این خرید بیشتر شبیه یه «عملیات خفه کردن» برای کنترل یا حذف رقابت در بازار هست.

فاز سوم: خفه کن، جایگزین کن
حالا که پروژه یا استارت‌آپ مال خودشون شده، دو تا اتفاق ممکنه بیفته:
1. یا پروژه به طور کامل تعطیل میشه، چون دیگه برای شرکت ارزش استراتژیک نداره.
2. یا اون پروژه تغییر می‌کنه تا فقط به اهداف انحصاری شرکت خدمت کنه.

@Syntax_fa
👍13
مثال‌هایی از شکار و انحصارطلبی

1. مایکروسافت و نوآوری‌های Netscape: پایان مرورگر مستقل
در دهه ۹۰ میلادی، Netscape یکی از محبوب‌ترین مرورگرهای وب بود. این شرکت به نوعی پیشگام اینترنت مدرن به حساب می‌اومد و مایکروسافت که از محبوبیت و رشد سریع Netscape ترسیده بود، استراتژی تهاجمی خودش رو شروع کرد. 
مایکروسافت تصمیم گرفت مرورگر خودش به نام Internet Explorer رو به صورت رایگان همراه با ویندوز عرضه کنه. این حرکت باعث شد که کاربران به طور پیش‌فرض از Internet Explorer استفاده کنن و سهم بازار Netscape به شدت کاهش پیدا کنه. 
در نهایت، Netscape نتونست با این انحصارطلبی مبارزه کنه و ورشکست شد. این پرونده حتی به دادگاه ضدانحصار ایالات متحده کشیده شد، جایی که مشخص شد مایکروسافت عمداً از قدرت انحصاری ویندوز برای حذف رقبای مرورگر استفاده کرده. 

2. مایکروسافت و Skype: تصاحب و سقوط یک نوآوری
مایکروسافت در سال ۲۰۱۱ با مبلغ ۸.۵ میلیارد دلار Skype رو خریداری کرد. اسکایپ تا قبل از خرید یکی از محبوب‌ترین ابزارهای تماس ویدیویی و صوتی در جهان بود و به عنوان یک نوآوری مستقل می‌درخشید. اما بعد از خرید توسط مایکروسافت، مشکلات شروع شد: 
- مایکروسافت به جای توسعه و بهبود اسکایپ، تمرکز رو روی ادغام اون با محصولات خودش مثل ویندوز و Office گذاشت. 
- اسکایپ به مرور زمان از کارایی افتاد؛ مشکلات مربوط به کیفیت تماس و رابط کاربری گیج‌کننده باعث شد که بسیاری از کاربران به سرویس‌های رقیب مثل Zoom، WhatsApp، و Google Meet مهاجرت کنن. 
- نهایتاً، اسکایپ که یک‌زمانی یکه‌تاز بازار تماس‌های ویدیویی بود، به حاشیه رانده شد و تقریباً از فضای رقابت حذف شد. 

این اتفاق نشون داد که مایکروسافت به جای تقویت این نوآوری، بیشتر به دنبال استفاده از برند اسکایپ برای منافع خودش بود.

3. مایکروسافت و Nokia: شکست برنامه‌ریزی‌شده؟
یکی از جنجالی‌ترین تصاحب‌های مایکروسافت، خرید بخش موبایل شرکت نوکیا در سال ۲۰۱۳ بود. نوکیا که زمانی بزرگترین تولیدکننده گوشی‌های موبایل در دنیا بود، به خاطر رقابت با سیستم‌عامل‌های اندروید و iOS دچار افت شد. مایکروسافت با وعده همکاری و توسعه، بخش موبایل نوکیا رو خرید و ادعا کرد که این خرید به زنده‌کردن نوکیا کمک می‌کنه. اما در واقعیت، این اتفاق به سقوط کامل نوکیا منجر شد:
- مایکروسافت تصمیم گرفت که گوشی‌های نوکیا فقط با سیستم‌عامل Windows Phone عرضه بشن، که سهم بسیار کوچکی از بازار موبایل داشت. این تصمیم، نوکیا رو از رقابت با اندروید و iOS دور کرد.
- سرمایه‌گذاری روی ویندوزفون شکست خورد و مایکروسافت خیلی زود این پروژه رو رها کرد.
- در نهایت، بخش موبایل نوکیا تعطیل شد و هزاران نفر از کارکنانش بیکار شدن.

4. گوگل و DeepMind 
گوگل وقتی DeepMind رو خرید، قول داد که این شرکت مستقل و متمرکز روی «هوش مصنوعی اخلاقی» باقی می‌مونه. اما حالا بیشتر کارای DeepMind روی پروژه‌هایی متمرکزه که به تبلیغات گوگل و سرویس‌های پول‌ساز این شرکت کمک می‌کنه. مثلاً پروژه‌های سلامت DeepMind به Google Health منتقل شدن، و حالا بیشتر از اینکه به اخلاق فکر کنن، به سوددهی فکر می‌کنن. 

5. آمازون و استارت‌آپ‌های خرده‌فروشی 
آمازون یکی از بزرگترین شکارچی‌های استارت‌آپ‌های خرده‌فروشی هست. استراتژی‌شون؟ اول از یه استارت‌آپ حمایت می‌کنن، بعد یه نسخه مشابه از اون محصول رو ارزون‌تر تولید می‌کنن، و در نهایت یا اون استارت‌آپ رو می‌خرن یا ورشکسته‌ش می‌کنن. مثلاً استارت‌آپی مثل Diapers.com که تو فروش پوشک بچه موفق بود، اول تحت فشار قیمت‌های پایین آمازون قرار گرفت و در نهایت مجبور شد خودش رو بفروشه. 

6. واتس‌اپ و اینستاگرام: شکارهای فیسبوک 
فیسبوک وقتی دید واتس‌اپ و اینستاگرام دارن محبوب‌تر میشن، سریع دست به کار شد. هر دو رو خرید و قول داد که مستقل می‌مونن. ولی امروز دیگه می‌دونیم که اطلاعات واتس‌اپ و اینستاگرام به شدت برای تبلیغات فیسبوک استفاده میشه. واتس‌اپی که یه زمانی قول حفظ حریم خصوصی داده بود، الان به یکی از ابزارهای اصلی فیسبوک برای تحلیل داده‌ها تبدیل شده.

5. گوگل و Nest 
استارت‌آپی که تو حوزه خانه‌های هوشمند خیلی محبوب شده بود، توسط گوگل خریداری شد. بعد از خرید، خیلی از محصولاتش تعطیل شدن یا مستقیماً به سرویس‌های گوگل گره خوردن. کار به جایی رسید که حتی مدیرعامل Nest از گوگل جدا شد و به صراحت گفت: گوگل فقط به دنبال کنترل بازار بود

@Syntax_fa
👍171