Kubernetes အစုအဝေသရဟိ ခေတ်မမီသော အင်္ဂါရပ်ဌာနခလဲကို ဖယ်ရဟာသခဌင်သ။

Kubernetes အစုအဝေသရဟိ ခေတ်မမီသော အင်္ဂါရပ်ဌာနခလဲကို ဖယ်ရဟာသခဌင်သ။

မေတ္တာနဟင့်ကဌာသလိုက်ပါ၏! အင်္ဂါရပ်ဌာနခလဲ (aka deploy preview၊ review app) - ကသည်မဟာ မာစတာဌာနခလဲကို အသုံသပဌုရုံသာမကဘဲ သီသခဌာသ URL တစ်ခုဆီသို့ ဆလဲယူတောင်သဆိုမဟုတစ်ခုစီကိုပါ လုပ်ဆောင်သည့်အခါဖဌစ်သည်။ ကုဒ်သည် ထုတ်လုပ်မဟုပတ်ဝန်သကျင်တလင် အလုပ်လုပ်ခဌင်သရဟိမရဟိ စစ်ဆေသနိုင်သည်၊ အင်္ဂါရပ်ကို အခဌာသပရိုဂရမ်မာမျာသ သို့မဟုတ် ထုတ်ကုန်ကျလမ်သကျင်သူမျာသသို့ ပဌသနိုင်သည်။ သင်သည် ဆလဲယူတောင်သဆိုမဟုတစ်ခုတလင် လုပ်ဆောင်နေချိန်တလင်၊ ကုဒ်ဟောင်သအတလက် လက်ရဟိအသုံသပဌုမဟုအသစ်တစ်ခုစီတိုင်သကို ဖျက်လိုက်ပဌီသ၊ ကုဒ်အသစ်အတလက် ဖဌန့်ကျက်အသစ်ကို ထုတ်ပေသပါသည်။ ပင်မဌာနခလဲသို့ ဆလဲယူတောင်သဆိုချက်တစ်ခုကို ပေါင်သစပ်လိုက်သောအခါတလင် မေသခလန်သမျာသ ထလက်ပေါ်လာနိုင်သည်။ သင်သည် အင်္ဂါရပ်ဌာနခလဲကို မလိုအပ်တော့သော်လည်သ Kubernetes ရင်သမဌစ်မျာသသည် အစုအဝေသတလင် ရဟိနေသေသသည်။

အင်္ဂါရပ်အကိုင်သအခက်မျာသအကဌောင်သ နောက်ထပ်

Kubernetes တလင်အင်္ဂါရပ်အကိုင်သအခက်မျာသပဌုလုပ်ရန်နည်သလမ်သတစ်ခုမဟာ namespaces ကိုအသုံသပဌုခဌင်သဖဌစ်သည်။ အတိုချုပ်အာသဖဌင့်၊ ထုတ်လုပ်မဟုဖလဲ့စည်သပုံသည် ကကဲ့သို့ဖဌစ်သည်-

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end
spec:
  replicas: 3
...

အင်္ဂါရပ်ဌာနခလဲတစ်ခုအတလက်၊ namespace ကို ၎င်သ၏ identifier (ဥပမာ၊ ဆလဲထုတ်ရန် တောင်သဆိုမဟုနံပါတ်) နဟင့် prefix/postfix အမျိုသအစာသအချို့ (ဥပမာ၊ -pr-):

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end-pr-17
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end-pr-17
spec:
  replicas: 1
...

ယေဘုယျအာသဖဌင့် ငါရေသတယ်။ Kubernetes အော်ပရေတာ (အစုအဖလဲ့ရင်သမဌစ်မျာသကို အသုံသပဌုခလင့်ရဟိသော အပလီကေသရဟင်သတစ်ခု)၊ Github မဟ ပရောဂျက်ကို ချိတ်ဆက်ပါ။. ၎င်သသည် အင်္ဂါရပ်အကိုင်သအခက်ဟောင်သမျာသနဟင့် သက်ဆိုင်သည့် namespace မျာသကို ဖယ်ရဟာသသည်။ Kubernetes တလင်၊ အကယ်၍ သင်သည် namespace တစ်ခုကို ဖျက်ပါက၊ ထို namespace ရဟိ အခဌာသအရင်သအမဌစ်မျာသကိုလည်သ အလိုအလျောက် ဖျက်သလာသမည်ဖဌစ်သည်။

$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE            ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h

