የአሻንጉሊት መግቢያ

አሻንጉሊት የውቅር አስተዳደር ስርዓት ነው። አስተናጋጆችን ወደ ተፈላጊው ግዛት ለማምጣት እና ይህንን ሁኔታ ለመጠበቅ ጥቅም ላይ ይውላል.

አሁን ከአምስት ዓመታት በላይ ከአሻንጉሊት ጋር እየሠራሁ ነው። ይህ ጽሑፍ ከኦፊሴላዊው ሰነድ የተተረጎመ እና እንደገና የታዘዘ የቁልፍ ነጥቦች ስብስብ ነው፣ ይህም ጀማሪዎች የአሻንጉሊትን ምንነት በፍጥነት እንዲረዱ ያስችላቸዋል።

የአሻንጉሊት መግቢያ

መሰረታዊ መረጃ

የአሻንጉሊት ኦፐሬቲንግ ሲስተም ደንበኛ-አገልጋይ ነው፣ ምንም እንኳን አገልጋይ አልባ አሰራርን ከተገደበ ተግባር ጋር ይደግፋል።

የሚጎትት ኦፕሬሽን ሞዴል ጥቅም ላይ ይውላል፡ በነባሪነት፣ በየግማሽ ሰዓቱ አንድ ጊዜ፣ ደንበኞች ለማዋቀር አገልጋዩን ያነጋግሩ እና ይተግብሩት። ከ Ansible ጋር ሰርተው ከሆነ, ከዚያ የተለየ የግፋ ሞዴል ይጠቀማሉ: አስተዳዳሪው አወቃቀሩን የመተግበር ሂደት ይጀምራል, ደንበኞቹ እራሳቸው ምንም ነገር አይተገበሩም.

በአውታረ መረብ ግንኙነት ወቅት፣ ባለሁለት መንገድ TLS ምስጠራ ጥቅም ላይ ይውላል፡ አገልጋዩ እና ደንበኛው የራሳቸው የግል ቁልፎች እና ተጓዳኝ የምስክር ወረቀቶች አሏቸው። በተለምዶ አገልጋዩ ለደንበኞች የምስክር ወረቀቶችን ይሰጣል, ነገር ግን በመርህ ደረጃ ውጫዊ CA መጠቀም ይቻላል.

የማኒፌስቶዎች መግቢያ

በአሻንጉሊት ቃላት ወደ አሻንጉሊት አገልጋይ መገናኘት አንጓዎች (አንጓዎች). ለአንጓዎች ውቅር ተጽፏል በማኒፌስቶዎች ውስጥ በልዩ የፕሮግራም አወጣጥ ቋንቋ - አሻንጉሊት DSL.

አሻንጉሊት DSL ገላጭ ቋንቋ ነው። እሱ የሚፈለገውን የመስቀለኛ መንገድ ሁኔታ በግለሰብ ሀብቶች መግለጫ መልክ ይገልጻል፣ ለምሳሌ፡-

  • ፋይሉ አለ እና የተወሰነ ይዘት አለው።
  • ጥቅሉ ተጭኗል።
  • አገልግሎቱ ተጀምሯል።

ግብዓቶች እርስ በርስ ሊተሳሰሩ ይችላሉ፡-

  • ጥገኞች አሉ, ሃብቶች ጥቅም ላይ በሚውሉበት ቅደም ተከተል ላይ ተጽዕኖ ያሳድራሉ.
    ለምሳሌ፣ “መጀመሪያ ጥቅሉን ጫን፣ በመቀጠል የማዋቀሪያ ፋይሉን አርትዕ፣ በመቀጠል አገልግሎቱን ጀምር።
  • ማሳወቂያዎች አሉ - አንድ ግብዓት ከተቀየረ ለእሱ ለተመዘገቡ ሀብቶች ማሳወቂያዎችን ይልካል።
    ለምሳሌ, የማዋቀሪያው ፋይል ከተቀየረ, አገልግሎቱን በራስ-ሰር እንደገና ማስጀመር ይችላሉ.

በተጨማሪም፣ አሻንጉሊት DSL ተግባራት እና ተለዋዋጮች፣ እንዲሁም ሁኔታዊ መግለጫዎች እና መራጮች አሉት። የተለያዩ የማስተካከያ ዘዴዎችም ይደገፋሉ - EPP እና ERB.

አሻንጉሊት በሩቢ ውስጥ ተጽፏል, ስለዚህ ብዙዎቹ ግንባታዎች እና ውሎች ከዚያ የተወሰዱ ናቸው. Ruby አሻንጉሊትን ለማስፋት ይፈቅድልዎታል - ውስብስብ አመክንዮ, አዲስ አይነት ሀብቶች, ተግባራት ይጨምሩ.

አሻንጉሊት እየሄደ እያለ በአገልጋዩ ላይ ላለው እያንዳንዱ ልዩ መስቀለኛ መንገድ መግለጫዎች ወደ ማውጫ ይሰባሰባሉ። ማውጫ á‹¨á‰°áŒá‰ŁáˆŽá‰˝, ተለዋዋጮች እና ሁኔታዊ መግለጫዎችን ማስፋፋት ዋጋ ካሰላ በኋላ የሀብቶች ዝርዝር እና ግንኙነታቸው ነው.

አገባብ እና codestyle

የቀረቡት ምሳሌዎች በቂ ካልሆኑ አገባቡን ለመረዳት የሚረዱዎት ኦፊሴላዊ ሰነዶች ክፍሎች እዚህ አሉ።

አንጸባራቂው ምን እንደሚመስል የሚያሳይ ምሳሌ ይኸውና፡-

# Комментарии пишутся, как и много где, после решётки.
#
# Описание конфигурации ноды начинается с ключевого слова node,
# за которым следует селектор ноды — хостнейм (с доменом или без)
# или регулярное выражение для хостнеймов, или ключевое слово default.
#
# После этого в фигурных скобках описывается собственно конфигурация ноды.
#
# Одна и та же нода может попасть под несколько селекторов. Про приоритет
# селекторов написано в статье про синтаксис описания нод.
node 'hostname', 'f.q.d.n', /regexp/ {
  # Конфигурация по сути является перечислением ресурсов и их параметров.
  #
  # У каждого ресурса есть тип и название.
  #
  # Внимание: не может быть двух ресурсов одного типа с одинаковыми названиями!
  #
  # Описание ресурса начинается с его типа. Тип пишется в нижнем регистре.
  # Про разные типы ресурсов написано ниже.
  #
  # После типа в фигурных скобках пишется название ресурса, потом двоеточие,
  # дальше идёт опциональное перечисление параметров ресурса и их значений.
  # Значения параметров указываются через т.н. hash rocket (=>).
  resource { 'title':
    param1 => value1,
    param2 => value2,
    param3 => value3,
  }
}

የመግቢያ እና የመስመር መግቻዎች የአንጸባራቂው አስፈላጊ አካል አይደሉም፣ ነገር ግን የሚመከር አለ። የቅጥ መመሪያ. ማጠቃለያ፡-

  • ባለ ሁለት ቦታ ገባዎች፣ ትሮች ጥቅም ላይ አይውሉም።
  • የተጠማዘዙ ማሰሪያዎች በቦታ ይለያያሉ፤ ኮሎኖች በቦታ አይለያዩም።
  • የመጨረሻውን ጨምሮ ከእያንዳንዱ ግቤት በኋላ ኮማዎች። እያንዳንዱ ግቤት በተለየ መሾመር ላይ ነው. ለየት ያለ ሁኔታ ለጉዳዩ ያለ ግቤቶች እና አንድ ግቤት ተዘጋጅቷል-በአንድ መሾመር ላይ እና ያለ ሰረዝ (ማለትም. resource { 'title': } и resource { 'title': param => value }).
  • በመለኪያዎቹ ላይ ያሉት ቀስቶች በተመሳሳይ ደረጃ መሆን አለባቸው.
  • የንብረት ግንኙነት ቀስቶች በፊታቸው ተጽፈዋል.

በ pappetserver ላይ የፋይሎች መገኛ

ለበለጠ ማብራሪያ የ "root directory" ጽንሰ-ሐሳብ አስተዋውቃለሁ. የስር ማውጫው ለተወሰነ መስቀለኛ መንገድ የአሻንጉሊት ውቅርን የያዘ ማውጫ ነው።

የስር ማውጫው እንደ የአሻንጉሊት ስሪት እና ጥቅም ላይ እንደዋለ ይለያያል። አከባቢዎች በተለየ ማውጫዎች ውስጥ የተከማቹ ገለልተኛ የማዋቀር ስብስቦች ናቸው። ብዙውን ጊዜ ከጂት ጋር በማጣመር ጥቅም ላይ ይውላል, በዚህ ሁኔታ አከባቢዎች ከጂት ቅርንጫፎች ይፈጠራሉ. በዚህ መሠረት እያንዳንዱ መስቀለኛ መንገድ በአንድ አካባቢ ወይም በሌላ ውስጥ ይገኛል. ይህ በራሱ መስቀለኛ መንገድ ላይ ሊዋቀር ይችላል, ወይም በ ENC ውስጥ, በሚቀጥለው ርዕስ ውስጥ ስለምናገረው.

  • በሶስተኛው ስሪት ("አሮጌ አሻንጉሊት") የመሠረት ማውጫው ነበር /etc/puppet. አከባቢዎችን መጠቀም አማራጭ ነው - ለምሳሌ ከድሮው አሻንጉሊት ጋር አንጠቀምባቸውም. አከባቢዎች ጥቅም ላይ ከዋሉ, በአብዛኛው የሚቀመጡት በ ውስጥ ነው /etc/puppet/environments, የስር ማውጫው የአካባቢ መዝገብ ይሆናል. አካባቢዎች ጥቅም ላይ ካልዋሉ የስር ማውጫው የመሠረት ማውጫ ይሆናል።
  • ከአራተኛው ስሪት ("አዲስ አሻንጉሊት") ጀምሮ የአካባቢን አጠቃቀም አስገዳጅ ሆነ እና የመሠረት ማውጫው ወደ ተዛወረ. /etc/puppetlabs/code. በዚህ መሠረት አከባቢዎች ተከማችተዋል /etc/puppetlabs/code/environments, root directory የአካባቢ መዝገብ ነው.

