์์ฑ ๋น์ v2 ๋ถ๊ธฐ์๋ ์ด์ ์ '์ญํ '(์ผ๋ช
"์์
์ ์ํํ๋ ํธ์คํธ ๋ฌถ์")์ผ๋ก ์๋ ค์ง ๋จ์ ์ญํ ์ ํ ์ ์๋ Group
ํด๋์ค๊ฐ ์์ต๋๋ค.
๊ทธ๋ฌ๋ Group
๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํ๊ฑฐ๋ ๋ ์ด๋ธ์ ์ง์ ํ๋ ๊ตฌ์ฒด์ ์ธ ๋ฐฉ๋ฒ์ ์์ง ์์ต๋๋ค. ๊ณ ์ ํ ๊ณ ์ ํ ์์ฑ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ค๋ ๊ณ ๊ธ ์ฌ์ฉ์์ ์์ํ API ์ฌ์ฉ ์ฌ๋ก์๋ ์ถฉ๋ถํ "์๋ฃ"๋์์ง๋ง, CLI ์งํฅ ์ฌ์ฉ์ ๋๋ ํ๋ ์์ํฌ ๊ตฌ์ถ์ ์ํ๋ ์ค๊ธ ์ฌ์ฉ์์๊ฒ๋ ์๋ฌด ๊ฒ๋ ๋ถ์กฑํฉ๋๋ค.
๋ฌ๋ฆฌ ๋งํ๋ฉด, API๋ก ์์ ํ ๋กค๋งํ์ง ์๋ ํ, CLI ๋๋ ์์ ํธ์ถ ๋นํธ์์ ์ฐพ์ ๋ฐฉ๋ฒ์ด ์๋ ๊ฒฝ์ฐ ์ด๋๊ฐ์ Group ๊ฐ์ฒด๋ฅผ ๋ฐฐ์นํ๋ ๊ฒ์ ์ธ๋ชจ๊ฐ ์์ต๋๋ค!
v1์์ ์ญํ ์ ๋จ์ํ ๋ฌธ์์ด ๋ ์ด๋ธ์ v2์ ๊ทธ๋ฃน์ ๋งคํํ๋ ๋จ์ผ ํ๋ซ ๋ค์์คํ์ด์ค์์ผ๋ฉฐ ๋ฐํ์ ์ CLI์์ ์ ํ( fab --roles=web,db
) ๋ฐ/๋๋ ์์
์ ๊ธฐ๋ณธ ๋์์ผ๋ก ๋ฑ๋ก( @task('db') \n def migrate():
), ํธ์คํธ์ ๋งค์ฐ ์ ์ฌํฉ๋๋ค.
์ฌ์ฉ์๋ env.roledefs
, ๊ฐ๋จํ ์ฌ์ ์ ์ ์ํ์ต๋๋ค. ๋ชจ๋ ์ค๊ฐ์์ ๊ณ ๊ธ ๊ธฐ๋ฅ์ ์ผ๋ฐ์ ์ผ๋ก ๋ฐํ์(์ฌ์ ์์
๋๋ ์๋ธ๋ฃจํด์ ํตํด), ๋๋ก๋ ๋ชจ๋ ๋ก๋ ์ ์์ ์ ์ค์ฌ์ผ๋ก ์ด๋ฃจ์ด์ก์ต๋๋ค.
Group
s ๋ฐ/๋๋ Connection
s์ ์ผ๋ถ ๋ฐ๋ณต ๊ฐ๋ฅ์ ๊ฐ์ ธ์ต๋๋ค.Lexicon
๋์ ์ dict
.db
, web
, lb
๋ผ๋ ์ด๋ฆ์ ์ง์ ๋งคํ์ด ์์ง๋ง prod
๋ผ๋ ๋ ๋ฒ์งธ ๊ณ์ธต ์ด๋ฆ์ด ์์ต๋๋ค Lexicon
์ถ๊ฐํ๋์ง ์์ด๋ฒ๋ ธ์ต๋๋ค. ์ด๋ฏธ ๊ทธ๋ ๊ฒ ํ๋ ๋ค๋ฅธ ์ง๋ ํ์ ํด๋์ค๊ฐ ์์ ์ ์์ต๋๋ค.cxn
๊ฐ ๊ณ ์ ํ ๊ฐ์ฒด์ธ ๊ฒฝ์ฐ์๋ if cxn in group
๊ฐ ์๋ํฉ๋๋ค. group
๋ด๋ถ์ ๋๋ฑํ ๋ฉค๋ฒ์์.db
์ญํ ์ ๋ํด ์คํ๋ฉ๋๋ค."@group
์ ๊ฐ์ @task
, ๊ทธ๋ฆฌ๊ณ ๊ธฐ๋ฅ์ ์์
์ ์คํ ๋จ์ ์๋์ง๋ง, ๋์ ๊ทธ๋ฃน ๊ฐ์ฒด๋ฅผ ์ป์ ์ ์์ต๋๋ค.๋ฉ์ผ๋ง ๋ฆฌ์คํธ์์:
๋ฐฐํฌ๋๋ ํ๋ก์ ํธ์ ๋ฐ๋ผ env.roledefs๋ฅผ ๋์ ์ผ๋ก ์ฑ์ฐ๋ ์์ฒด ๋ด๋ถ REST API๋ฅผ ๊ตฌํํ์ผ๋ฉฐ ํธ์คํธ ๋ฌธ์์ด์ ํ๋ก์ ํธ์ fabfile์ ํฌํจํ์ง ์๊ฑฐ๋ CLI์์ ์ง์ ํ์ง ์๋ ๊ฒ์ ํฌ๊ฒ ์์กดํฉ๋๋ค.
์ฌ์ฉ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
EnvironmentDatabaseAPIClient(
'https://rest.api.url/schema/',
env.service_name,
).apply_env()
์๋ฒ ํ๊ฒฝ์ ์ - ์ฌ๋ฌ ํ ์คํธ ํ๊ฒฝ(์ผ๋ถ๋ ๋น๊ณต๊ฐ, ์ผ๋ถ๋ ๊ณต๊ฐ) ๋ฐ ์ฌ๋ฌ ํ๋ก๋์ ํ๊ฒฝ(๋ค๋ฅธ ํด๋ผ์ด์ธํธ์ฉ). ๊ฐ ํ๊ฒฝ์ ํ๋ ์ด์์ ํธ์คํธ๋ก ๊ตฌ์ฑ๋๋ฉฐ ํจ๋ธ๋ฆญ ์ญํ ์ ๋งคํ๋ฉ๋๋ค.
๊ฐ ์๋น์ค(์์ ์์์ env.service_name
)์๋ ์๋ก ๋ค๋ฅธ ํ๊ฒฝ ์ธํธ๊ฐ ์์ต๋๋ค.
๋ํ ๋ฉํ ์ญํ (์ญํ ๊ทธ๋ฃน)์ด ์์ต๋๋ค. group-
์ ๋์ฌ: group-production
, group-test
, group-external
, group-internal
, group-all
. ์ด๋ฅผ ํตํด ํ๋์ฉ ์ง์ ํ์ง ์๊ณ ์ฌ๋ฌ ์๋ฒ ์ญํ ์ ๋ฐฐํฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด group-all
๋ ํ๋ก๋์
๋ฐ ํ
์คํธ์ ๋ชจ๋ ์ญํ ์ ๋ฐฐํฌํฉ๋๋ค.
์ญํ ๊ทธ๋ฃน, ์ญํ ๋ฐ ํธ์คํธ์ ๋ํ ์ ๋ณด๋ฅผ ์ธ์ํ๋ ํน๋ณํ ํจ๋ธ๋ฆญ ์์ ์ด ์์ต๋๋ค.
๋ํ ํธ์คํธ ๋ฌธ์์ด์ ์ญํ ์ด๋ฆ์ผ๋ก ๋ค์ ๋งคํํ๋ ์ญ๋ฐฉํฅ ๋งคํ์ ํฌ๊ฒ ์์กดํฉ๋๋ค(ํธ์คํธ ๋ฌธ์์ด์ service_name๋ณ๋ก ๊ณ ์ ํจ). ์ด๋ ๋ฐฐํฌ ๋ก๊น
๋ฐ ์๋ฆผ์ ์ฌ์ฉ๋ฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ ํธ์คํธ์ ์๋น์ค ๋ฐฐํฌ๋ฅผ ๊ธฐ๋กํ๊ณ ์ญํ ์ ๋ชจ๋ ํธ์คํธ์ ์๋น์ค๊ฐ ๋ฐฐํฌ๋๋ฉด Slack ์๋ฆผ์ ๋ณด๋
๋๋ค. EnvironmentDatabaseAPI ์๋ฒ๊ฐ ์ด๋ฅผ ๋ด๋นํฉ๋๋ค(๋ก๊ทธ ๋ฐ ๋ฐฐํฌ ์ํ๋ฅผ ์ ์งํจ). ์ด๊ฒ์ env.host
, env.port
๋ฐ env.service_name
(์ปค๋ฐ ์ ๋ณด ํฌํจ)๋ฅผ API ์๋ฒ์ ๋ค์ ์ ์ถํ๋ ๋ฐ์ฝ๋ ์ดํฐ๋ก ํจ๋ธ๋ฆญ ์์
์ ๋ฐ์ฝ๋ ์ด์
ํ์ฌ ์ํ๋ฉ๋๋ค.
์ฐ๋ฆฌ๋ ์์ผ๋ก ๋ฐฐํฌ ์ธ์ฆ์ ์ถ๊ฐํ ๊ณํ์ด๋ฉฐ, ์์
์ปจํ
์คํธ ๋ด์์ ์ฌ์ฉํ ์ ์๋๋ก ์๋ฒ์์ ๋ ๋ง์ env
๋ณ์๋ฅผ ๊ฐ์ ธ์ฌ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋์ต๋๋ค.
@max-arnold ๊ฐ์ฌํฉ๋๋ค! ๋๋ ๊ณผ๊ฑฐ์ ๋ด ์์ ์ ์ฌ์ฉ ์ฌ๋ก์์๋ ๋ง์ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ํนํ ์ญ ๋งคํ ๋นํธ๋ v1์ ๋ช ๋ฒ ๋์๋ ๊ฒ์ผ๋ก ๊ธฐ์ตํฉ๋๋ค. ๊ทธ๋์ ๋ชฉ๋ก์ ์ถ๊ฐํ์ต๋๋ค.
Fabric v2๊ฐ ๋์๊ฒ ์ ์ฉํ๋ ค๋ฉด fab
์ ์์
์ ์คํํ ํธ์คํธ ์งํฉ์ ์๋ ค์ฃผ๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค.
์ด์ ์๋ ์ญํ ์ ์ ์ํ ๋ค์ fab -R ...
. (์ค์ ๋ก ์ญํ ์ IP ์ฃผ์ ๋ฒ์๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ์ ์๋์์ง๋ง ์๊ตฌ ์ฌํญ์ ์๋๋ฉฐ YAML ํ์ผ ๋ด๋ถ์ ์ ์ ๋ชฉ๋ก์ ๊ด์ฐฎ์ ๊ฒ์
๋๋ค.)
Fabric v2์์ ์ด์ ์์ํ๋ ๊ฒ์ ์ฐพ์ง ๋ชปํ๊ณ ๋ค์์ ์ฌ์ฉํ์ฌ ์ด ๊ธฐ๋ฅ์ ์๋ฎฌ๋ ์ดํธํ๋ ๋ฐ๋ ์คํจํ์ต๋๋ค.
fabric.yaml
๊ตฌ์ฑ ํ์ผactive_hostset: null
hostsets:
myhostset:
- ...
active_hostset = config["hostsets"][config["active_hostset"]]
์ fabfile.py
env INVOKE_ACTIVE_HOSTSET=myhostset fab ...
์์ ํธ์คํธ ๋ชฉ๋ก ๋์ KeyError: 'active_hostset'
์ป์ต๋๋ค.
Fabric v1์ ๊ฐ ํ๊ฒฝ์ ๋ํ ๊ฐ ์ญํ ์ ์๋ก ๋ค๋ฅธ ํธ์คํธ ์ธํธ๋ฅผ ๋งคํํ๊ณ role.environment:staging
์์
์ ์คํํ์ฌ ํ๊ฒฝ์ ์ค์ ํ์ฌ ํ๊ฒฝ์ ์ง์ ํฉ๋๋ค. ๋ฐ๋ผ์ ์ด ์์
์ ๋ค์ ์์
์์ ์ฌ์ฉํ๋ ํธ์คํธ์ ์ํฅ์ ์ค๋๋ค.
v2์์ ์ฐ๋ฆฌ๋ ์ฌ์ฉ์ ์ ์ ์์
์ ์ฌ์ฉํ๋ ค๊ณ ์๋ํ์ง๋ง ๋ฌธ์ ๋ Executor.expand_calls
role.environment
์์
์ด ์คํ๋๊ธฐ ์ ์ Executor.expand_calls
๊ฐ ์คํ๋๋ฏ๋ก ๋ค์ ์์
์ค ์ด๋ ๊ฒ๋ ํธ์คํธ ๋ชฉ๋ก์ ๋์ ์ผ๋ก ๋น๋ํ๊ธฐ ์ํด ํ๊ฒฝ์ ์์ง ๋ชปํ๋ค๋ ๊ฒ์
๋๋ค.
Executor.expand_calls
์์ฑ๊ธฐ๋ฅผ ๋ง๋ค๋ฉด ์์
์คํ์ด ์ดํ ์์
์คํ์ ์ํฅ์ ์ค ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์์ ์๋ ํธ์คํธ์ ๋ํ ์ญํ ์ ์ ์ ํ๊ฒ ํ์ฅํ๊ธฐ ์ํ ํ๊ฒฝ์ ์์์ผ ํ๋ ์ฌ์ฉ์ ์ ์ Task
๊ฐ ์๋ ๊ณณ์์ ์๋ํฉ๋๋ค. ์: fab role.environment dev deploy.app
- deploy.app
๊ฐ ํ์ฅ๋๊ธฐ ์ ์ role.environment
์์
์ด ์คํ๋๋ฏ๋ก deploy.app
๋ ํ๊ฒฝ์ ์๊ณ ํธ์คํธ๋ฅผ ๊ตฌ์ฑํ ์ ์์ผ๋ฉฐ ๋ค์์ผ๋ก ํ์ฅ๋ฉ๋๋ค. ์ฌ๋ฐ๋ฅธ ์์
์ธํธ.
๋ด ํฌํฌ์์ ํ๋กํ ํ์
์ ๋ง๋ค์์ต๋๋ค.
https://github.com/pyinvoke/invoke/compare/master...rectallogic:expand-generator
https://github.com/fabric/fabric/compare/master...rectallogic:expand-generator
์๋
ํ์ธ์, ๋ช ๋
ํ ์ด ์ํํธ์จ์ด์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ๋ชจ๋ฅด์ง๋ง [email protected] ์์ ํนํ $ fab -R dev
์คํํ ๋ "์ญํ " ๊ฐ๋
์ ๋์ณค์ต๋๋ค.
๋ํ ์ญํ ์ ์ฌ์ฉํ์ฌ ์๋ก ๋ค๋ฅธ ํ๊ฒฝ์์ ๋์ผํ ์์ ์งํฉ์ ๋ํ๋ ๋๋ค. ๋ช ๋ช ๋ ์ญํ ๊ณผ ๋ช ๋ช ๋ ํ๊ฒฝ์ ๊ฐ๋ ์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ ์ฉํ ๊น์? ์์์ ๊ฐ์ด ๊ฐ๋ฐ ํ๊ฒฝ์์ ์น ์ญํ .
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์๋ ํ์ธ์, ๋ช ๋ ํ ์ด ์ํํธ์จ์ด์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ๋ชจ๋ฅด์ง๋ง [email protected] ์์ ํนํ
$ fab -R dev
์คํํ ๋ "์ญํ " ๊ฐ๋ ์ ๋์ณค์ต๋๋ค.