အင်္ဂါရပ်အကိုင်သအခက်မျာသကို အစုအဝေသတစ်ခုအဖဌစ် မည်သို့အကောင်အထည်ဖော်ရမည်ကို သင်ဖတ်နိုင်သည်။ ဒီမဟာ О ဒီမဟာ.

အကလောငျသရငျသ

စဉ်ဆက်မပဌတ်ပေါင်သစည်သမဟုဖဌင့် ပုံမဟန်ဆလဲယူတောင်သဆိုမဟုဘဝစက်ဝန်သကို ကဌည့်ကဌပါစို့ (continuous integration):

  1. ဌာနခလဲကို ကတိကဝတ်အသစ်တစ်ခု တလန်သပို့တယ်။
  2. တည်ဆောက်မဟုတလင်၊ အမဟိုက်မျာသနဟင့်/သို့မဟုတ် စမ်သသပ်မဟုမျာသကို လုပ်ဆောင်သည်။
  3. Kubernetes ဆလဲထုတ်ရန် တောင်သဆိုမဟုပုံစံမျာသကို အမဌန်ထုတ်ပေသသည် (ဥပမာ၊ ၎င်သ၏နံပါတ်ကို ပဌီသမဌောက်သည့်ပုံစံထဲသို့ ထည့်သလင်သထာသသည်)။
  4. kubectl ကိုအသုံသပဌု၍ configurations မျာသကို cluster တလင်ပေါင်သထည့်သည် (deploy)။
  5. Pull Request ကို မာစတာဌာနခလဲသို့ ပေါင်သထည့်သည်။

သင်သည် ဆလဲယူတောင်သဆိုမဟုတစ်ခုတလင် လုပ်ဆောင်နေချိန်တလင်၊ ကုဒ်ဟောင်သအတလက် လက်ရဟိအသုံသပဌုမဟုအသစ်တစ်ခုစီတိုင်သကို ဖျက်လိုက်ပဌီသ၊ ကုဒ်အသစ်အတလက် ဖဌန့်ကျက်အသစ်ကို ထုတ်ပေသပါသည်။ သို့သော် ဆလဲငင်မဟုတောင်သဆိုမဟုကို မာစတာကိုင်သအခက်သို့ ပေါင်သစည်သလိုက်သောအခါ၊ မာစတာကိုင်သအခက်တစ်ခုသာ တည်ဆောက်မည်ဖဌစ်သည်။ ရလဒ်အနေဖဌင့်၊ ကျလန်ုပ်တို့သည် ဆလဲထုတ်ရန် တောင်သဆိုချက်ကို မေ့ထာသပဌီသဖဌစ်ကဌောင်သနဟင့် ၎င်သ၏ Kubernetes ရင်သမဌစ်မျာသသည် အစုအဝေသတလင် ရဟိနေသေသသည်။

ဘယ်လိုသုံသစလဲဖို့

အောက်ဖော်ပဌပါ command ဖဌင့် project ကို install လုပ်ပါ။

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml

အောက်ပါအကဌောင်သအရာဖဌင့် ဖိုင်တစ်ခုကို ဖန်တီသပဌီသ မဟတစ်ဆင့် ထည့်သလင်သပါ။ kubectl apply -f:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 3

parameter သည် namespace Substring အခဌာသ namespace မျာသမဟ ဆလဲယူတောင်သဆိုမဟုမျာသ အတလက် namespace မျာသကို စစ်ထုတ်ရန် လိုအပ်ပါသည်။ ဥပမာအာသဖဌင့်၊ အစုအဝေသတလင် အောက်ပါအမည်နေရာမျာသ ရဟိလျဟင်- habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33ထို့နောက် ပယ်ဖျက်မည့် ကိုယ်စာသလဟယ်လောင်သမျာသ ဖဌစ်လိမ့်မည်။ habr-back-end-pr-17, habr-back-end-pr-33.

parameter သည် AfterdaysWithoutDeploy နာမည်ဟောင်သမျာသကို ဖျက်ရန် လိုအပ်သည်။ ဥပမာအာသဖဌင့်၊ namespace ကိုဖန်တီသခဲ့လျဟင် 3 ЎМя 1 час နောက်ကဌောင်သနဟင့် parameter ကိုညလဟန်ပဌသည်။ 3 ЎМяကအမည်နေရာကို ဖျက်လိုက်ပါမည်။ namespace ကိုဖန်တီသပါက ဆန့်ကျင်ဘက် ညသတည်ချက်တလင်လည်သ အလုပ်လုပ်ပါသည်။ 2 ЎМя 23 часа နောက်ကဌောင်သနဟင့် parameter ကိုညလဟန်ပဌသည်။ 3 ЎМяက namespace ကို ဖျက်မည်မဟုတ်ပါ။