በስር ማውጫ ውስጥ ንዑስ ማውጫ መኖር አለበት። manifestsአንጓዎችን የሚገልጹ አንድ ወይም ከዚያ በላይ መገለጫዎችን የያዘ። በተጨማሪም, ንዑስ ማውጫ መኖር አለበት modulesሞጁሎችን የያዘው. ምን አይነት ሞጁሎች ትንሽ ቆይተው እነግራችኋለሁ። በተጨማሪም ፣ የድሮው አሻንጉሊት እንዲሁ ንዑስ ማውጫ ሊኖረው ይችላል። filesወደ መስቀለኛ መንገድ የምንቀዳባቸው የተለያዩ ፋይሎችን የያዘ። በአዲሱ አሻንጉሊት, ሁሉም ፋይሎች በሞጁሎች ውስጥ ይቀመጣሉ.

አንጸባራቂ ፋይሎች ቅጥያ አላቸው። .pp.

ጥቂት የውጊያ ምሳሌዎች

በላዩ ላይ የመስቀለኛ መንገድ እና መገልገያ መግለጫ

በመስቀለኛ መንገድ ላይ server1.testdomain ፋይል መፈጠር አለበት። /etc/issue ከይዘት ጋር Debian GNU/Linux n l. ፋይሉ በተጠቃሚ እና በቡድን ባለቤትነት የተያዘ መሆን አለበት። root፣ የመዳረሻ መብቶች መሆን አለባቸው 644.

ማኒፌስቶ እንጽፋለን፡-

node 'server1.testdomain' {   # блок конфигурации, относящийся к ноде server1.testdomain
    file { '/etc/issue':   # описываем файл /etc/issue
        ensure  => present,   # этот файл должен существовать
        content => 'Debian GNU/Linux n l',   # у него должно быть такое содержимое
        owner   => root,   # пользователь-владелец
        group   => root,   # группа-владелец
        mode    => '0644',   # права на файл. Они заданы в виде строки (в кавычках), потому что иначе число с 0 в начале будет воспринято как записанное в восьмеричной системе, и всё пойдёт не так, как задумано
    }
}

በመስቀለኛ መንገድ ላይ ባሉ ሀብቶች መካከል ያሉ ግንኙነቶች

በመስቀለኛ መንገድ ላይ server2.testdomain nginx መሮጥ አለበት, ከዚህ ቀደም ከተዘጋጀው ውቅር ጋር በመስራት ላይ.

ችግሩን እንበሰብሰው፡-

  • ጥቅሉን መጫን ያስፈልገዋል nginx.
  • የውቅረት ፋይሎችን ከአገልጋዩ መቅዳት አስፈላጊ ነው.
  • አገልግሎቱ መሮጥ አለበት። nginx.
  • አወቃቀሩ ከተዘመነ አገልግሎቱ እንደገና መጀመር አለበት።

ማኒፌስቶ እንጽፋለን፡-

node 'server2.testdomain' {   # блок конфигурации, относящийся к ноде server2.testdomain
    package { 'nginx':   # описываем пакет nginx
        ensure => installed,   # он должен быть установлен
    }
  # Прямая стрелка (->) говорит о том, что ресурс ниже должен
  # создаваться после ресурса, описанного выше.
  # Такие зависимости транзитивны.
    -> file { '/etc/nginx':   # описываем файл /etc/nginx
        ensure  => directory,   # это должна быть директория
        source  => 'puppet:///modules/example/nginx-conf',   # её содержимое нужно брать с паппет-сервера по указанному адресу
        recurse => true,   # копировать файлы рекурсивно
        purge   => true,   # нужно удалять лишние файлы (те, которых нет в источнике)
        force   => true,   # удалять лишние директории
    }
  # Волнистая стрелка (~>) говорит о том, что ресурс ниже должен
  # подписаться на изменения ресурса, описанного выше.
  # Волнистая стрелка включает в себя прямую (->).
    ~> service { 'nginx':   # описываем сервис nginx
        ensure => running,   # он должен быть запущен
        enable => true,   # его нужно запускать автоматически при старте системы
    }
  # Когда ресурс типа service получает уведомление,
  # соответствующий сервис перезапускается.
}

ይህ እንዲሰራ፣ በአሻንጉሊት አገልጋዩ ላይ በግምት የሚከተለው የፋይል ቦታ ያስፈልግዎታል።

/etc/puppetlabs/code/environments/production/ # (это для нового Паппета, для старого корневой директорией будет /etc/puppet)
├── manifests/
│   └── site.pp
└── modules/
    └── example/
        └── files/
            └── nginx-conf/
                ├── nginx.conf
                ├── mime.types
                └── conf.d/
                    └── some.conf

የመርጃ ዓይነቶች

የሚደገፉ የንብረት ዓይነቶች ሙሉ ዝርዝር እዚህ ይገኛሉ በሰነዱ ውስጥ, እዚህ አምስት መሰረታዊ ዓይነቶችን እገልጻለሁ, በእኔ ልምምድ ውስጥ ብዙ ችግሮችን ለመፍታት በቂ ናቸው.

ፋይል

ፋይሎችን፣ ማውጫዎችን፣ ሲምሊንኮችን፣ ይዘቶቻቸውን እና የመዳረሻ መብቶችን ያስተዳድራል።

መለኪያዎች

  • የንብረት ስም - ወደ ፋይል መንገድ (አማራጭ)
  • ዱካ - ወደ ፋይሉ የሚወስደው መንገድ (በስሙ ውስጥ ካልተገለጸ)
  • ለማረጋገጥ - የፋይል ዓይነት;
    • absent - ፋይል ሰርዝ
    • present - ማንኛውም አይነት ፋይል መኖር አለበት (ፋይል ከሌለ መደበኛ ፋይል ይፈጠራል)
    • file - መደበኛ ፋይል
    • directory - ማውጫ
    • link - ሲምሊንክ
  • ይዘት - የፋይል ይዘቶች (ለመደበኛ ፋይሎች ብቻ ተስማሚ ፣ ከ ጋር አብሮ መጠቀም አይቻልም) áˆáŠ•áŒ­ ወይም ዒላማ)
  • ምንጭ - የፋይሉን ይዘት ለመቅዳት ወደሚፈልጉት መንገድ የሚወስድ አገናኝ (ከዚህ ጋር አብሮ መጠቀም አይቻልም á‹­á‹˜á‰ľ ወይም ዒላማ). እቅድ ያለው እንደ URI ወይ ሊገለጽ ይችላል። puppet: (ከዚያም ከአሻንጉሊት አገልጋዩ የተገኙ ፋይሎች ጥቅም ላይ ይውላሉ), እና ከእቅዱ ጋር http: (በዚህ ጉዳይ ላይ ምን እንደሚሆን ግልጽ እንደሆነ ተስፋ አደርጋለሁ), እና በስዕላዊ መግለጫው እንኳን file: ወይም እንደ ፍፁም መንገድ ያለ ንድፍ (ከዚያም ከአካባቢው FS በኖድ ላይ ያለው ፋይል ጥቅም ላይ ይውላል)
  • ዒላማ - ሲምሊንኩ የሚጠቁምበት ቦታ (ከጋር መጠቀም አይቻልም ይዘት ወይም ምንጭ)
  • ባለቤት - የፋይሉ ባለቤት መሆን ያለበት ተጠቃሚ
  • ቡድን - ፋይሉ መሆን ያለበት ቡድን
  • ሞድ - የፋይል ፈቃዶች (እንደ ሕብረቁምፊ)
  • እንደገና መመለሾ - ተደጋጋሚ ማውጫን ማቀናበር ያስችላል
  • ትውስታን - በአሻንጉሊት ውስጥ ያልተገለጹ ፋይሎችን መሰረዝን ያስችላል
  • ኃይል - በአሻንጉሊት ውስጥ ያልተገለጹ ማውጫዎችን መሰረዝ ያስችላል

እሽግ

ጥቅሎችን ይጭናል እና ያስወግዳል። ማሳወቂያዎችን ማስተናገድ የሚችል - መለኪያው ከተገለጸ ጥቅሉን እንደገና ይጭናል እንደገና ጫን_በአድስ.

መለኪያዎች

  • የንብረት ስም - የጥቅል ስም (አማራጭ)
  • ስም - የጥቅል ስም (በስሙ ውስጥ ካልተገለጸ)
  • አቅራቢ - ጥቅል አስተዳዳሪ ለመጠቀም
  • ለማረጋገጥ - የሚፈለገው የጥቅሉ ሁኔታ;
    • present, installed - ማንኛውም የተጫነ ስሪት
    • latest - የቅርብ ጊዜ ስሪት ተጭኗል
    • absent - ተሰርዟል (apt-get remove)
    • purged - ከውቅረት ፋይሎች ጋር ተሰርዟል (apt-get purge)
    • held - የጥቅል ስሪት ተቆልፏል (apt-mark hold)
    • любая другая строка - የተገለጸው ስሪት ተጭኗል
  • እንደገና ጫን_በአድስ - ከሆነ true, ከዚያም ማሳወቂያው እንደደረሰው ጥቅሉ እንደገና ይጫናል. የግንባታ መለኪያዎችን በሚቀይሩበት ጊዜ ጥቅሎችን እንደገና መገንባት አስፈላጊ በሚሆንበት ምንጭ ላይ ለተመሰረቱ ስርጭቶች ጠቃሚ። ነባሪ false.

