{"id":34989,"date":"2024-09-19T16:46:40","date_gmt":"2024-09-19T09:46:40","guid":{"rendered":"http:\/\/jupitek.maudemo.vip\/index.php\/2024\/09\/19\/test-salt-states-locally-with-kitchensalt\/"},"modified":"2024-09-19T16:46:40","modified_gmt":"2024-09-19T09:46:40","slug":"test-salt-states-locally-with-kitchensalt","status":"publish","type":"post","link":"https:\/\/jupitek.maudemo.vip\/index.php\/2024\/09\/19\/test-salt-states-locally-with-kitchensalt\/","title":{"rendered":"Ki\u1ec3m th\u1eed Salt States c\u1ee5c b\u1ed9 v\u1edbi KitchenSalt"},"content":{"rendered":"<p>KitchenSalt cho ph\u00e9p b\u1ea1n s\u1eed d\u1ee5ng Test Kitchen \u0111\u1ec3 ki\u1ec3m tra c\u1ea5u h\u00ecnh Salt c\u1ee7a b\u1ea1n c\u1ee5c b\u1ed9 m\u00e0 kh\u00f4ng c\u1ea7n Salt master ho\u1eb7c minion. Trong h\u01b0\u1edbng d\u1eabn n\u00e0y, b\u1ea1n s\u1ebd c\u00e0i \u0111\u1eb7t KitchenSalt v\u00e0 s\u1eed d\u1ee5ng Docker \u0111\u1ec3 ki\u1ec3m tra tr\u1ea1ng th\u00e1i Salt. H\u01b0\u1edbng d\u1eabn n\u00e0y \u0111\u01b0\u1ee3c t\u1ea1o b\u1eb1ng h\u1ec7 th\u1ed1ng ch\u1ea1y Ubuntu 18.04.<\/p>\n<h2 id=\"before-you-begin\">Tr\u01b0\u1edbc khi b\u1ea1n b\u1eaft \u0111\u1ea7u<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#before-you-begin\"><\/a><\/h2>\n<ul>\n<li>B\u1ea1n s\u1ebd c\u1ea7n quy\u1ec1n truy c\u1eadp root v\u00e0o m\u00e1y t\u00ednh c\u1ee7a m\u00ecnh ho\u1eb7c t\u00e0i kho\u1ea3n ng\u01b0\u1eddi d\u00f9ng c\u00f3&nbsp;<code>sudo<\/code>\u0111\u1eb7c quy\u1ec1n. \u0110\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 \u0111\u1eb7c quy\u1ec1n, h\u00e3y xem h\u01b0\u1edbng d\u1eabn&nbsp;<a href=\"https:\/\/www.linode.com\/docs\/guides\/linux-users-and-groups\/\">Ng\u01b0\u1eddi d\u00f9ng v\u00e0 Nh\u00f3m<\/a>&nbsp;c\u1ee7a ch\u00fang t\u00f4i .<\/li>\n<li><a href=\"https:\/\/www.linode.com\/docs\/guides\/how-to-install-git-on-linux-mac-and-windows\/\">C\u00e0i \u0111\u1eb7t Git<\/a>&nbsp;tr\u00ean m\u00e1y t\u00ednh c\u1ee5c b\u1ed9 c\u1ee7a b\u1ea1n n\u1ebfu n\u00f3 ch\u01b0a \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t.<\/li>\n<li>C\u1eadp nh\u1eadt c\u00e1c g\u00f3i h\u1ec7 th\u1ed1ng c\u1ee7a b\u1ea1n.<\/li>\n<\/ul>\n<h2 id=\"install-rbenv-and-ruby\">C\u00e0i \u0111\u1eb7t rbenv v\u00e0 Ruby<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#install-rbenv-and-ruby\"><\/a><\/h2>\n<p>Kitchen ch\u1ea1y tr\u00ean Ruby. C\u00e1c l\u1ec7nh sau s\u1ebd c\u00e0i \u0111\u1eb7t b\u1ed9 \u0111i\u1ec1u khi\u1ec3n phi\u00ean b\u1ea3n Ruby rbenv, \u0111\u1eb7t rbenv trong PATH c\u1ee7a b\u1ea1n v\u00e0 c\u00e0i \u0111\u1eb7t Ruby th\u00f4ng qua rbenv.<\/p>\n<p>1.C\u00e0i \u0111\u1eb7t c\u00e1c g\u00f3i c\u1ea7n thi\u1ebft cho rbenv:<\/p>\n<pre class=\"wp-block-code\"><code>sudo apt install libssl-dev libreadline-dev zlib1g-dev bzip2 gcc make git ruby-dev\n<\/code><\/pre>\n<p>2.Sao ch\u00e9p kho l\u01b0u tr\u1eef git rbenv v\u00e0 thi\u1ebft l\u1eadp PATH c\u1ee7a b\u1ea1n:<\/p>\n<pre class=\"wp-block-code\"><code>sudo git clone git:\/\/github.com\/rbenv\/rbenv.git \/usr\/local\/rbenv\nsudo mkdir \/usr\/local\/rbenv\/plugins\nsudo git clone git:\/\/github.com\/rbenv\/ruby-build.git \/usr\/local\/rbenv\/plugins\/ruby-build\nsudo tee \/etc\/profile.d\/rbenv.sh &lt;&lt;&lt; 'export PATH=\"\/usr\/local\/rbenv\/plugins\/ruby-build\/bin:\/usr\/local\/rbenv\/bin:$PATH\"'\nsudo tee -a \/etc\/profile.d\/rbenv.sh &lt;&lt;&lt; 'source &lt;(rbenv init -)'<\/code><\/pre>\n<p>3.T\u1ea3i l\u1ea1i c\u1ea5u h\u00ecnh h\u1ec7 th\u1ed1ng c\u1ee7a b\u1ea1n \u0111\u1ec3 c\u00e1c l\u1ec7nh rbenv \u0111\u01b0\u1ee3c th\u00eam v\u00e0o&nbsp;<code>PATH<\/code>:<\/p>\n<pre class=\"wp-block-code\"><code>source \/etc\/profile\n<\/code><\/pre>\n<p>B\u1ea1n c\u0169ng c\u00f3 th\u1ec3 kh\u1edfi \u0111\u1ed9ng l\u1ea1i phi\u00ean shell \u0111\u1ec3&nbsp;<code>PATH<\/code>nh\u1eefng thay \u0111\u1ed5i c\u00f3 hi\u1ec7u l\u1ef1c.<\/p>\n<p>4.C\u00e0i \u0111\u1eb7t Ruby:<\/p>\n<h2 id=\"install-docker\">C\u00e0i \u0111\u1eb7t Docker<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#install-docker\"><\/a><\/h2>\n<p>\u0110\u1ec3 c\u00e0i \u0111\u1eb7t Docker CE (Phi\u00ean b\u1ea3n c\u1ed9ng \u0111\u1ed3ng), h\u00e3y l\u00e0m theo h\u01b0\u1edbng d\u1eabn trong m\u1ed9t trong c\u00e1c h\u01b0\u1edbng d\u1eabn d\u01b0\u1edbi \u0111\u00e2y:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.linode.com\/docs\/guides\/installing-and-using-docker-on-ubuntu-and-debian\/\">C\u00e0i \u0111\u1eb7t v\u00e0 s\u1eed d\u1ee5ng Docker tr\u00ean Ubuntu v\u00e0 Debian<\/a><\/li>\n<li><a href=\"https:\/\/www.linode.com\/docs\/guides\/installing-and-using-docker-on-centos-and-fedora\/\">C\u00e0i \u0111\u1eb7t v\u00e0 s\u1eed d\u1ee5ng Docker tr\u00ean CentOS v\u00e0 Fedora<\/a><\/li>\n<\/ul>\n<p>\u0110\u1ec3 xem h\u01b0\u1edbng d\u1eabn c\u00e0i \u0111\u1eb7t cho c\u00e1c b\u1ea3n ph\u00e2n ph\u1ed1i Linux ho\u1eb7c h\u1ec7 \u0111i\u1ec1u h\u00e0nh kh\u00e1c nh\u01b0 Mac ho\u1eb7c Windows, h\u00e3y tham kh\u1ea3o t\u00e0i li\u1ec7u ch\u00ednh th\u1ee9c c\u1ee7a Docker t\u1ea1i \u0111\u00e2y:&nbsp;<a href=\"https:\/\/docs.docker.com\/engine\/install\/\" target=\"_blank\" rel=\"noreferrer noopener\">C\u00e0i \u0111\u1eb7t Docker Engine<\/a><\/p>\n<h2 id=\"install-kitchensalt\">C\u00e0i \u0111\u1eb7t KitchenSalt<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#install-kitchensalt\"><\/a><\/h2>\n<p>1.C\u00e0i \u0111\u1eb7t bundler gem:<\/p>\n<pre class=\"wp-block-code\"><code>sudo gem install bundler<\/code><\/pre>\n<p>2.T\u1ea1o Gemfile trong th\u01b0 m\u1ee5c l\u00e0m vi\u1ec7c c\u1ee7a b\u1ea1n v\u00e0 th\u00eam c\u00e1c gem&nbsp;<code>kitchen-salt<\/code>,&nbsp;<code>kitchen-docker<\/code>, v\u00e0&nbsp;<code>kitchen-sync<\/code>:<\/p>\n<pre class=\"wp-block-code\"><code>#Gemfile\nsource 'https:\/\/rubygems.org'\n\ngem 'kitchen-salt'\ngem 'kitchen-docker'\ngem 'kitchen-sync'<\/code><\/pre>\n<p><code>kitchen-sync<\/code>\u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 sao ch\u00e9p t\u1ec7p v\u00e0o v\u00f9ng ch\u1ee9a Docker nhanh h\u01a1n.<\/p>\n<p>3.C\u00e0i \u0111\u1eb7t gem b\u1eb1ng bundler:<\/p>\n<pre class=\"wp-block-code\"><code>sudo bundle install\n<\/code><\/pre>\n<h2 id=\"create-a-sample-sls-file\">T\u1ea1o m\u1ed9t t\u1ec7p .sls m\u1eabu<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#create-a-sample-sls-file\"><\/a><\/h2>\n<p>\u0110\u1ec3 th\u1eed nghi\u1ec7m, h\u00e3y t\u1ea1o m\u1ed9t t\u1ec7p tr\u1ea1ng th\u00e1i Salt c\u00e0i \u0111\u1eb7t NGINX v\u00e0 \u0111\u1ea3m b\u1ea3o r\u1eb1ng n\u00f3 \u0111ang ch\u1ea1y. Trong tr\u00ecnh so\u1ea1n th\u1ea3o v\u0103n b\u1ea3n, h\u00e3y t\u1ea1o m\u1ed9t&nbsp;<code>nginx.sls<\/code>t\u1ec7p trong th\u01b0 m\u1ee5c l\u00e0m vi\u1ec7c c\u1ee7a b\u1ea1n v\u00e0 th\u00eam c\u00e1c d\u00f2ng sau:<\/p>\n<pre class=\"wp-block-code\"><code>nginx:\n  pkg:\n    - installed\n  service.running:\n    - enable: True\n    - reload: True\n    - watch:\n      - pkg: nginx<\/code><\/pre>\n<h2 id=\"configure-kitchenyml\">C\u1ea5u h\u00ecnh kitchen.yml<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#configure-kitchenyml\"><\/a><\/h2>\n<p>1.B\u00e2y gi\u1edd, h\u00e3y vi\u1ebft t\u1ec7p c\u1ea5u h\u00ecnh Kitchen, b\u1eaft \u0111\u1ea7u b\u1eb1ng ph\u1ea7n&nbsp;<strong>provisioner<\/strong>&nbsp;. Sao ch\u00e9p c\u00e1c d\u00f2ng sau v\u00e0o m\u1ed9t&nbsp;<code>kitchen.yml<\/code>t\u1ec7p trong th\u01b0 m\u1ee5c l\u00e0m vi\u1ec7c c\u1ee7a b\u1ea1n.<\/p>\n<pre class=\"wp-block-code\"><code>provisioner:\n  name: salt_solo\n  salt_install: bootstrap\n  is_file_root: true\n  require_chef: false\n  state_top:\n    base:\n      \"*\":\n        - nginx\n\n...<\/code><\/pre>\n<p>Ph\u1ea7n n\u00e0y \u0111\u1ecbnh ngh\u0129a&nbsp;<code>salt_solo<\/code>l\u00e0 provisioner, cho ph\u00e9p Kitchen s\u1eed d\u1ee5ng Salt m\u00e0 kh\u00f4ng c\u1ea7n Salt master. Trong ph\u1ea7n n\u00e0y, Salt \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t th\u00f4ng qua t\u1eadp l\u1ec7nh bootstrap b\u1eb1ng c\u00e1ch thi\u1ebft l\u1eadp&nbsp;<code>salt_install: bootstrap<\/code>, g\u1ed1c t\u1ec7p Salt \u0111\u01b0\u1ee3c \u00e1nh x\u1ea1 t\u1edbi th\u01b0 m\u1ee5c&nbsp;<code>.kitchen.yml<\/code>\u0111\u01b0\u1ee3c \u0111\u1ecbnh v\u1ecb b\u1eb1ng c\u00e1ch thi\u1ebft l\u1eadp&nbsp;<code>is_file_root: true<\/code>, v\u00e0 Chef b\u1ecb v\u00f4 hi\u1ec7u h\u00f3a b\u1eb1ng c\u00e1ch thi\u1ebft l\u1eadp&nbsp;<code>require_chef: false<\/code>. Thay v\u00ec cung c\u1ea5p t\u1ec7p top cho c\u00e1c tr\u1ea1ng th\u00e1i Salt, t\u1ec7p top \u0111\u01b0\u1ee3c khai b\u00e1o n\u1ed9i tuy\u1ebfn. Ph\u1ea7n n\u00e0y c\u0169ng l\u00e0 n\u01a1i c\u00e1c t\u1ec7p tr\u1ee5 c\u1ed9t Salt \u0111\u01b0\u1ee3c th\u00eam v\u00e0o. \u0110\u1ec3 tham kh\u1ea3o, ch\u00fang \u0111\u01b0\u1ee3c th\u00eam v\u00e0o b\u00ean d\u01b0\u1edbi kh\u1ed1i&nbsp;<strong>provisioner<\/strong>&nbsp;:<\/p>\n<pre class=\"wp-block-code\"><code>provisioner:\n...\n  pillars:\n    top.sls:\n      base:\n        \"*\":\n          - nginx_pillar\n  pillars_from_files:\n    nginx_pillar.sls: nginx.pillar<\/code><\/pre>\n<p>2.Ti\u1ebfp theo, c\u1ea5u h\u00ecnh ph\u1ea7n&nbsp;<strong>tr\u00ecnh \u0111i\u1ec1u khi\u1ec3n<\/strong>&nbsp;:<\/p>\n<pre class=\"wp-block-code\"><code>...\n\ndriver:\n  name: docker\n  user_sudo: false\n  privileged: true\n  forward:\n    - 80\n\n...<\/code><\/pre>\n<p>Ph\u1ea7n n\u00e0y khai b\u00e1o Docker l\u00e0 tr\u00ecnh \u0111i\u1ec1u khi\u1ec3n, m\u1eb7c d\u00f9 b\u1ea1n c\u0169ng c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng Vagrant. Kitchen kh\u00f4ng c\u1ea7n s\u1eed d\u1ee5ng&nbsp;<code>sudo<\/code>\u0111\u1ec3 x\u00e2y d\u1ef1ng c\u00e1c container Docker, do \u0111\u00f3&nbsp;<code>user_sudo<\/code>\u0111\u01b0\u1ee3c \u0111\u1eb7t th\u00e0nh&nbsp;<code>false<\/code>.&nbsp;<code>privileged<\/code>\u0111\u01b0\u1ee3c \u0111\u1eb7t th\u00e0nh&nbsp;<code>true<\/code>\u0111\u1ec3 \u0111\u1ea3m b\u1ea3o r\u1eb1ng c\u00e1c container ch\u1ea1y systemd d\u01b0\u1edbi d\u1ea1ng l\u1ec7nh exec. Container Docker s\u1ebd&nbsp;<code>forward<\/code>l\u01b0u th\u00f4ng \u0111\u1ebfn m\u00e1y ch\u1ee7 tr\u00ean c\u1ed5ng&nbsp;<code>80<\/code>.<\/p>\n<p>3.C\u1ea5u h\u00ecnh ph\u1ea7n&nbsp;<strong>n\u1ec1n t\u1ea3ng<\/strong>&nbsp;:<\/p>\n<pre class=\"wp-block-code\"><code>...\n\nplatforms:\n  - name: ubuntu\n    driver_config:\n      run_command: \/lib\/systemd\/systemd\n\n...<\/code><\/pre>\n<p>Ph\u1ea7n n\u00e0y \u0111\u1ecbnh ngh\u0129a n\u1ec1n t\u1ea3ng n\u00e0o Docker s\u1ebd ch\u1ea1y. Theo m\u1eb7c \u0111\u1ecbnh, Docker s\u1ebd ch\u1ea1y phi\u00ean b\u1ea3n m\u1edbi nh\u1ea5t c\u1ee7a n\u1ec1n t\u1ea3ng \u0111\u00f3. V\u00ec c\u00e1c n\u1ec1n t\u1ea3ng kh\u00e1c nhau \u0111\u1eb7t systemd \u1edf c\u00e1c v\u1ecb tr\u00ed kh\u00e1c nhau, n\u00ean&nbsp;<code>driver_config<\/code>ph\u1ea7n n\u00e0y \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 tr\u1ecf \u0111\u1ebfn \u0111\u01b0\u1eddng d\u1eabn c\u00e0i \u0111\u1eb7t systemd c\u1ee7a n\u1ec1n t\u1ea3ng \u0111\u00f3. C\u00f3 th\u1ec3 \u0111\u1ecbnh ngh\u0129a nhi\u1ec1u n\u1ec1n t\u1ea3ng.<\/p>\n<p>4.C\u1ea5u h\u00ecnh ph\u1ea7n b\u1ed9&nbsp;<strong>s\u1ea3n ph\u1ea9m<\/strong>&nbsp;:<\/p>\n<pre class=\"wp-block-code\"><code>...\n\nsuites:\n  - name: oxygen\n    provisioner:\n      salt_bootstrap_options: -X -p git stable 2018.3\n\n...<\/code><\/pre>\n<p><code>suites<\/code>\u0111\u1ecbnh ngh\u0129a b\u1ed9 ph\u1ea7n m\u1ec1m n\u00e0o m\u00e0 Kitchen s\u1ebd ki\u1ec3m tra. Trong ng\u1eef c\u1ea3nh n\u00e0y, Kitchen s\u1ebd ki\u1ec3m tra b\u1ea3n ph\u00e1t h\u00e0nh Oxygen c\u1ee7a Salt. C\u00f3 th\u1ec3 \u0111\u1ecbnh ngh\u0129a nhi\u1ec1u h\u01a1n m\u1ed9t b\u1ed9 ph\u1ea7n m\u1ec1m.<\/p>\n<p>5.Cu\u1ed1i c\u00f9ng, ph\u1ea7n&nbsp;<strong>v\u1eadn chuy\u1ec3n<\/strong>&nbsp;cho ph\u00e9p ch\u00fang ta ch\u1ec9 \u0111\u1ecbnh c\u00e1ch s\u1eed d\u1ee5ng&nbsp;<code>kitchen-sync<\/code>\u0111\u1ec3 truy\u1ec1n t\u1ec7p:<\/p>\n<pre class=\"wp-block-code\"><code>...\n\ntransport:\n  name: sftp<\/code><\/pre>\n<p>6.B\u00e2y gi\u1edd b\u1ea1n c\u00f3 th\u1ec3 ki\u1ec3m tra c\u1ea5u h\u00ecnh Salt c\u1ee7a m\u00ecnh b\u1eb1ng Kitchen. Nh\u1eadp l\u1ec7nh sau \u0111\u1ec3 ch\u1ea1y th\u1eed nghi\u1ec7m:<\/p>\n<pre class=\"wp-block-code\"><code>kitchen test<\/code><\/pre>\n<p>L\u1ec7nh n\u00e0y s\u1ebd t\u1ea1o, h\u1ed9i t\u1ee5 v\u00e0 sau \u0111\u00f3 h\u1ee7y phi\u00ean b\u1ea3n th\u1eed nghi\u1ec7m. N\u1ebfu ho\u00e0n t\u1ea5t th\u00e0nh c\u00f4ng, \u0111\u1ea7u ra cu\u1ed1i c\u00f9ng c\u1ee7a thi\u1ebft b\u1ecb \u0111\u1ea7u cu\u1ed1i s\u1ebd l\u00e0:<\/p>\n<pre class=\"wp-block-code\"><code>-----&gt; Kitchen is finished. (13m32.13s)\n<\/code><\/pre>\n<p>\u0110\u1ec3 c\u00f3 c\u00e1ch ti\u1ebfp c\u1eadn chi ti\u1ebft h\u01a1n khi ch\u1ea1y th\u1eed nghi\u1ec7m, b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng t\u1eebng l\u1ec7nh theo tr\u00ecnh t\u1ef1:<\/p>\n<pre class=\"wp-block-code\"><code>kitchen list\nkitchen create\nkitchen converge\nkitchen destroy<\/code><\/pre>\n<h2 id=\"using-a-verifier-and-next-steps\">S\u1eed d\u1ee5ng Tr\u00ecnh x\u00e1c minh v\u00e0 c\u00e1c b\u01b0\u1edbc ti\u1ebfp theo<a href=\"https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/#using-a-verifier-and-next-steps\"><\/a><\/h2>\n<p>M\u1eb7c d\u00f9 n\u1eb1m ngo\u00e0i ph\u1ea1m vi c\u1ee7a b\u00e0i vi\u1ebft n\u00e0y, Kitchen cho ph\u00e9p ki\u1ec3m tra m\u1ea1nh m\u1ebd h\u01a1n l\u00e0 ch\u1ec9 ki\u1ec3m tra c\u1ea5u h\u00ecnh Salt. B\u1ea1n c\u00f3 th\u1ec3 vi\u1ebft c\u00e1c b\u00e0i ki\u1ec3m tra trong bash b\u1eb1ng Bats, trong Ruby b\u1eb1ng Minitest, Rspec, Serverspec v\u00e0 Inspec ho\u1eb7c n\u1ebfu b\u1ea1n quen thu\u1ed9c h\u01a1n v\u1edbi Python, b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng pytest.<\/p>\n<p>V\u00ed d\u1ee5, b\u1ea1n c\u00f3 th\u1ec3 th\u00eam \u0111o\u1ea1n m\u00e3 sau v\u00e0o&nbsp;<code>kitchen.yaml<\/code>\u0111\u1ec3 x\u00e1c minh c\u00e1c b\u00e0i ki\u1ec3m tra c\u1ee7a m\u00ecnh b\u1eb1ng c\u00e1ch s\u1eed d\u1ee5ng vi\u00ean ng\u1ecdc Inspec:<\/p>\n<pre class=\"wp-block-code\"><code>...\n\nverifier:\n  name: inspec<\/code><\/pre>\n<p>\u0110\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 b\u00e0i ki\u1ec3m tra vi\u1ebft, h\u00e3y truy c\u1eadp c\u00e1c li\u00ean k\u1ebft trong ph\u1ea7n Th\u00f4ng tin th\u00eam b\u00ean d\u01b0\u1edbi.<\/p>\n<h2 id=\"more-information\">Th\u00f4ng tin th\u00eam<\/h2>\n<p>B\u1ea1n c\u00f3 th\u1ec3 mu\u1ed1n tham kh\u1ea3o c\u00e1c ngu\u1ed3n sau \u0111\u1ec3 bi\u1ebft th\u00eam th\u00f4ng tin v\u1ec1 ch\u1ee7 \u0111\u1ec1 n\u00e0y. M\u1eb7c d\u00f9 ch\u00fang t\u00f4i cung c\u1ea5p v\u1edbi hy v\u1ecdng r\u1eb1ng ch\u00fang s\u1ebd h\u1eefu \u00edch, nh\u01b0ng xin l\u01b0u \u00fd r\u1eb1ng ch\u00fang t\u00f4i kh\u00f4ng th\u1ec3 \u0111\u1ea3m b\u1ea3o t\u00ednh ch\u00ednh x\u00e1c ho\u1eb7c t\u00ednh k\u1ecbp th\u1eddi c\u1ee7a c\u00e1c t\u00e0i li\u1ec7u \u0111\u01b0\u1ee3c l\u01b0u tr\u1eef b\u00ean ngo\u00e0i.<\/p>\n<ul>\n<li><a href=\"https:\/\/kitchen.saltproject.io\/docs\/file\/README.rdoc\" target=\"_blank\" rel=\"noreferrer noopener\">T\u00e0i li\u1ec7u KitchenSalt<\/a><\/li>\n<li><a href=\"https:\/\/docs.chef.io\/kitchen.html\" target=\"_blank\" rel=\"noreferrer noopener\">T\u00e0i li\u1ec7u nh\u00e0 b\u1ebfp<\/a><\/li>\n<li><a href=\"https:\/\/docs.saltproject.io\/en\/latest\/topics\/development\/conventions\/formulas.html\" target=\"_blank\" rel=\"noreferrer noopener\">C\u00f4ng th\u1ee9c mu\u1ed1i<\/a><\/li>\n<li><a href=\"https:\/\/kitchen.ci\/docs\/getting-started\/writing-test\/\" target=\"_blank\" rel=\"noreferrer noopener\">Vi\u1ebft m\u1ed9t b\u00e0i ki\u1ec3m tra<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/gtmanfred\/wordpress-formula\/tree\/master\/tests\/integration\" target=\"_blank\" rel=\"noreferrer noopener\">M\u1eabu x\u00e9t nghi\u1ec7m Pytest<\/a><\/li>\n<\/ul>\n<p>Ngu\u1ed3n: https:\/\/www.linode.com\/docs\/guides\/test-salt-locally-with-kitchen-salt\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>KitchenSalt cho ph\u00e9p b\u1ea1n s\u1eed d\u1ee5ng Test Kitchen \u0111\u1ec3 ki\u1ec3m tra c\u1ea5u h\u00ecnh Salt c\u1ee7a b\u1ea1n c\u1ee5c b\u1ed9 m\u00e0 kh\u00f4ng c\u1ea7n Salt master ho\u1eb7c minion. Trong h\u01b0\u1edbng d\u1eabn n\u00e0y, b\u1ea1n s\u1ebd c\u00e0i \u0111\u1eb7t KitchenSalt v\u00e0 s\u1eed d\u1ee5ng Docker \u0111\u1ec3 ki\u1ec3m tra tr\u1ea1ng th\u00e1i Salt. H\u01b0\u1edbng d\u1eabn n\u00e0y \u0111\u01b0\u1ee3c t\u1ea1o b\u1eb1ng h\u1ec7 th\u1ed1ng ch\u1ea1y Ubuntu 18.04.<\/p>\n","protected":false},"author":1,"featured_media":36044,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[124],"tags":[],"class_list":["post-34989","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-salt"],"_links":{"self":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/posts\/34989","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/comments?post=34989"}],"version-history":[{"count":0,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/posts\/34989\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/media\/36044"}],"wp:attachment":[{"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/media?parent=34989"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/categories?post=34989"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jupitek.maudemo.vip\/index.php\/wp-json\/wp\/v2\/tags?post=34989"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}