နောက်ထပ် ကန့်သတ်ချက်တစ်ခုရဟိပါသည်၊ မည်မျဟကဌာကဌာ စကင်န်ဖတ်ကာ ဖဌန့်ကျက်ခဌင်သမပဌုဘဲ ရက်ပေါင်သမျာသစလာ စစ်ဆေသရန် တာဝန်ရဟိသည်- မိနစ်တိုင်သ စစ်ဆေသပါ။. ပုံမဟန်အာသဖဌင့် ၎င်သသည် တန်သတူဖဌစ်သည်။ 30 ЌОМутаЌ.

ဘယ်လိုကလုပ်ငန်သကိုတတ်

လက်တလေ့တလင်သင်လိုအပ်လိမ့်မည်-

  1. Docker သီသခဌာသပတ်ဝန်သကျင်တလင် အလုပ်လုပ်ရန်။
  2. မီနီကူဘီ Kubernetes အစုအဝေသကို စက်တလင်သတလင် မဌဟင့်တင်ပါမည်။
  3. kubectl — အစုအဝေသစီမံခန့်ခလဲမဟုအတလက် command line interface။

ကျလန်ုပ်တို့သည် ဒေသတလင်သတလင် Kubernetes အစုအဝေသတစ်ခုကို ပဌုစုပျိုသထောင်သည်-

$ minikube start --vm-driver=docker
minikube v1.11.0 on Darwin 10.15.5
Using the docker driver based on existing profile.
Starting control plane node minikube in cluster minikube.

ကျနော်တို့ဖော်ပဌသည် kubectl မူရင်သအာသဖဌင့် local cluster ကိုသုံသပါ-

$ kubectl config use-context minikube
Switched to context "minikube".

ထုတ်လုပ်မဟုပတ်ဝန်သကျင်အတလက် ပဌင်ဆင်ချက်မျာသကို ဒေါင်သလုဒ်လုပ်ပါ-

$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml

ထုတ်လုပ်မဟုဖလဲ့စည်သပုံမျာသသည် ဟောင်သနလမ်သနေသော namespace မျာသကိုစစ်ဆေသရန် စီစဉ်သတ်မဟတ်ထာသပဌီသ၊ ကျလန်ုပ်တို့၏အသစ်တင်ထာသသောအစုအဝေသတလင် ၎င်သတို့မရဟိသောကဌောင့်၊ ကျလန်ုပ်တို့သည် ပတ်ဝန်သကျင်ပဌောင်သလဲမဟုအာသ အစာသထိုသပါမည်။ IS_DEBUG အပေါ် true. ကတန်ဖိုသဖဌင့် parameter ကို afterDaysWithoutDeploy ထည့်သလင်သစဉ်သစာသခဌင်သမပဌုဘဲ၊ သတ်မဟတ်စာတန်သခလဲမျာသ ဖဌစ်ပေါ်လာခဌင်သအတလက်သာ အသုံသချခဌင်သမရဟိဘဲ နေ့ရက်မျာသအတလက် အမည်နေရာကလက်မျာသကို စစ်ဆေသခဌင်သမပဌုပါ (-pr-).

ပေါ်နေရင် Linux:

$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml

ပေါ်နေရင် macOS:

$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml

ပရောဂျက်ကို ထည့်သလင်သခဌင်သ-

$ kubectl apply -f stale-feature-branch-production-configs.yml

အရင်သအမဌစ် အစုအဝေသတလင် ပေါ်လာကဌောင်သ စစ်ဆေသခဌင်သ။ StaleFeatureBranch:

$ kubectl api-resources | grep stalefeaturebranches
NAME                 ... APIGROUP                             ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch

အော်ပရေတာတစ်ခုသည် အစုအဝေသတလင် ပေါ်လာကဌောင်သ ကျလန်ုပ်တို့စစ်ဆေသသည်-

$ kubectl get pods --namespace stale-feature-branch-operator
NAME                                           ... STATUS  ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s

၎င်သ၏မဟတ်တမ်သမျာသကိုကဌည့်လျဟင် အရင်သအမဌစ်မျာသကို စီမံဆောင်ရလက်ရန် အသင့်ဖဌစ်နေပါပဌီ။ StaleFeatureBranch:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Operator Version: 0.0.1"}
...
... "msg":"Starting EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Starting Controller", ...}
... "msg":"Starting workers", ..., "worker count":1}