አገልግሎት

አገልግሎቶችን ያስተዳድራል። ማሳወቂያዎችን ማካሄድ የሚችል - አገልግሎቱን እንደገና ያስጀምራል.

መለኪያዎች

  • የንብረት ስም - የሚተዳደር አገልግሎት (አማራጭ)
  • ስም - ማስተዳደር ያለበት አገልግሎት (በስሙ ውስጥ ካልተገለጸ)
  • ለማረጋገጥ - የሚፈለገው የአገልግሎቱ ሁኔታ;
    • running - ተጀመረ
    • stopped - ቆሟል
  • አንቃ - አገልግሎቱን ለመጀመር ችሎታን ይቆጣጠራል;
    • true - autorun ነቅቷል (systemctl enable)
    • mask - የተደበቀ (systemctl mask)
    • false - autorun ተሰናክሏል (systemctl disable)
  • እንደገና ጀምር - አገልግሎቱን እንደገና ለማስጀመር ትእዛዝ ይስጡ
  • ሁናቴ - የአገልግሎት ሁኔታን ለማረጋገጥ ትእዛዝ
  • እንደገና ተጀምሯል። - የአገልግሎቱ ኢንስክሪፕት እንደገና መጀመርን የሚደግፍ መሆኑን ያመልክቱ። ከሆነ false እና መለኪያው ተለይቷል እንደገና ጀምር - የዚህ ግቤት ዋጋ ጥቅም ላይ ይውላል. ከሆነ false እና መለኪያ እንደገና ጀምር አልተገለጸም - አገልግሎቱ ቆሟል እና እንደገና መጀመር ጀምሯል (ነገር ግን systemd ትዕዛዙን ይጠቀማል systemctl restart).
  • ችኮላ - የአገልግሎቱ ኢንስክሪፕት ትዕዛዙን የሚደግፍ መሆኑን ያመልክቱ status. ከሆነ false, ከዚያ የመለኪያ እሴቱ ጥቅም ላይ ይውላል ሁናቴ. ነባሪ true.

exec

ውጫዊ ትዕዛዞችን ያስኬዳል. መለኪያዎችን ካልገለጹ ይፈጥራል, ቢሆን ብቻ, በስተቀር ወይም መንፈስን የሚያድስ, ትዕዛዙ አሻንጉሊት በሚሠራበት ጊዜ ሁሉ ይሠራል. ማሳወቂያዎችን ማስኬድ የሚችል - ትዕዛዝ ያስኬዳል።

መለኪያዎች

  • የንብረት ስም - እንዲፈፀም ትእዛዝ (አማራጭ)
  • ትእዛዝ - የሚፈጸመው ትዕዛዝ (በስሙ ውስጥ ካልተገለጸ)
  • ዱካ - ተፈጻሚውን ፋይል የሚፈልግባቸው መንገዶች
  • ቢሆን ብቻ - በዚህ ግቤት ውስጥ የተገለጸው ትዕዛዝ በዜሮ መመለም ኮድ ከተጠናቀቀ ዋናው ትዕዛዝ ይፈጸማል
  • በስተቀር - በዚህ ግቤት ውስጥ የተገለጸው ትዕዛዝ ዜሮ ባልሆነ የመመለሻ ኮድ ከተጠናቀቀ ዋናው ትዕዛዝ ይፈጸማል
  • ይፈጥራል - በዚህ ግቤት ውስጥ የተገለጸው ፋይል ከሌለ ዋናው ትዕዛዝ ይፈጸማል
  • መንፈስን የሚያድስ - ከሆነ true, ከዚያ ትዕዛዙ የሚሰራው ይህ ኤክሰፕት ከሌሎች ምንጮች ማሳወቂያ ሲደርሰው ብቻ ነው
  • cwd - ትዕዛዙን የሚሠራበት ማውጫ
  • ተጠቃሚ - ትዕዛዙን የሚያስኬድ ተጠቃሚ
  • አቅራቢ - ትዕዛዙን እንዴት ማስኬድ እንደሚቻል;
    • ፖሴስ - የሕፃን ሂደት በቀላሉ ተፈጥሯል ፣ መግለፅዎን ያረጋግጡ ዱካ
    • ቀለህ - ትዕዛዙ በሼል ውስጥ ተጀምሯል /bin/sh፣ ላይገለጽ ይችላል። ዱካ, ግሎቢንግ, ቧንቧዎችን እና ሌሎች የሼል ባህሪያትን መጠቀም ይችላሉ. ልዩ ቁምፊዎች ካሉ (ብዙውን ጊዜ በራስ-ሰር ተገኝቷል)|, ;, &&, || ወዘተ)።

በመርሃግብሩ

ክሮንጆዎችን ይቆጣጠራል.

መለኪያዎች

  • የንብረት ስም - ልክ አንድ ዓይነት መለያ
  • ለማረጋገጥ - የዘውድ ሁኔታ;
    • present - ከሌለ ይፍጠሩ
    • absent - ካለ ይሰርዙ
  • ትእዛዝ - የትኛውን ትእዛዝ ለማሄድ
  • አካባቢ - ትዕዛዙን በየትኛው አካባቢ እንደሚሰራ (የአካባቢ ተለዋዋጮች ዝርዝር እና እሴቶቻቸው በ =)
  • ተጠቃሚ - ከየትኛው ተጠቃሚ ትዕዛዙን ለማስኬድ
  • ደቂቃ, ሰአት, የስራ ቀን, ወር, ወርሃዊ - ክሮን ሲሰል. ከእነዚህ ባህሪያት ውስጥ አንዳቸውም ካልተገለጹ፣ በ crontab ውስጥ ያለው ዋጋ ይሆናል። *.

በአሻንጉሊት 6.0 በመርሃግብሩ በ ከሳጥኑ ውስጥ ተወግዷል በአሻንጉሊት አገልጋይ ውስጥ, ስለዚህ በአጠቃላይ ጣቢያው ላይ ምንም ሰነድ የለም. ግን እሱ በሳጥኑ ውስጥ ነው በአሻንጉሊት-ወኪል, ስለዚህ በተናጠል መጫን አያስፈልግም. ለእሱ ሰነዶችን ማየት ይችላሉ ለአምስተኛው የአሻንጉሊት ስሪት በሰነዱ ውስጥ, ወይም በ GitHub ላይ.

ስለ ሀብቶች በአጠቃላይ

ለሀብት ልዩነት መስፈርቶች

የሚያጋጥመን በጣም የተለመደው ስህተት ነው። የተባዛ መግለጫ. ይህ ስህተት ሁለት ወይም ከዚያ በላይ ተመሳሳይ ተመሳሳይ ስም ያላቸው ተመሳሳይ ሀብቶች በማውጫው ውስጥ ሲታዩ ይከሰታል።

ስለዚ፡ ደግሜ እጽፋለሁ፡- ለተመሳሳይ መስቀለኛ መንገድ መገለጫዎች አንድ ዓይነት ርዕስ ያላቸው ተመሳሳይ ሀብቶችን መያዝ የለባቸውም!

አንዳንድ ጊዜ ተመሳሳይ ስም ያላቸው፣ ግን ከተለያዩ የጥቅል አስተዳዳሪዎች ጋር ፓኬጆችን መጫን ያስፈልጋል። በዚህ ሁኔታ, መለኪያውን መጠቀም ያስፈልግዎታል nameስህተቱን ለማስወገድ;

package { 'ruby-mysql':
  ensure   => installed,
  name     => 'mysql',
  provider => 'gem',
}
package { 'python-mysql':
  ensure   => installed,
  name     => 'mysql',
  provider => 'pip',
}

ማባዛትን ለማስወገድ ሌሎች የመርጃ ዓይነቶች ተመሳሳይ አማራጮች አሏቸው - name у አገልግሎት, command у exec, እናም ይቀጥላል.

Metaparameters

ተፈጥሮው ምንም ይሁን ምን እያንዳንዱ የንብረት አይነት አንዳንድ ልዩ መለኪያዎች አሉት.

የሜታ መለኪያዎች ሙሉ ዝርዝር በአሻንጉሊት ሰነድ ውስጥ.

አጭር ዝርዝር፡-

  • ይጠይቁ - ይህ ግቤት ይህ መገልገያ በየትኞቹ ሀብቶች ላይ እንደሚመረኮዝ ያሳያል።
  • ከዚህ በፊት - ይህ ግቤት የትኞቹ ሀብቶች በዚህ ሀብት ላይ እንደሚመሰረቱ ይገልጻል.
  • ለደንበኝነት - ይህ ግቤት ይህ ምንጭ ከየትኞቹ ምንጮች ማሳወቂያዎችን እንደሚቀበል ይገልጻል።
  • አሳውቅ - ይህ ግቤት የትኞቹ ሀብቶች ከዚህ ምንጭ ማሳወቂያዎችን እንደሚቀበሉ ይገልጻል።

ሁሉም የተዘረዘሩ ሜታፓራሜትሮች አንድ ነጠላ የንብረት ማገናኛን ወይም በካሬ ቅንፎች ውስጥ ያሉ አገናኞችን ድርድር ይቀበላሉ።

ወደ ሀብቶች አገናኞች

የንብረት ማገናኛ በቀላሉ የሀብቱን መጠቀስ ነው። በዋናነት ጥገኛነትን ለማመልከት ያገለግላሉ። የሌለ ሀብትን መጥቀስ የማጠናቀር ስህተትን ያስከትላል።

የአገናኙ አገባብ የሚከተለው ነው-የሀብት አይነት በካፒታል ፊደል (የአይነቱ ስም ድርብ ኮሎኖችን ከያዘ በኮሎኖች መካከል ያለው እያንዳንዱ የስም ክፍል ትልቅ ነው) ከዚያም የመርጃው ስም በካሬ ቅንፎች (የስሙ ጉዳይ) አይለወጥም!) ክፍተቶች ሊኖሩ አይገባም፤ የካሬ ቅንፎች የሚጻፉት ከስሙ በኋላ ወዲያውኑ ነው።

ለምሳሌ:

file { '/file1': ensure => present }
file { '/file2':
  ensure => directory,
  before => File['/file1'],
}
file { '/file3': ensure => absent }
File['/file1'] -> File['/file3']

ጥገኞች እና ማሳወቂያዎች

ሰነድ እዚህ።

ቀደም ሲል እንደተገለፀው በሀብቶች መካከል ቀላል ጥገኞች ተሻጋሪ ናቸው. በነገራችን ላይ ጥገኞችን ሲጨምሩ ይጠንቀቁ - ሳይክሊክ ጥገኞችን መፍጠር ይችላሉ, ይህም የማጠናቀር ስህተትን ያስከትላል.

እንደ ጥገኞች ሳይሆን ማሳወቂያዎች ተሻጋሪ አይደሉም። የሚከተሉት ደንቦች ለማሳወቂያዎች ተፈጻሚ ይሆናሉ፡

  • ሀብቱ ማሳወቂያ ከደረሰው ተዘምኗል። የማሻሻያ እርምጃዎች በንብረት አይነት - exec ትዕዛዙን ያካሂዳል ፣ አገልግሎት አገልግሎቱን እንደገና ይጀምራል ፣ እሽግ ጥቅሉን እንደገና ይጭናል. ሀብቱ የማዘመን እርምጃ ከሌለው ምንም ነገር አይከሰትም።
  • በአንድ የአሻንጉሊት ሩጫ ወቅት ሀብቱ ከአንድ ጊዜ በላይ አይዘመንም። ይህ ሊሆን የቻለው ማሳወቂያዎች ጥገኞችን ስለሚያካትቱ እና የጥገኛ ግራፉ ዑደቶችን ስለሌለው ነው።
  • አሻንጉሊት የሃብት ሁኔታን ከለወጠ ሃብቱ ለእሱ ለተመዘገቡት ሁሉም ምንጮች ማሳወቂያዎችን ይልካል።
  • አንድ መገልገያ ከተዘመነ፣ ለእሱ ለተመዘገቡት ሁሉም ምንጮች ማሳወቂያዎችን ይልካል።

ያልተገለጹ መለኪያዎች አያያዝ

እንደ ደንቡ ፣ አንዳንድ የንብረት ግቤት ነባሪ እሴት ከሌለው እና ይህ ግቤት በአንፀባራቂው ውስጥ ካልተገለጸ ፣ ከዚያ አሻንጉሊት ይህንን ንብረት በመስቀለኛ መንገዱ ላይ ላለው ተዛማጅ ሀብቶች አይለውጠውም። ለምሳሌ, የዓይነት ምንጭ ከሆነ ፋይል መለኪያ አልተገለጸም owner, ከዚያ አሻንጉሊት የተዛማጁን ፋይል ባለቤት አይለውጥም.

ለክፍሎች ፣ ተለዋዋጮች እና ትርጓሜዎች መግቢያ

የውቅሩ ተመሳሳይ ክፍል ያላቸው በርካታ አንጓዎች አሉን እንበል ነገር ግን ልዩነቶችም አሉ - ያለበለዚያ ሁሉንም በአንድ ብሎክ መግለፅ እንችላለን። node {}. እርግጥ ነው, የውቅረት ተመሳሳይ ክፍሎችን በቀላሉ መቅዳት ይችላሉ, ነገር ግን በአጠቃላይ ይህ መጥፎ መፍትሄ ነው - አወቃቀሩ ያድጋል, እና የአቀማመጡን አጠቃላይ ክፍል ከቀየሩ, ተመሳሳይ ነገር በብዙ ቦታዎች ላይ ማስተካከል አለብዎት. በተመሳሳይ ጊዜ, ስህተት ለመሥራት ቀላል ነው, እና በአጠቃላይ, DRY (እራስዎን አይድገሙ) መርህ የተፈጠረው በአንድ ምክንያት ነው.

ይህንን ችግር ለመፍታት እንደዚህ ያለ ንድፍ አለ класс.

ክፍሎች

ክፍል á‹¨á‰°áˆ°á‹¨áˆ˜ የፖፕ ኮድ ኮድ ነው። ኮድን እንደገና ለመጠቀም ክፍሎች ያስፈልጋሉ።

በመጀመሪያ ክፍሉን መግለጽ ያስፈልጋል. መግለጫው ራሱ በየትኛውም ቦታ ምንም አይነት ሀብቶችን አይጨምርም. ክፍሉ በመገለጫዎች ውስጥ ተገልጿል-

# Описание класса начинается с ключевого слова class и его названия.
# Дальше идёт тело класса в фигурных скобках.
class example_class {
    ...
}

ከዚህ በኋላ ክፍሉን መጠቀም ይቻላል-

# первый вариант использования — в стиле ресурса с типом class
class { 'example_class': }
# второй вариант использования — с помощью функции include
include example_class
# про отличие этих двух вариантов будет рассказано дальше

ከቀዳሚው ተግባር ምሳሌ - የ nginx ን መጫን እና ማዋቀር ወደ ክፍል እናንቀሳቅስ።

class nginx_example {
    package { 'nginx':
        ensure => installed,
    }
    -> file { '/etc/nginx':
        ensure => directory,
        source => 'puppet:///modules/example/nginx-conf',
        recure => true,
        purge  => true,
        force  => true,
    }
    ~> service { 'nginx':
        ensure => running,
        enable => true,
    }
}

node 'server2.testdomain' {
    include nginx_example
}

ተለዋዋጮች

ከቀዳሚው ምሳሌ ውስጥ ያለው ክፍል በጭራሽ ተለዋዋጭ አይደለም ምክንያቱም ሁልጊዜ ተመሳሳይ የ nginx ውቅር ያመጣል። ወደ ውቅረቱ ተለዋዋጭ መንገዱን እናድርገው ፣ ከዚያ ይህ ክፍል nginx ን ከማንኛውም ውቅር ጋር ለመጫን ሊያገለግል ይችላል።

ሊደረግ ይችላል ተለዋዋጮችን በመጠቀም.

ትኩረት: በአሻንጉሊት ውስጥ ያሉ ተለዋዋጮች የማይለወጡ ናቸው!

በተጨማሪም, ተለዋዋጭ ሊደረስበት የሚችለው ከተገለጸ በኋላ ብቻ ነው, አለበለዚያ የተለዋዋጭ ዋጋ ይሆናል undef.

ከተለዋዋጮች ጋር የመሥራት ምሳሌ፡-

# создание переменных
$variable = 'value'
$var2 = 1
$var3 = true
$var4 = undef
# использование переменных
$var5 = $var6
file { '/tmp/text': content => $variable }
# интерполяция переменных — раскрытие значения переменных в строках. Работает только в двойных кавычках!
$var6 = "Variable with name variable has value ${variable}"

አሻንጉሊት አለው የስም ቦታዎች, እና ተለዋዋጮች, በዚህ መሠረት, አላቸው የታይነት አካባቢ: ተመሳሳይ ስም ያለው ተለዋዋጭ በተለያዩ የስም ቦታዎች ሊገለጽ ይችላል. የተለዋዋጭ እሴትን በሚፈታበት ጊዜ, ተለዋዋጭው አሁን ባለው የስም ቦታ, ከዚያም በተዘጋው የስም ቦታ, ወዘተ.

የስም ቦታ ምሳሌዎች፡-

  • ዓለም አቀፋዊ - ከክፍል ውጭ ያሉ ተለዋዋጮች ወይም የመስቀለኛ ክፍል መግለጫ ወደዚያ ይሄዳሉ;
  • በመስቀለኛ ክፍል ውስጥ የመስቀለኛ ስም ቦታ;
  • በክፍል መግለጫ ውስጥ የክፍል ስም ቦታ.

ተለዋዋጭ ሲደርሱ አሻሚነትን ለማስወገድ፣ በተለዋዋጭ ስም ውስጥ የስም ቦታውን መግለጽ ይችላሉ፡

# переменная без пространства имён
$var
# переменная в глобальном пространстве имён
$::var
# переменная в пространстве имён класса
$classname::var
$::classname::var

ወደ nginx ውቅር የሚወስደው መንገድ በተለዋዋጭ ውስጥ እንዳለ እንስማማ $nginx_conf_source. ከዚያ ክፍሉ እንደዚህ ይመስላል

class nginx_example {
    package { 'nginx':
        ensure => installed,
    }
    -> file { '/etc/nginx':
        ensure => directory,
        source => $nginx_conf_source,   # здесь используем переменную вместо фиксированной строки
        recure => true,
        purge  => true,
        force  => true,
    }
    ~> service { 'nginx':
        ensure => running,
        enable => true,
    }
}

node 'server2.testdomain' {
    $nginx_conf_source = 'puppet:///modules/example/nginx-conf'
    include nginx_example
}