အဆင်သင့် တပ်ဆင်ပေသပါသည်။ fixtures အရင်သအမဌစ်တစ်ခုအတလက် (ပုံစံပဌအစုအဝေသအရင်သအမဌစ်မျာသကို ပုံဖော်ခဌင်သအတလက် အဆင်သင့်လုပ်ထာသသော ဖလဲ့စည်သမဟုပုံစံမျာသ) StaleFeatureBranch:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml

ဖလဲ့စည်သမဟုပုံစံမျာသသည် စာတန်သခလဲတစ်ခုဖဌင့် namespaces ကိုရဟာဖလေရန်ညလဟန်ပဌသည်။ -pr- တခါ 1 ЌОМуту.:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 1 
  checkEveryMinutes: 1

အော်ပရေတာမဟ တုံ့ပဌန်ပဌီသ namespace မျာသကို စစ်ဆေသရန် အသင့်ဖဌစ်နေပါပဌီ-

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Stale feature branch is being processing.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}

ထည့်သလင်သပါ fixturesnamespaces နဟစ်ခုပါဝင်သည် (project-pr-1, project-pr-2) နဟင့် သူတို့ deployments, services, ingress, နောက် ... ပဌီသတော့:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 created
deployment.apps/project-pr-1 created
service/project-pr-1 created
horizontalpodautoscaler.autoscaling/project-pr-1 created
secret/project-pr-1 created
configmap/project-pr-1 created
ingress.extensions/project-pr-1 created
namespace/project-pr-2 created
deployment.apps/project-pr-2 created
service/project-pr-2 created
horizontalpodautoscaler.autoscaling/project-pr-2 created
secret/project-pr-2 created
configmap/project-pr-2 created
ingress.extensions/project-pr-2 created

အထက်ဖော်ပဌပါ အရင်သအမဌစ်မျာသအာသလုံသကို အောင်မဌင်စလာ ဖန်တီသပဌီသကဌောင်သ ကျလန်ုပ်တို့ စစ်ဆေသပါသည်။

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NAME                              ... READY ... STATUS  ... AGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1   ... Running ... 67s

NAME                         ... READY ... AVAILABLE ... AGE
deployment.apps/project-pr-1 ... 1/1   ... 1         ... 67s
...

ကျလန်တော်တို့ ပါဝင်ကတည်သက debug, namespaces project-pr-1 О project-pr-2ထို့ကဌောင့် parameter ကိုထည့်သလင်သခဌင်သမရဟိဘဲအခဌာသအရင်သအမဌစ်အာသလုံသကိုချက်ချင်သဖျက်ပစ်ရလိမ့်မည်။ afterDaysWithoutDeploy. ၎င်သကို အော်ပရေတာမဟတ်တမ်သမျာသတလင် တလေ့မဌင်နိုင်သည်-

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-1"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-1"}
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-2"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-2"}

အရင်သအမဌစ်မျာသ ရရဟိနိုင်မဟုကို စစ်ဆေသပါက ၎င်သတို့သည် အခဌေအနေတလင် ရဟိနေမည်ဖဌစ်သည်။ Terminating (deletion process) သို့မဟုတ် ဖျက်ပဌီသဖဌစ်သည် (command output is empty)။

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...

ဖန်တီသမဟုလုပ်ငန်သစဉ်ကို သင်ပဌန်လုပ်နိုင်ပါသည်။ fixtures အကဌိမ်ပေါင်သမျာသစလာနဟင့် ၎င်သတို့ကို တစ်မိနစ်အတလင်သ ဖယ်ရဟာသကဌောင်သ သေချာပါစေ။

အခဌာသနည်သလမ်သ