ሆኖም ግን, የተሰጠው ምሳሌ መጥፎ ነው, ምክንያቱም አንዳንድ "ሚስጥራዊ እውቀት" በክፍል ውስጥ የሆነ ቦታ ላይ እንደዚህ ያለ ስም ያለው ተለዋዋጭ ጥቅም ላይ ይውላል. ይህንን እውቀት አጠቃላይ ማድረግ የበለጠ ትክክል ነው - ክፍሎች ግቤቶች ሊኖራቸው ይችላል።

የክፍል መለኪያዎች á‰ áŠ­ááˆ የስም ቦታ ውስጥ ተለዋዋጮች ናቸው፣ እነሱ በክፍል ራስጌ ውስጥ የተገለጹ እና በክፍል አካል ውስጥ እንደ መደበኛ ተለዋዋጮች ጥቅም ላይ ሊውሉ ይችላሉ። በአንፀባራቂው ውስጥ ክፍሉን ሲጠቀሙ የመለኪያ እሴቶች ይገለፃሉ።

መለኪያው ወደ ነባሪ እሴት ሊዋቀር ይችላል። መለኪያው ነባሪ እሴት ከሌለው እና እሴቱ ጥቅም ላይ ሲውል ካልተዋቀረ የማጠናቀር ስህተትን ያስከትላል።

ክፍሉን ከላይ ካለው ምሳሌ እንጥቀስ እና ሁለት ግቤቶችን እንጨምር-የመጀመሪያው ፣ የሚፈለገው ፣ ወደ ውቅር የሚወስደው መንገድ ነው ፣ እና ሁለተኛው ፣ አማራጭ ፣ የጥቅሉ ስም ከ nginx ጋር ነው (በዴቢያን ፣ ለምሳሌ ፣ ጥቅሎች አሉ። nginx, nginx-light, nginx-full).

# переменные описываются сразу после имени класса в круглых скобках
class nginx_example (
  $conf_source,
  $package_name = 'nginx-light', # параметр со значением по умолчанию
) {
  package { $package_name:
    ensure => installed,
  }
  -> file { '/etc/nginx':
    ensure  => directory,
    source  => $conf_source,
    recurse => true,
    purge   => true,
    force   => true,
  }
  ~> service { 'nginx':
    ensure => running,
    enable => true,
  }
}

node 'server2.testdomain' {
  # если мы хотим задать параметры класса, функция include не подойдёт* — нужно использовать resource-style declaration
  # *на самом деле подойдёт, но про это расскажу в следующей серии. Ключевое слово "Hiera".
  class { 'nginx_example':
    conf_source => 'puppet:///modules/example/nginx-conf',   # задаём параметры класса точно так же, как параметры для других ресурсов
  }
}

በአሻንጉሊት ውስጥ, ተለዋዋጮች ይጻፋሉ. ብላ ብዙ የውሂብ አይነቶች. የውሂብ አይነቶች በተለምዶ ወደ ክፍሎች እና ትርጓሜዎች የተላለፉትን የመለኪያ እሴቶችን ለማረጋገጥ ያገለግላሉ። ያለፈው ግቤት ከተጠቀሰው አይነት ጋር የማይመሳሰል ከሆነ, የማጠናቀር ስህተት ይከሰታል.

አይነቱ ከመለኪያው ስም በፊት ወዲያውኑ ይፃፋል፡-

class example (
  String $param1,
  Integer $param2,
  Array $param3,
  Hash $param4,
  Hash[String, String] $param5,
) {
  ...
}

ክፍሎች፡ የክፍል ስም ከክፍል ጋር ያካትታሉ{'የክፍል ስም'፡}

እያንዳንዱ ክፍል የዓይነት ምንጭ ነው መደብ. እንደሌላው የሀብት አይነት፣ በአንድ መስቀለኛ መንገድ ላይ የአንድ ክፍል ሁለት አጋጣሚዎች ሊኖሩ አይችሉም።

ሁለት ጊዜ ተጠቅመው አንድ ክፍል ወደ ተመሳሳይ መስቀለኛ መንገድ ለመጨመር ከሞከሩ class { 'classname':} (ምንም ልዩነት የለም, ከተለያዩ ወይም ተመሳሳይ መለኪያዎች ጋር), የማጠናቀር ስህተት ይኖራል. ነገር ግን በንብረት ዘይቤ ውስጥ ክፍልን ከተጠቀሙ ወዲያውኑ ሁሉንም መመዘኛዎቹን በአንፀባራቂው ውስጥ በትክክል ማዘጋጀት ይችላሉ።

ሆኖም ግን, ከተጠቀሙ include, ከዚያም ክፍሉን በተፈለገው መጠን ብዙ ጊዜ መጨመር ይቻላል. እውነታው ይህ ነው። include áŠ áŠ•á‹ľ ክፍል ወደ ማውጫው መጨመሩን የሚፈትሽ ኢ-አድራጎት ተግባር ነው። ክፍሉ በማውጫው ውስጥ ካልሆነ, ይጨምረዋል, እና ቀድሞውኑ ካለ, ምንም አያደርግም. ነገር ግን በአጠቃቀም ሁኔታ include በክፍል መግለጫ ጊዜ የክፍል መለኪያዎችን ማዘጋጀት አይችሉም - ሁሉም አስፈላጊ መለኪያዎች በውጫዊ የውሂብ ምንጭ - Hiera ወይም ENC ውስጥ መቀመጥ አለባቸው. በሚቀጥለው ርዕስ ውስጥ ሾለ እነርሱ እንነጋገራለን.

ይገልፃል።

በቀደመው ብሎክ ላይ እንደተነገረው አንድ አይነት ክፍል ከአንድ ጊዜ በላይ በመስቀለኛ መንገድ ላይ ሊገኝ አይችልም። ነገር ግን፣ በአንዳንድ አጋጣሚዎች በተመሳሳይ መስቀለኛ መንገድ ላይ ከተለያዩ መመዘኛዎች ጋር አንድ አይነት የማገጃ ኮድ መጠቀም መቻል አለብዎት። በሌላ አነጋገር, የራሱ የሆነ የንብረት አይነት ያስፈልጋል.

ለምሳሌ፣ የ PHP ሞጁሉን ለመጫን በአቪቶ ውስጥ የሚከተሉትን እናደርጋለን።

  1. ጥቅሉን በዚህ ሞጁል ይጫኑ.
  2. ለዚህ ሞጁል የማዋቀሪያ ፋይል እንፍጠር።
  3. ለ php-fpm ውቅረት ሲምሊንክ እንፈጥራለን።
  4. ለ php cli ውቅረት ሲምሊንክ እንፈጥራለን።

በእንደዚህ ዓይነት ሁኔታዎች ውስጥ እንደ ንድፍ መግለፅ (የተገለፀው ፣ የተገለጸው ዓይነት ፣ የተገለጸ የንብረት ዓይነት)። Define ከክፍል ጋር ተመሳሳይ ነው, ግን ልዩነቶች አሉ: በመጀመሪያ, እያንዳንዱ Define የንብረት አይነት እንጂ ሃብት አይደለም; በሁለተኛ ደረጃ, እያንዳንዱ ፍቺ ግልጽ የሆነ መለኪያ አለው $title, በሚታወቅበት ጊዜ የመርጃው ስም የሚሄድበት. ልክ በክፍሎች ሁኔታ ውስጥ, ፍቺ በመጀመሪያ መገለጽ አለበት, ከዚያ በኋላ ጥቅም ላይ ሊውል ይችላል.

ለ PHP ሞጁል ያለው ቀለል ያለ ምሳሌ፡-

define php74::module (
  $php_module_name = $title,
  $php_package_name = "php7.4-${title}",
  $version = 'installed',
  $priority = '20',
  $data = "extension=${title}.son",
  $php_module_path = '/etc/php/7.4/mods-available',
) {
  package { $php_package_name:
    ensure          => $version,
    install_options => ['-o', 'DPkg::NoTriggers=true'],  # триггеры дебиановских php-пакетов сами создают симлинки и перезапускают сервис php-fpm - нам это не нужно, так как и симлинками, и сервисом мы управляем с помощью Puppet
  }
  -> file { "${php_module_path}/${php_module_name}.ini":
    ensure  => $ensure,
    content => $data,
  }
  file { "/etc/php/7.4/cli/conf.d/${priority}-${php_module_name}.ini":
    ensure  => link,
    target  => "${php_module_path}/${php_module_name}.ini",
  }
  file { "/etc/php/7.4/fpm/conf.d/${priority}-${php_module_name}.ini":
    ensure  => link,
    target  => "${php_module_path}/${php_module_name}.ini",
  }
}

node server3.testdomain {
  php74::module { 'sqlite3': }
  php74::module { 'amqp': php_package_name => 'php-amqp' }
  php74::module { 'msgpack': priority => '10' }
}

የተባዛ መግለጫ ስህተትን ለመያዝ ቀላሉ መንገድ በ Define ውስጥ ነው። ይህ የሚሆነው ፍቺ ቋሚ ስም ያለው ምንጭ ካለው እና በአንዳንድ መስቀለኛ መንገድ ላይ የዚህ ፍቺ ሁለት ወይም ከዚያ በላይ አጋጣሚዎች ካሉ ነው።

እራስዎን ከዚህ መጠበቅ ቀላል ነው፡ በትርጉሙ ውስጥ ያሉት ሁሉም ሃብቶች በዚህ ላይ በመመስረት ስም ሊኖራቸው ይገባል። $title. አንድ አማራጭ የሃብት መጨመር አቅም ያለው ነው ፣ በቀላል ሁኔታ ፣ በሁሉም የትርጉም ሁኔታዎች ውስጥ ያሉትን ሀብቶች ወደ የተለየ ክፍል ማዛወር እና ይህንን ክፍል በትርጉሙ ውስጥ ማካተት በቂ ነው - ተግባር include ኃይለኛ።

ሀብቶችን በሚጨምሩበት ጊዜ አካላዊ ጥንካሬን ለማግኘት ሌሎች መንገዶች አሉ ፣ ማለትም ተግባራት defined и ensure_resourcesግን በሚቀጥለው ክፍል ስለ ጉዳዩ እነግራችኋለሁ.

ለክፍሎች እና ለትርጉሞች ጥገኞች እና ማሳወቂያዎች

ክፍሎች እና ትርጓሜዎች ጥገኝነቶችን እና ማሳወቂያዎችን ለማስተናገድ የሚከተሉትን ህጎች ይጨምራሉ።

  • በክፍል/መግለጫ ላይ ጥገኝነት በሁሉም የክፍል/የመግለጫ ሀብቶች ላይ ጥገኛነትን ይጨምራል።
  • የመደብ/የመወሰን ጥገኝነት በሁሉም ክፍል ላይ ጥገኛነትን ይጨምራል/ንብረቶችን መግለፅ;
  • ክፍል/መግለጽ ማስታወቂያ የክፍል/መግለጽ ሁሉንም ሀብቶች ያሳውቃል;
  • የክፍል/መግለጫ የደንበኝነት ምዝገባ ለሁሉም የክፍሉ ምንጮች ይመዘገባል/ይገልፃል።

ሁኔታዊ መግለጫዎች እና መራጮች

ሰነድ እዚህ።

if

እዚህ ቀላል ነው፡-

if ВЫРАЖЕНИЕ1 {
  ...
} elsif ВЫРАЖЕНИЕ2 {
  ...
} else {
  ...
}

በስተቀር

በተቃራኒው ካልሆነ በስተቀር፡ አገላለጹ ሐሰት ከሆነ የኮዱ እገዳ ይፈጸማል።

unless ВЫРАЖЕНИЕ {
  ...
}

ክስ

እዚህም ምንም የተወሳሰበ ነገር የለም. መደበኛ እሴቶችን (ሕብረቁምፊዎች ፣ ቁጥሮች ፣ ወዘተ) ፣ መደበኛ መግለጫዎችን እና የውሂብ ዓይነቶችን እንደ እሴቶች መጠቀም ይችላሉ።

case ВЫРАЖЕНИЕ {
  ЗНАЧЕНИЕ1: { ... }
  ЗНАЧЕНИЕ2, ЗНАЧЕНИЕ3: { ... }
  default: { ... }
}

መራጮች

መራጭ የሚመስለው የቋንቋ ግንባታ ነው። caseነገር ግን የኮድ ብሎክን ከማስፈጸም ይልቅ እሴትን ይመልሳል።

$var = $othervar ? { 'val1' => 1, 'val2' => 2, default => 3 }

Модули

አወቃቀሩ ትንሽ ሲሆን, በቀላሉ በአንድ አንጸባራቂ ውስጥ ሊቀመጥ ይችላል. ግን ብዙ አወቃቀሮችን በገለፅን ቁጥር በአንጸባራቂው ውስጥ ብዙ ክፍሎች እና አንጓዎች አሉ ፣ ያድጋል ፣ እና ከእሱ ጋር ለመስራት የማይመች ይሆናል።

በተጨማሪም, ኮድ እንደገና ጥቅም ላይ ማዋል ችግር አለ - ሁሉም ኮዶች በአንድ አንጸባራቂ ውስጥ ሲሆኑ, ይህን ኮድ ለሌሎች ማጋራት አስቸጋሪ ነው. እነዚህን ሁለት ችግሮች ለመፍታት፣ አሻንጉሊቱ ሞጁሎች የሚባል አካል አለው።

Модули - እነዚህ በተለየ ማውጫ ውስጥ የተቀመጡ የክፍሎች፣ ትርጓሜዎች እና ሌሎች የአሻንጉሊት አካላት ስብስቦች ናቸው። በሌላ አነጋገር ሞጁል ራሱን የቻለ የአሻንጉሊት ሎጂክ ነው። ለምሳሌ, ከ nginx ጋር ለመስራት ሞጁል ሊኖር ይችላል, እና ከ nginx ጋር ለመስራት የሚያስፈልገውን እና ምን ብቻ ይይዛል, ወይም ከ PHP ጋር ለመስራት ሞጁል, ወዘተ.

ሞጁሎች የተስተካከሉ ናቸው፣ እና የሞጁሎች ጥገኞች እርስ በእርስ ይደገፋሉ። የሞጁሎች ክፍት ማከማቻ አለ - አሻንጉሊት ፎርጅ.

በአሻንጉሊት አገልጋይ ላይ ፣ ሞጁሎች በስር ማውጫው ሞጁሎች ንዑስ ማውጫ ውስጥ ይገኛሉ ። በእያንዳንዱ ሞጁል ውስጥ መደበኛ የማውጫ እቅድ አለ - መግለጫዎች ፣ ፋይሎች ፣ አብነቶች ፣ ሊብ ፣ ወዘተ.

በአንድ ሞጁል ውስጥ የፋይል መዋቅር

የሞጁሉ ሥር የሚከተሉትን ገላጭ ስሞች የያዘ ማውጫ ሊይዝ ይችላል።

  • manifests - ማኒፌስቶዎችን ይዟል
  • files - ፋይሎችን ይዟል
  • templates - አብነቶችን ይዟል
  • lib - የ Ruby ኮድ ይዟል

ይህ የተሟላ የማውጫ እና የፋይሎች ዝርዝር አይደለም, ግን ለዚህ ጽሑፍ አሁን በቂ ነው.

በሞጁሉ ውስጥ የንብረቶች እና የፋይሎች ስሞች

ሰነድ እዚህ።

በአንድ ሞጁል ውስጥ ያሉ ሀብቶች (ክፍሎች፣ ትርጓሜዎች) የፈለጉትን ስም ሊጠሩ አይችሉም። በተጨማሪም፣ በንብረት ስም እና በፋይሉ ስም መካከል ቀጥተኛ የደብዳቤ ልውውጥ አለ። የስያሜ ህጎቹን ከጣሱ፣ አሻንጉሊቱ በቀላሉ የንብረት መግለጫውን አያገኝም እና የማጠናቀር ስህተት ይደርስብዎታል።

ደንቦቹ ቀላል ናቸው፡-

  • በአንድ ሞጁል ውስጥ ያሉ ሁሉም ሀብቶች በሞጁል የስም ቦታ ውስጥ መሆን አለባቸው። ሞጁሉ ከተጠራ foo, ከዚያም በውስጡ ያሉት ሁሉም ሀብቶች መሰየም አለባቸው foo::<anything>፣ ወይም ብቻ foo.
  • የሞጁሉ ስም ያለው ምንጭ በፋይሉ ውስጥ መሆን አለበት init.pp.
  • ለሌሎች ግብዓቶች፣ የፋይል አወጣጥ ዘዴው እንደሚከተለው ነው።
    • የሞጁል ስም ያለው ቅድመ ቅጥያ ተጥሏል።
    • ሁሉም ድርብ ኮሎን, ካለ, በቆርቆሮዎች ይተካሉ
    • ቅጥያ ታክሏል .pp

በምሳሌ አሳይሻለሁ። ሞጁል እየጻፍኩ ነው እንበል nginx. በውስጡም የሚከተሉትን ሀብቶች ይዟል.

  • кНасс nginx በአንጸባራቂው ውስጥ ተገልጿል init.pp;
  • кНасс nginx::service በአንጸባራቂው ውስጥ ተገልጿል service.pp;
  • መግለፅ nginx::server በአንጸባራቂው ውስጥ ተገልጿል server.pp;
  • መግለፅ nginx::server::location በአንጸባራቂው ውስጥ ተገልጿል server/location.pp.

አብነቶች

አብነቶች ምን እንደሆኑ አንተ ራስህ ታውቃለህ፤ እዚህ በዝርዝር አልገልጻቸውም። ግን እንደ አጋጣሚ ብቻ እተወዋለሁ ወደ ዊኪፔዲያ አገናኝ.

አብነቶችን እንዴት መጠቀም እንደሚቻል፡ የአብነት ትርጉም ተግባርን በመጠቀም ሊሰፋ ይችላል። templateወደ አብነት የሚወስደውን መንገድ የሚያልፍ። ለዓይነት ሀብቶች ፋይል ከመለኪያው ጋር አንድ ላይ ጥቅም ላይ ይውላል content. ለምሳሌ፣ እንደዚህ፡-