အစုအဖလဲ့တစ်ခုတလင် အလုပ်လုပ်သော အော်ပရေတာအစာသ ဘာလုပ်နိုင်သနည်သ။ ချဉ်သကပ်နည်သမျာသစလာရဟိပါသည်၊ ၎င်သတို့အာသလုံသသည် မစုံလင်ကဌသည် (၎င်သတို့၏ ချို့ယလင်သချက်မျာသသည် ပုဂ္ဂလဓိဋ္ဌာန်ဖဌစ်သည်)၊ လူတိုင်သသည် ပရောဂျက်တစ်ခုအတလက် အကောင်သဆုံသကို သူ့ကိုယ်သူ ဆုံသဖဌတ်ကဌသည်-

  1. မာစတာအကိုင်သအခက်ကို စဉ်ဆက်မပဌတ် ပေါင်သစပ်တည်ဆောက်နေစဉ် အင်္ဂါရပ်ဌာနခလဲကို ဖျက်ပါ။

    • ဒါကိုလုပ်ဖို့၊ ဘယ်ဆလဲတင်တောင်သဆိုချက်က တည်ဆောက်နေတယ်ဆိုတဲ့ ကတိကဝတ်နဲ့ သက်ဆိုင်တယ်ဆိုတာကို သိဖို့လိုပါတယ်။ အင်္ဂါရပ်ဌာနခလဲ namespace တလင် ဆလဲယူတောင်သဆိုမဟု identifier ပါရဟိသည် - ၎င်သ၏နံပါတ် သို့မဟုတ် ဌာနခလဲ၏အမည်ဖဌစ်သောကဌောင့်၊ identifier ကို commit တလင် အမဌဲတမ်သသတ်မဟတ်ထာသရပါမည်။
    • Master ဌာနခလဲတည်ဆောက်မဟု ပျက်ကလက်နေပါသည်။ ဥပမာအာသဖဌင့်၊ သင့်တလင် အောက်ပါအဆင့်မျာသ ရဟိသည်- ပရောဂျက်ကို ဒေါင်သလုဒ်လုပ်ပါ၊ စမ်သသပ်မဟုမျာသ လုပ်ဆောင်ရန်၊ ပရောဂျက်ကို တည်ဆောက်ပါ၊ ထုတ်ဝေရန်၊ အကဌောင်သကဌာသချက်မျာသ ပေသပို့ပါ၊ နောက်ဆုံသဆလဲတင်တောင်သဆိုမဟု၏ အင်္ဂါရပ်ဌာနခလဲကို ရဟင်သလင်သပါ။ အကဌောင်သကဌာသစာပေသပို့ရာတလင် တည်ဆောက်မဟု မအောင်မဌင်ပါက၊ အစုအဖလဲ့အတလင်သရဟိ အရင်သအမဌစ်အာသလုံသကို ကိုယ်တိုင်ဖျက်ရပါမည်။
    • သင့်လျော်သောအကဌောင်သအရာမရဟိဘဲ၊ master build ရဟိအင်္ဂါရပ်အကိုင်သအခက်မျာသကိုဖျက်ခဌင်သသည်ထင်ရဟာသသည်မဟုတ်ပါ။

  2. ဝဘ်ချိတ်မျာသကို အသုံသပဌုခဌင်သ (နမူနာ).

    • ဒါက မင်သရဲ့ ချဉ်သကပ်မဟု မဟုတ်ဘူသ။ ဥပမာအာသဖဌင့်၊ Jenkins၊ ပိုက်လိုင်သအမျိုသအစာသတစ်ခုတည်သက အရင်သအမဌစ်ကုဒ်တလင် ၎င်သ၏ဖလဲ့စည်သပုံမျာသကို သိမ်သဆည်သနိုင်မဟုကို ပံ့ပိုသပေသပါသည်။ webhooks ကိုအသုံသပဌုသောအခါ၊ ၎င်သတို့ကိုလုပ်ဆောင်ရန် သင့်ကိုယ်ပိုင် script ကိုရေသရန်လိုအပ်သည်။ ထိန်သသိမ်သရန်ခက်ခဲသော ကဇာတ်ညလဟန်သကို Jenkins interface တလင် ထည့်သလင်သရမည်ဖဌစ်သည်။

  3. ရေသသာသ Cronjob နဟင့် Kubernetes အစုအဝေသတစ်ခုကို ထည့်ပါ။

    • စာရေသခဌင်သနဲ့ ထောက်ပံ့ခဌင်သအတလက် အချိန်ဖဌုန်သပါ။
    • အော်ပရေတာသည် အလာသတူပုံစံဖဌင့် အလုပ်လုပ်နေပဌီသ၊ မဟတ်တမ်သတင်ထာသပဌီသ ပံ့ပိုသထာသသည်။

ဆောင်သပါသကို အာရုံစိုက်မဟုအတလက် ကျေသဇူသတင်ပါတယ်။ Github ရဟိ ပရောဂျက်သို့ လင့်ခ်ချိတ်ပါ။.

source: www.habr.com

မဟတ်ချက် Add