file { '/tmp/example': content => template('modulename/templatename.erb')

የእይታ መንገድ <modulename>/<filename> ፋይልን ያመለክታል <rootdir>/modules/<modulename>/templates/<filename>.

በተጨማሪም, አንድ ተግባር አለ inline_template - የአብነት ጽሁፍ የሚቀበለው እንደ ግብአት እንጂ የፋይል ስም አይደለም።

በአብነት ውስጥ፣ አሁን ባለው ወሰን ሁሉንም የአሻንጉሊት ተለዋዋጮችን መጠቀም ይችላሉ።

አሻንጉሊት በERB እና EPP ቅርጸት አብነቶችን ይደግፋል፡-

ስለ ኢአርቢ በአጭሩ

የቁጥጥር መዋቅሮች;

  • <%= ВЫРАЖЕНИЕ %> - የመግለጫውን ዋጋ ያስገቡ
  • <% ВЫРАЖЕНИЕ %> - የአንድን አገላለጽ ዋጋ ያሰሉ (ሳያስገቡት)። ሁኔታዊ መግለጫዎች (ከሆነ) እና loops (እያንዳንዱ) ብዙውን ጊዜ እዚህ ይሄዳሉ።
  • <%# КОММЕНТАРИЙ %>

በERB ውስጥ ያሉ አገላለጾች የተፃፉት በሩቢ ነው (ERB በእውነቱ የተካተተ Ruby ነው)።

ከአንጸባራቂው ውስጥ ተለዋዋጮችን ለመድረስ፣ ማከል አለብህ @ ወደ ተለዋዋጭ ስም. ከቁጥጥር ግንባታ በኋላ የሚታየውን የመስመር መግቻ ለማስወገድ የመዝጊያ መለያ መጠቀም ያስፈልግዎታል -%>.

አብነቱን የመጠቀም ምሳሌ

ZooKeeperን ለመቆጣጠር ሞጁል እየጻፍኩ ነው እንበል። አወቃቀሩን የመፍጠር ኃላፊነት ያለው ክፍል ይህን ይመስላል።

class zookeeper::configure (
  Array[String] $nodes,
  Integer $port_client,
  Integer $port_quorum,
  Integer $port_leader,
  Hash[String, Any] $properties,
  String $datadir,
) {
  file { '/etc/zookeeper/conf/zoo.cfg':
    ensure  => present,
    content => template('zookeeper/zoo.cfg.erb'),
  }
}

እና ተጓዳኝ አብነት zoo.cfg.erb - ስለዚህ:

<% if @nodes.length > 0 -%>
<% @nodes.each do |node, id| -%>
server.<%= id %>=<%= node %>:<%= @port_leader %>:<%= @port_quorum %>;<%= @port_client %>
<% end -%>
<% end -%>

dataDir=<%= @datadir %>

<% @properties.each do |k, v| -%>
<%= k %>=<%= v %>
<% end -%>

እውነታዎች እና አብሮገነብ ተለዋዋጮች

ብዙውን ጊዜ የማዋቀሪያው የተወሰነ ክፍል በአሁኑ ጊዜ በመስቀለኛ መንገድ ላይ ባለው ላይ ይወሰናል. ለምሳሌ፣ የዴቢያን መልቀቂያ ምን እንደሆነ ላይ በመመስረት አንድ ወይም ሌላ የጥቅሉን ስሪት መጫን ያስፈልግዎታል። ይህንን ሁሉ እራስዎ መከታተል ይችላሉ ፣ አንጓዎች ከተቀየሩ እንደገና መፃፍ። ግን ይህ ከባድ አካሄድ አይደለም ፣ አውቶማቲክ በጣም የተሻለ ነው።

ሾለ አንጓዎች መረጃ ለማግኘት፣ አሻንጉሊት እውነታዎች የሚባል ዘዴ አለው። መረጃ - ይህ ሾለ መስቀለኛ መንገድ መረጃ ነው, በአለምአቀፍ የስም ቦታ ውስጥ በተለመደው ተለዋዋጮች መልክ ይገኛል. ለምሳሌ፣ የአስተናጋጅ ስም፣ የስርዓተ ክወና ስሪት፣ ፕሮሰሰር አርክቴክቸር፣ የተጠቃሚዎች ዝርዝር፣ የአውታረ መረብ በይነገጾች ዝርዝር እና አድራሻዎቻቸው፣ እና ብዙ እና ሌሎችም። እውነታዎች በመገለጫዎች እና በአብነት ውስጥ እንደ መደበኛ ተለዋዋጮች ይገኛሉ።

ከእውነታዎች ጋር የመሥራት ምሳሌ፡-

notify { "Running OS ${facts['os']['name']} version ${facts['os']['release']['full']}": }
# ресурс типа notify просто выводит сообщение в лог

በመደበኛ አነጋገር፣ አንድ እውነታ ስም (ሕብረቁምፊ) እና እሴት አለው (የተለያዩ ዓይነቶች አሉ፡ ሕብረቁምፊዎች፣ ድርድሮች፣ መዝገበ ቃላት)። ብላ አብሮገነብ እውነታዎች ስብስብ. እንዲሁም የራስዎን መጻፍ ይችላሉ. እውነታ ሰብሳቢዎች ተገልጸዋል። እንደ Ruby ውስጥ ያሉ ተግባራትእንደ ሊተገበሩ የሚችሉ ፋይሎች. እውነታዎች በቅጹም ሊቀርቡ ይችላሉ የጽሑፍ ፋይሎች ከውሂብ ጋር በመስቀለኛ መንገድ ላይ.

በሚሠራበት ጊዜ የአሻንጉሊት ወኪሉ ሁሉንም የሚገኙትን እውነታ ሰብሳቢዎች ከፓፕትሰርቨር ወደ መስቀለኛ መንገድ ይገለበጣል ፣ ከዚያ በኋላ ያስነሳቸዋል እና የተሰበሰቡትን እውነታዎች ወደ አገልጋዩ ይልካል ። ከዚህ በኋላ አገልጋዩ ካታሎጉን ማጠናቀር ይጀምራል።

እውነታዎች ሊተገበሩ በሚችሉ ፋይሎች መልክ

እንደነዚህ ያሉ እውነታዎች በማውጫው ውስጥ በሞጁሎች ውስጥ ተቀምጠዋል facts.d. በእርግጥ, ፋይሎቹ ሊተገበሩ የሚችሉ መሆን አለባቸው. በሚሮጡበት ጊዜ መረጃን በ YAML ወይም key=value format ወደ መደበኛ ውፅዓት ማውጣት አለባቸው።

እውነታዎች ሞጁልዎ በተሰማራበት በፖፕ አገልጋይ ቁጥጥር ስር ባሉ ሁሉም አንጓዎች ላይ እንደሚተገበሩ አይርሱ። ስለዚህ, በስክሪፕቱ ውስጥ, ስርዓቱ ለእርስዎ እውነታ እንዲሰራ አስፈላጊ የሆኑ ሁሉም ፕሮግራሞች እና ፋይሎች እንዳሉ ለማረጋገጥ ይጠንቀቁ.

#!/bin/sh
echo "testfact=success"
#!/bin/sh
echo '{"testyamlfact":"success"}'

የሩቢ እውነታዎች

እንደነዚህ ያሉ እውነታዎች በማውጫው ውስጥ በሞጁሎች ውስጥ ተቀምጠዋል lib/facter.

# всё начинается с вызова функции Facter.add с именем факта и блоком кода
Facter.add('ladvd') do
# в блоках confine описываются условия применимости факта — код внутри блока должен вернуть true, иначе значение факта не вычисляется и не возвращается
  confine do
    Facter::Core::Execution.which('ladvdc') # проверим, что в PATH есть такой исполняемый файл
  end
  confine do
    File.socket?('/var/run/ladvd.sock') # проверим, что есть такой UNIX-domain socket
  end
# в блоке setcode происходит собственно вычисление значения факта
  setcode do
    hash = {}
    if (out = Facter::Core::Execution.execute('ladvdc -b'))
      out.split.each do |l|
        line = l.split('=')
        next if line.length != 2
        name, value = line
        hash[name.strip.downcase.tr(' ', '_')] = value.strip.chomp(''').reverse.chomp(''').reverse
      end
    end
    hash  # значение последнего выражения в блоке setcode является значением факта
  end
end

የጽሑፍ እውነታዎች

እንደነዚህ ያሉ እውነታዎች በማውጫው ውስጥ ባሉ አንጓዎች ላይ ተቀምጠዋል /etc/facter/facts.d በአሮጌ አሻንጉሊት ወይም /etc/puppetlabs/facts.d በአዲሱ አሻንጉሊት ውስጥ.

examplefact=examplevalue
---
examplefact2: examplevalue2
anotherfact: anothervalue

ወደ እውነታዎች መድረስ

ወደ እውነታዎች ለመቅረብ ሁለት መንገዶች አሉ፡-

  • መዝገበ ቃላት በኩል $facts: $facts['fqdn'];
  • የእውነታውን ስም እንደ ተለዋዋጭ ስም በመጠቀም፡- $fqdn.

መዝገበ ቃላት መጠቀም ጥሩ ነው። $facts፣ ወይም እንዲያውም የተሻለ፣ የአለምአቀፍ የስም ቦታን ያመልክቱ ($::facts).

የሰነዱ ተዛማጅ ክፍል ይኸውና.

አብሮገነብ ተለዋዋጮች

ከእውነታው በተጨማሪ, እንዲሁ አለ አንዳንድ ተለዋዋጮች፣ በአለምአቀፍ የስም ቦታ ይገኛል።

  • የታመኑ እውነታዎች - ከደንበኛው የምስክር ወረቀት የተወሰዱ ተለዋዋጮች (የምስክር ወረቀቱ ብዙውን ጊዜ በፖፕ አገልጋይ ላይ ስለሚሰጥ ወኪሉ የምስክር ወረቀቱን ብቻ ወስዶ መለወጥ አይችልም ፣ ስለዚህ ተለዋዋጮቹ “የታመኑ” ናቸው) የምስክር ወረቀት ስም ፣ የምስክር ወረቀት ስም አስተናጋጅ እና ጎራ, ከእውቅና ማረጋገጫው ቅጥያዎች.
  • የአገልጋይ እውነታዎች -ሾለ አገልጋዩ መረጃ ጋር የተያያዙ ተለዋዋጮች-ስሪት፣ ስም፣ የአገልጋይ IP አድራሻ፣ አካባቢ።
  • ወኪል እውነታዎች - ተለዋዋጮች በቀጥታ በአሻንጉሊት-ወኪል የተጨመሩ እንጂ በፋተር አይደለም - የምስክር ወረቀት ስም፣ የወኪል ሥሪት፣ የአሻንጉሊት ሥሪት።
  • ዋና ተለዋዋጮች - የፓፔትማስተር ተለዋዋጮች (sic!) ውስጥ ካለው ጋር ተመሳሳይ ነው። á‹¨áŠ áŒˆáˆáŒ‹á‹­ እውነታዎች፣ ሲደመር የውቅር ግቤት እሴቶች አሉ።
  • የማጠናከሪያ ተለዋዋጮች - በእያንዳንዱ ወሰን የሚለያዩ የኮምፕሌተር ተለዋዋጮች-የአሁኑ ሞጁል ስም እና የአሁኑ ነገር የተገኘበት የሞጁል ስም። እነሱ ለምሳሌ የግል ክፍሎችዎ ከሌሎች ሞጁሎች በቀጥታ ጥቅም ላይ እንዳልዋሉ ለማረጋገጥ ሊጠቀሙበት ይችላሉ።

ተጨማሪ 1: ይህን ሁሉ እንዴት ማስኬድ እና ማረም?

ጽሑፉ ብዙ የአሻንጉሊት ኮድ ምሳሌዎችን ይዟል፣ ግን ይህን ኮድ እንዴት ማስኬድ እንዳለብን በጭራሽ አልነገረንም። እሺ ራሴን እያረምኩ ነው።

Puppetን ለማስኬድ ወኪል በቂ ነው፣ ግን ለአብዛኛዎቹ ጉዳዮች አገልጋይም ያስፈልግዎታል።

ወኪል

ቢያንስ ከስሪት XNUMX ጀምሮ፣ የአሻንጉሊት ወኪል ጥቅሎች ከ áŠŚáŠáˆ´áˆ‹á‹Š Puppetlabs ማከማቻ ሁሉንም ጥገኞች (ሩቢ እና ተጓዳኝ እንቁዎች) ይዘዋል፣ ስለዚህ ምንም የመጫኛ ችግሮች የሉም (የምናገረው ሾለ ዴቢያን-ተኮር ስርጭቶች - RPM ላይ የተመሰረቱ ስርጭቶችን አንጠቀምም)።

በጣም ቀላል በሆነ ሁኔታ የአሻንጉሊት ውቅርን ለመጠቀም ወኪሉን አገልጋይ በሌለው ሁነታ ማስጀመር በቂ ነው-የአሻንጉሊት ኮድ ወደ መስቀለኛ መንገድ ከተገለበጠ ፣ አስነሳ puppet apply <путь к манифесту>:

atikhonov@atikhonov ~/puppet-test $ cat helloworld.pp 
node default {
    notify { 'Hello world!': }
}
atikhonov@atikhonov ~/puppet-test $ puppet apply helloworld.pp 
Notice: Compiled catalog for atikhonov.localdomain in environment production in 0.01 seconds
Notice: Hello world!
Notice: /Stage[main]/Main/Node[default]/Notify[Hello world!]/message: defined 'message' as 'Hello world!'
Notice: Applied catalog in 0.01 seconds

በእርግጥ አገልጋዩን ማዋቀር እና ወኪሎችን በዲሞን ሞድ ላይ በመስቀለኛ መንገድ ማሄድ የተሻለ ነው - ከዚያ በየግማሽ ሰዓቱ አንድ ጊዜ ከአገልጋዩ የወረደውን ውቅር ይተገበራሉ።

የግፋውን የስራ ሞዴል መኮረጅ ይችላሉ - ወደሚፈልጉበት መስቀለኛ መንገድ ይሂዱ እና ይጀምሩ sudo puppet agent -t. ቁልፍ -t (--test) በተናጥል ሊነቁ የሚችሉ በርካታ አማራጮችን ያካትታል። እነዚህ አማራጮች የሚከተሉትን ያካትታሉ:

  • በዲሞን ሁነታ አይሂዱ (በነባሪነት ወኪሉ በዴሞን ሁነታ ይጀምራል);
  • ካታሎጉን ከተጠቀሙ በኋላ መዝጋት (በነባሪነት ወኪሉ መስራቱን ይቀጥላል እና በየግማሽ ሰዓቱ አንድ ጊዜ አወቃቀሩን ይተገበራል);
  • ዝርዝር የሥራ መዝገብ ይጻፉ;
  • በፋይሎች ውስጥ ለውጦችን አሳይ.

ወኪሉ ምንም ለውጥ ሳይደረግበት የአሠራር ሁኔታ አለው - ትክክለኛውን ውቅር እንደጻፉ እርግጠኛ ካልሆኑ እና በሚሠራበት ጊዜ ወኪሉ በትክክል ምን እንደሚለወጥ ማረጋገጥ ሲፈልጉ ሊጠቀሙበት ይችላሉ። ይህ ሁነታ በመለኪያው ነቅቷል። --noop በትእዛዝ መስመር ላይ: sudo puppet agent -t --noop.

በተጨማሪም ፣ የሥራውን ማረም መዝገብ ማንቃት ይችላሉ - በእሱ ውስጥ ፣ አሻንጉሊት ስለሚያደርጋቸው ድርጊቶች ሁሉ ይጽፋል-በአሁኑ ጊዜ ስለሚያስኬደው ሀብት ፣ ስለ የዚህ ምንጭ መለኪያዎች ፣ ስለ ምን ፕሮግራሞች እንደሚጀምር ይጽፋል። በእርግጥ ይህ መለኪያ ነው --debug.

አገልጋይ

በዚህ ጽሑፍ ውስጥ የፓፕ ሰርቨርን ሙሉ ማዋቀር እና ኮድ ማሰማራቱን አላስብም ፣ ከሳጥኑ ውስጥ ሙሉ በሙሉ የሚሰራ የአገልጋዩ ስሪት አለ እና ከትንሽ ቁጥር ጋር ለመስራት ተጨማሪ ውቅር የማይፈልግ እላለሁ ። አንጓዎች (እስከ መቶ ድረስ ይበሉ)። ብዙ ቁጥር ያላቸው አንጓዎች ማስተካከልን ይፈልጋሉ - በነባሪነት ፣ puppetserver ከአራት የማይበልጡ ሰራተኞችን ይጀምራል ፣ ለበለጠ አፈፃፀም ቁጥራቸውን መጨመር ያስፈልግዎታል እና የማህደረ ትውስታ ገደቦችን መጨመር አይርሱ ፣ አለበለዚያ አገልጋዩ ብዙ ጊዜ ቆሻሻ ይሰበስባል።

ኮድ ማሰማራት - በፍጥነት እና በቀላሉ ከፈለጉ ፣ ከዚያ ይመልከቱ (r10k ይመልከቱ)[https://github.com/puppetlabs/r10k], ለአነስተኛ ጭነቶች በጣም በቂ መሆን አለበት.

ተጨማሪ 2፡ ኮድ አሰጣጥ መመሪያዎች

  1. ሁሉንም አመክንዮዎች በክፍሎች እና ትርጓሜዎች ውስጥ ያስቀምጡ።
  2. ክፍሎችን እና ትርጓሜዎችን በሞጁሎች ውስጥ ያቆዩ እንጂ አንጓዎችን በሚገልጹ መግለጫዎች ውስጥ አይደለም።
  3. እውነታውን ተጠቀም።
  4. በአስተናጋጅ ስም ላይ ተመስርተው ከሆነ አይስሩ።
  5. ለክፍሎች እና ለትርጉሞች መለኪያዎችን ለመጨመር ነፃነት ይሰማህ - ይህ በክፍል / ገላጭ አካል ውስጥ ከተደበቀ ስውር አመክንዮ የተሻለ ነው።

ይህንን ለማድረግ ለምን እንደምመክረው በሚቀጥለው ርዕስ ውስጥ እገልጻለሁ.

መደምደሚያ

በመግቢያው እንጨርስ። በሚቀጥለው ርዕስ ስለ Hiera፣ ENC እና PuppetDB እነግራችኋለሁ።

በዳሰሳ ጥናቱ ውስጥ የተመዘገቡ ተጠቃሚዎች ብቻ መሳተፍ ይችላሉ። ስግን እንእባክህን።

በእውነቱ ፣ ብዙ ተጨማሪ ነገሮች አሉ - በሚከተሉት ርዕሶች ላይ መጣጥፎችን መጻፍ እችላለሁ ፣ ለማንበብ በሚፈልጉት ላይ ድምጽ ይስጡ ።

  • 59,1%የላቀ የአሻንጉሊት ግንባታዎች - አንዳንድ የሚቀጥለው ደረጃ ሽት፡ loops፣ የካርታ ሾል እና ሌሎች የላምዳ አገላለጾች፣ ሃብት ሰብሳቢዎች፣ ወደ ውጭ የሚላኩ ሀብቶች እና የኢንተር አስተናጋጅ ግንኙነት በአሻንጉሊት፣ መለያዎች፣ አቅራቢዎች፣ የአብስትራክት የመረጃ አይነቶች።13
  • 31,8%"እኔ የእናቴ አስተዳዳሪ ነኝ" ወይም በአቪቶ ውስጥ እንዴት ከተለያዩ ስሪቶች ከተለያዩ የፖፕ ሰርቨሮች ጋር ጓደኛ እንደፈጠርን እና በመርህ ደረጃ የፖፕ አገልጋይን ስለማስተዳደር ክፍል።7
  • 81,8%የአሻንጉሊት ኮድ እንዴት እንደምንጽፍ፡መሳሪያዎች፣ ሰነዶች፣ ፈተናዎች፣ CI/CD.18

22 ተጠቃሚዎች ድምጽ ሰጥተዋል። 9 ተጠቃሚዎች ድምፀ ተአቅቦ አድርገዋል።

ምንጭ: hab.com