ããã«ã¡ã¯ãSREããŒã ããã€ã³ãã©ãšã³ãžãã¢ã®ç¶¿åŒã§ãã ä»å㯠MySQL ã®ééçæå·å ã«ã€ããŠèšèŒããããšæããŸãã å ã¿ã«ééçæå·åã䜿çšã§ããã®ã¯ MySQL 5.7.11 ãã ã§ãã®ã§ãèªèã®ã»ã©ã åå 㯠RDS ã®æå·åã«ã€ããŠè»œãè§ŠããŸãããã ãã®éã¯Webã³ã³ãœãŒã«ããããã¯ã¹ã«ãã§ãã¯ãå
¥ããã ãã§ããã ä»åã® MySQL ã®ééçæå·åã䜿çšããå Žåã«ã¯èšå®ãå¿
èŠã§ãã ã§ã¯æ©éãã£ãŠãããããšæããŸãã ç°å¢ ã»OS : CentOS 7.1 ã»ããŒã¿ããŒã¹ : MySQL 5.7.22 èšå® ãŸãã¯æå·åã®åã«æ€èšŒçšã®ãã¹ãããŒãã«ãäœæããŸãã ã»ããŒã¿ããŒã¹ : test ã»ããŒãã« : test ã«ã©ã ã¯é©åœã« id , name ãšãã2ã¬ã³ãŒãã»ã©ãinsert ããŠãããŸãã mysql> select * from test.test; +------+-------+ | id | name | +------+-------+ | 1 | test | | 2 | test2 | +------+-------+ 2 rows in set (0.00 sec) ãªãããšã³ãžã³ã¯ InnoDB ã§ãã å°ãè±ç·èŽããŸãã MyIsam ã§ãæå·åïŒalter table XX ENCRYPTION=’Y’ïŒãã§ããã®ã§ããã mysqldump ãååŸããŠãã€ã³ããŒãããéã«å€±æããã®ã§ã æå·åããéã¯ãšã³ãžã³ã InnoDB ã§ããããšã確èªããæ¹ãè¯ãã§ãã ãã¡ãã«é¢ããŠã¯ãŸãå¥éæžããããšæããŸãã ã§ã¯ã次㫠OS äžã§ã©ã®ããã«èŠããã確èªããŸãã ibd ãã¡ã€ã«ã¯ãã€ããªã®ãã strings ã³ãã³ãã§ç¢ºèªããŸãã # strings /var/lib/mysql/test/test.ibd ã» ã» ã» test test2 å
ã»ã© insert ãã name åã®æåã確èªã§ããç¶æ
ã§ããã æ¬¡ã¯æå·åçšã®èšå®ãè¡ãªã£ãŠãããããšæããŸãã ãã©ã°ã€ã³ã®ã€ã³ã¹ããŒã« ãŸãã¯ãã©ã°ã€ã³ã®ã€ã³ã¹ããŒã«ã§ãã $ mysql -uroot -p mysql> select PLUGIN_NAME,PLUGIN_STATUS from information_schema.plugins WHERE PLUGIN_NAME LIKE 'keyring%'; Empty set (0.00 sec) mysql> install plugin keyring_file soname 'keyring_file.so'; Query OK, 0 rows affected (0.01 sec) mysql> select PLUGIN_NAME,PLUGIN_STATUS from information_schema.plugins WHERE PLUGIN_NAME LIKE 'keyring%'; +--------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +--------------+---------------+ | keyring_file | ACTIVE | +--------------+---------------+ 1 row in set (0.00 sec) ãªããMySQL 5.7.11 ã§ã¯ããã©ã«ãã®ãã©ã°ã€ã³ã§ãããã MySQL 5.7.12 以éã¯ããã©ã«ãã§å
¥ã£ãŠããªãã®ã§æç€ºçã«ã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã my.cnfä¿®æ£ æ¬¡ã« my.cnf ã«ä»¥äžã®2è¡ã远å ããŠãããŸãã early-plugin-load=keyring_file.so keyring_file_data=/var/lib/mysql/mysql-keyring/keyring ãã©ã¡ãŒã¿ã®æå³ãšããŠã¯ã 1è¡ç®ã® early-plugin-load ãããŒããããã©ã°ã€ã³ãæå®ããŸãã å
ã»ã©ã€ã³ã¹ããŒã«ããããŒãªã³ã°ãã©ã°ã€ã³(keyring_file.so)ã§ããã 2è¡ç®ã® keyring_file_data ã¯ããŒãªã³ã°ãã¡ã€ã«ã®çœ®ãå Žæã§ãã ä»ã®ããŒã¿ããŒã¹ãã¡ã€ã«ãšæ··åšããªãå Žæãæšå¥šãããŠããã®ã§ã 次ã®é
ç®ã§å°çšã®ãã£ã¬ã¯ããªãäœæããŠãããŸãã å ã¿ã«ä»¥äžããã©ã¡ãŒã¿ãšããŠå¿
èŠãªã®ã§ããã MySQL 5.6.6以éã¯ããã©ã«ãã§æå¹ãªã®ã§ããã£ãŠãªããã°å€§äžå€«ã§ãã innodb_file_per_table=1 ããŒãªã³ã°ãã¡ã€ã«ã®çœ®ãå ŽæïŒãã£ã¬ã¯ããªïŒäœæ äžèšã§æå®ãããã£ã¬ã¯ããªãäœæããŠãããŸãã $ sudo mkdir -p /var/lib/mysql/mysql-keyring $ sudo ls -ltr /var/lib/mysql/ $ sudo chown -R mysql:mysql /var/lib/mysql/mysql-keyring $ sudo chmod 750 /var/lib/mysql/mysql-keyring $ sudo ls -ltr /var/lib/mysql/ MySQL åèµ·å åŸã¯ MySQL ãåèµ·åããŠãããŸãã $ sudo systemctl status mysqld $ sudo systemctl restart mysqld $ sudo systemctl status mysqld æå·åãããïŒ ãããŸã§åºæ¥ãã°æå·åã§ããç°å¢ã®æºåã¯æŽããŸããã æå·åã®æ¹æ³ãšããŠã¯ã以äžã§ãã ã»æ°èŠããŒãã« : Create ãªãã·ã§ã³ã« ãENCRYPTION=’Y’ã ãä»äžãã ã»æ¢åããŒãã« : 察象ããŒãã«ã«å¯ŸããŠã ãalter table ããŒãã«å ENCRYPTION=”Y”ã ã宿œãã ä»åã¯æ€èšŒçšã«ããŒãã«ãäœæããŠããã®ã§ã alter table æã§æå·åããŠãããŸãã ãŸãã¯å¯Ÿè±¡ããŒãã«ãæå·åãããŠããªãããšã確èªããŸãã 確èªã«ã¯ information_schema ã® tablesãã䜿çšããŸãã mysql> select TABLE_SCHEMA,TABLE_NAME,ENGINE,CREATE_OPTIONS from information_schema.tables -> where TABLE_SCHEMA = 'test'; +--------------+------------+--------+----------------+ | TABLE_SCHEMA | TABLE_NAME | ENGINE | CREATE_OPTIONS | +--------------+------------+--------+----------------+ | test | test | InnoDB | | +--------------+------------+--------+----------------+ 1 row in set (0.00 sec) æå·åããããšãäžèšã® CREATE_OPTIONS ã« ENCRYPTION=’Y’ ãå
¥ããŸãã ã§ã¯ alter table æãå®è¡ããŸãã mysql> alter table test.test ENCRYPTION='Y'; Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0 å床ãinformation_schema ã® tablesãã確èªããŸãããã mysql> select TABLE_SCHEMA,TABLE_NAME,ENGINE,CREATE_OPTIONS from information_schema.tables -> where TABLE_SCHEMA = 'test'; +--------------+------------+--------+----------------+ | TABLE_SCHEMA | TABLE_NAME | ENGINE | CREATE_OPTIONS | +--------------+------------+--------+----------------+ | test | test | InnoDB | ENCRYPTION="Y" | +--------------+------------+--------+----------------+ 1 row in set (0.01 sec) CREATE_OPTIONS ã ENCRYPTION=”Y” ãšãªã£ãŠããã®ã§æå·åãããããã§ããã å®éã«ã©ããªã£ãŠããã確èªããŠãããŸãããã åœç¶ãªãããselect æã¯åé¡ãªãçºè¡ã§ããŸãã mysql> select * from test.test; +------+-------+ | id | name | +------+-------+ | 1 | test | | 2 | test2 | +------+-------+ 2 rows in set (0.00 sec) ã§ã¯ãå
ã»ã©ã¯ç¢ºèªã§ãã OS ãããstrings ã³ãã³ããçºè¡ãããã©ãã§ãããã # strings /var/lib/mysql/test/test.ibd 2063f200-7132-11e8-bf60-08002751d15e T#*a 3omg ã» ã» ã» RaR&h es{Ds ,j6Z å
ã»ã©ã¯åºåãããŠãããtest ãªã©ã®æèšã衚瀺ãããã æå·åãããæååãåºåãããŠããŸããã æ³å®éãæå·åã§ããããã§ãã æåŸã«ãã°ãèŠãŠåé¡ãªãããšã確èªããŸãããã ERROR ãåºãŠããã 以äžã®ãããªãšã©ãŒãåºãŠãããŸãããã $ sudo cat /var/log/mysqld.log ã» ã» ã» 2018-06-16T08:14:49.059936Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' 2018-06-16T08:15:00.149256Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' 2018-06-16T08:15:55.047206Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' 2018-06-16T08:16:16.390285Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' 2018-06-16T08:16:21.920555Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' 2018-06-16T08:16:28.583733Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' 2018-06-16T08:16:58.977404Z 3 [ERROR] Invalid (old?) table or database name 'mysql-keyring' ä»åããŒãªã³ã°ãã¡ã€ã«ã®çœ®ãå
ãšã㊠/var/lib/mysql/mysql-keyring ãã£ã¬ã¯ããªé
äžãæå®ããŸãããã datadir ã«ãŠ /var/lib/mysql/ ãæå®ããŠããã®ã§ã mysql-keyring ãã£ã¬ã¯ããªãããŒã¿ããŒã¹ãšæããŠããŸã£ãããã§ãã ããã§ããããäœïŒ DB? ããïŒã ãšããã¡ãã»ãŒãžã ERROR ãšããŠåºåãããæš¡æ§ã 確ãã« show databases ã§ç¢ºèªãããšä»¥äžã®ãããªè¡šèšã«ãªããŸãã mysql> show databases; +------------------------+ | Database | +------------------------+ | information_schema | | mysql | | #mysql50#mysql-keyring | | performance_schema | | sys | | test | +------------------------+ 6 rows in set (0.00 sec) #mysql50#mysql-keyring ãšããã®ãããã£ãœãã§ããã DML ã¯åé¡ãªãçºè¡ã§ããã®ã§æåçã«ã¯åé¡ãªãããã§ãããã¡ãã»ãŒãžã®éããã³ããªããã ãã£ãšèŠãæã MySQL ã®åèµ·åæãããŒãã«ã¢ã¯ã»ã¹æã«ãåºåãããŠããã¿ãããã 察å¿ããŠãããŸãããã æ¹æ³ãšããŠã¯2ã€ãããäžã€ã¯ããŒãªã³ã°ãã¡ã€ã«ã®çœ®ãå Žæã倿Žããã ããäžã€ã¯æ¢åã®èšå®ã¯ãã®ãŸãŸã«ãã©ã¡ãŒã¿ãäžã€è¿œå ããæ¹æ³ã§ãã èšå®å€æŽããã®ã¯é¢åãªã®ã§ãåŸè
ã宿œããŠãããŸãã my.cnfåä¿®æ£ èšå®ã¯ç°¡åã§ãã以äžã远å ããŸãã ignore-db-dir=mysql-keyring ã§ãã®ã§æçµç㪠my.cnf ãšããŠã¯ä»¥äžã®ããã«ãªããŸããã early-plugin-load=keyring_file.so keyring_file_data=/var/lib/mysql/mysql-keyring/keyring ignore-db-dir=mysql-keyring MySQL åèµ·å å床ãåèµ·åããŠãããŸãã $ sudo systemctl status mysqld $ sudo systemctl restart mysqld $ sudo systemctl status mysqld ãã®åŸãã°ã確èªããŸãããã ãã [ERROR] Invalid (old?) table or database name ã»ã»ã» ãšãããšã©ãŒã¯åºãŠãªããããã show databases ã®çµæãåé¡ãªãããã§ãã mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+ 5 rows in set (0.00 sec) ãŸãšã æ³å®å€ããããŸããããééçæå·åãã§ããŠè¯ãã£ãã§ãã ç¹ã«ã¢ããªã±ãŒã·ã§ã³åŽã倿Žããã«ãã€ã³ãã©åŽã ãã§å¯Ÿå¿ã§ããç¹ã¯éåžžã«è¯ããšæããŸãã çããŸãæ¯éãèå³ãããã°ã ãã®åºŠã¯ããæž
芧é ãããããšãããããŸããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ãSREããŒã ã®è¥¿èïŒ@yasuhiro1711ïŒã§ããä»åã¯ç¹å¥çªçµãšããããšã§ã33æéã¯ããã³ã°ããKubernetesã®ã©ãºããªãŒãã€å
ã¿ããŠãšã颚ãããéãããããšæããŸããèŠéããããªæ¹ã¯ãã²é²ç»äºçŽããé¡ãããŸãã ãµã€ããŒã®çŸå³ããããªãã€å
ã¿ãèŠãŠããŠãšãã§ãç©ççã«ãã€å
ã¿ãäœã£ãŠã¿ãããšã«ããŸãããããŒã«ã«ãã·ã³ãã¯ã©ãŠãã§ãã¯ã©ã¹ã¿ãŒãçµãã§å©çšããããšã¯å¯èœã§ããããã®ã¯ããã³ã°ãéããŠKubernetesã®ããããã®çè§£ãæ·±ããããšãç®çãšããŠãããŸããã â» ãªããã¡ãã®èšäºã¯ãè³ãæããµã€ããŒãšãŒãžã§ã³ããéåžžããã«ãªããŒãžã¥ããããŸãããã®èšäºãäºæ¿é ããŸããŠãæ¬åœã«ããããšãããããŸãïŒ ãªããŒãžã¥èšäºã¯æåŸã«ãªã³ã¯ãããããŸãã äžå®¶ã«äžå°ãKubernetesã®æä»£ã« ãã®10幎ã§ã¹ãããççºçã«æ®åããããã«ãKubernetesãäžå®¶ã«äžå°ã®æä»£ããã£ãŠããŸããæ¬æ¥äœãã©ãºããªãŒãã€å
ã¿ã¯ãããªæä»£ã«ãã£ãŠãããå®¶åºã§ãåæ§ãããããã¡ãããŸã§å¹
åºãæãããã§ããããæã®ã²ããµã€ãºã®Kubernetesã§ãã 宿å 宿åã¯ãã¡ããšãªããŸãããžã£ãŒã³ïŒ ææãïŒ1ã¯ã©ã¹ã¿åïŒ ã§ã¯ããŸãã¯ææã®ã玹ä»ã§ãã ææå åæ° Raspberry Pi 3 Model B 3 å ããŒãã·ã³ã¯ 3 ã»ãã microSD ã«ãŒã (16 GB) 3 æ 4 段ç©å±€åŒ Raspberry Pi 3 ã±ãŒã¹ 1 å 6 ããŒã 50W USB å
é»åš 1 å 2.4A microUSB ã±ãŒãã« 5 æ¬ ã³ã³ãã¯ãç¡ç·èŠªæ© (WMR-433W-BK) 1 å microUSB çµŠé» ã¹ã€ããã³ã°ãã (LAN-SW05PSBE) 1 å 0.3m LAN ã±ãŒãã« 3 æ¬ 0.15m LAN ã±ãŒãã« 1 æ¬ 3M 匷åäž¡é¢ããŒã å°ã
çµæããŒã å°ã
å
è§ã¹ããŒãµãŒ é©é ãŠãšã ã®ã¹ããã«ãŒ ãã©ã€ã¹ã¬ã¹ ããã ãã®ææãéãããšãããªæãã«ãªããŸããã ãã®ãŸãŸã§ãçŸå³ããããªã©ãºããªãŒãã€ã6åããããŸããã äœãæ¹ ãã¿ã®äžæºå 1, ã©ãºãã€ã®éå° ãŸãã¯ãã©ãºããªãŒãã€ãéå°ããŸãã å·ã€ããªãããæ°ãã€ããŸãããã 2, ããŒãã·ã³ã¯èšçœ® ç¶ããŠããŒãã·ã³ã¯ãã€ããŸããäž¡é¢ããŒããå¥ããã®ãæå€ã«èŸãã£ãã§ããéã®é±åãã®ããã§ããã 3, 4 段ç©å±€åŒã®ã±ãŒã¹ã® äž 3 段㫠Raspberry Pi ãåãä»ã ã¢ã¯ãªã«æ¿ã®ä¿è·ã·ãŒã«ãå¥ãããŸããå¥ããã¥ãããšèããŠããŸãããä»å賌å
¥ã®ãã®ã¯ãçªã䜿ãã°æå€ãšç°¡åã§ããã å¥ããããã¢ã¯ãªã«æ¿ã«ã©ãºãã€ãåãä»ããŸãããã®ããã«ã§ããã°OKã§ããããããããïŒ ãã®åŸ,2段ç®ãïŒæ®µç®ãšäœã£ãŠãŸãããŸããããŒããæãã 4, æäžæ®µã« USB å
é»åšãåãä»ã åçã®ãããªããã¡ã§USBå
é»åšããšãã€ããŸããäž¡é¢ããŒãã§ãã£ã¡ããšããŸããããã¡ãªã¿ã«ä»åã®å
é»åšã¯ã®ãªã®ãªã®å€§ããã§ããã®ã§ã賌å
¥æã«å€§ããã¯ãã£ããèŠãŠãããæ¹ãããã£ãã§ãã èšçœ®åŸã倩æ¿ãŸã§èšçœ®ãã§ããŸããã 5, æäžæ®µã«ã¹ã€ããã³ã°ãããšã³ã³ãã¯ãç¡ç·èŠªæ©ãåãä»ã ããããäž¡é¢ããŒãã§åºå®ããŸããåãã¯ããªãã®ææ§ã§ãã±ãŒãã«ã®é·ãã«ã¯æ³šæããŸãããã 6, æåŸã«ã±ãŒããªã³ã°ãäžå¯§ã«å®æœ ããããšã³ãžãã¢ããããã®åæ§ãåºããšããã§ããç§ã¯ãããªæãã§æ±ºããŸããïŒã 7, ãããã¯ãŒã¯ã®èšå® äžçªäžã«èšçœ®ããŠãããç¡ç·LANã«ãŒã¿ãŒã«æ¥ç¶ããŸãããã®ç®¡çç»é¢ã«ãŠãå¥wifiã«æ¥ç¶ããããšã§ã€ã³ã¿ãŒããããžã®çéããšããŸãã OS ã®ã€ã³ã¹ããŒã« ããããã®éšåã¯ãããã€ãã®æ¹æ³ã詊ããŠçè§£ãæ·±ããŸããããããã§ã¯ããã±ãŒãžãçšããåãããããæ§ç¯æé ãèšèŒããŠé²ããŠãããŸãããŸãã¯ïœ€Raspberry PIã«OSãã€ã³ã¹ããŒã«ããŸãä»åã¯Raspbianãå©çšããŸã ãã€ã¯ãSDã«ãŒãã«OSã€ã¡ãŒãžäœæ ããããããã€ã¯ãSDã«ãŒãã«ã€ã¡ãŒãžãæžã蟌ã¿ããäœæ¥ãmacOSäžã§è¡ããŸãã 以äžã®URLããRaspbian stretch liteãããŠã³ããŒãããŸã https://www.raspberrypi.org/downloads/raspbian/ ããŠã³ããŒãããzipãã¡ã€ã«ãè§£åããŠïœ€ãã€ã¯ãSDã«ãŒãã«æžã蟌ã¿ãŸã ãã£ã¹ã¯ã®ãã¹ã¯ç°å¢ããšã«éãã®ã§æ³šæãå¿
èŠã§ã // zipãã¡ã€ã«ãè§£åãã $ cd ~/Download $ unzip 2017-09-07-raspbian-stretch-lite.zip Archive: 2017-09-07-raspbian-stretch-lite.zip inflating: 2017-09-07-raspbian-stretch-lite.img // SD card ã®ãã¹ãç¢ºèª $ diskutil list // SD card ãã¢ã³ããŠã³ããã sudo diskutil umountDisk /dev/disk2 // dd ã³ãã³ãã§ã€ã¡ãŒãžãæžã蟌ã $ sudo dd bs=1m if=2018-04-18-raspbian-stretch-lite.img of=/dev/rdisk2 conv=sync 1Mãšèª¬æããŠãããµã€ããå€ãããå°æåã§ãããªããããããªããããã OSã€ã¡ãŒãžãSDã«ãŒãã«æžã蟌ãããããã€ãèšå®ãè¡ããŸããããã®äœæ¥ãmacOSäžã§è¡ããŸã ssh ã®æå¹å sshãæå¹ã«ããããã®èšå®ãããŸãã«sshãšããååã®ãã¡ã€ã«ãäœæããŸã $ cd /Volumes/boot $ touch ssh ãã®äœæ¥ãè¡ãããšã«ããRaspbianã®èµ·ååŸã«sshdãèµ·åãããªã¢ãŒããã°ã€ã³ãå¯èœã«ãªããŸãã # cgroups ã®æå¹å 次ã«cgroupsã®cpusetãšmemoryãæå¹åããããã«ïœ€ä»¥äžã®èšå®ãè¡ããŸã $ cd /Volumes/boot $ vi cmdline.txt cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1ã远å ããŸã Bootãšåæèšå® äœæããSDã«ãŒããRaspberry PIã«æ¿å
¥ãïœ€é»æºããããŸã èµ·ååŸã¯ããã©ã«ãã§raspberrypi.localã®ååã§ã¢ã¯ã»ã¹ããããšãã§ããŸã slogin pi@raspberrypi.local ïŒåæãã¹ã¯ãŒã㯠raspberryïŒ ãã®åŸãåOSã®ãã¹ãåã®èšå®ãhostsã®èšå®ãè¡ããŸãã3å°ã¯ãk8s01ïŒmasterïŒãk8s02ïŒnodeïŒãk8s03ïŒnodeïŒ ãšããŸããã ã¹ã¯ããåé€ k8s 1.8ããã¹ã¯ãããæå¹ã ãškubeletãèµ·åããªãã®ã§å®æœããã sudo dphys-swapfile swapoff sudo dphys-swapfile uninstall sudo update-rc.d dphys-swapfile remove DockerãšKubernetesã³ã³ããŒãã³ãã®ã€ã³ã¹ããŒã« Docker ã€ã³ã¹ããŒã« curl -sSL https://get.docker.com/ | sh kubelet kubeadm kubectl kubernetes-cni ã®ã€ã³ã¹ããŒã« kubelet kubeadm kubectl kubernetes-cniãã€ã³ã¹ããŒã«ããŠãããŸãã apt-transport-httpsãã€ã³ã¹ããŒã« èªåã®ç°å¢ã§ã¯æ¢ã«ã€ã³ã¹ããŒã«æžã¿ã§ããã apt-get install -y apt-transport-https éµç»é² curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - aptã®ãœãŒã¹ãªã¹ãã«kubernetesã远å echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list aptãæŽæ°ããŸãã sudo apt-get update kubernetesã®åã¢ãžã¥ãŒã«ãã€ã³ã¹ããŒã«ããŸãã apt-get install kubelet kubeadm kubectl kubernetes-cni â» ã€ã³ã¹ããŒã«ã«æåãããšèªåçã«kubeletãèµ·åããŸãã masterã®ã»ããã¢ããïŒk8s01ã§ã®ã¿å®æœïŒ master ã®ã»ããã¢ãããè¡ããŸãã 以äžãå®è¡ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 ããinitã«å€±æããŠããããkubeadm reset ã§æ»ããŸããæåãããšä»¥äžã®ãããªã¡ãã»ãŒãžãæµããŸãã Your Kubernetes master has initialized successfully! To start using your cluster, you need to run (as a regular user): mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: http://kubernetes.io/docs/admin/addons/ You can now join any number of machines by running the following on each node as root: kubeadm join --token 6391e6.b4b1bb96a7bdea7c 192.168.13.11:6443 --discovery-token-ca-cert-hash sha256:90be9b3dd4d44c1225d5c3e52af49db25d5c3e5226a5a708fe0af36dadb kubeadm init ã§è¡šç€ºãããã¡ãã»ãŒãžã«åŸã£ãŠã以äžã®ã³ãã³ããå®è¡ã rootããäžè¬ãŠãŒã¶ã«ãªã£ãŠå®è¡ããŸãã mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config kubectl ãæ£ããå®è¡ã§ããã確èªã $kubectl version Client Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.5", GitCommit:"cce11c6a185279d037023e02ac5249e14daa22bf", GitTreeState:"clean", BuildDate:"2017-12-07T16:16:03Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/arm"} Server Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.13", GitCommit:"290fb182489a396dce5d136451388f9b12f29c94", GitTreeState:"clean", BuildDate:"2018-05-15T18:08:47Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/arm"} kubectl get nodes kubectl get nodes NAME STATUS ROLES AGE VERSION k8s01 NotReady master 5m v1.8.5 kubectl get pods –all-namespaces -o wide kubectl get pods --all-namespaces -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE kube-system etcd-k8s01 1/1 Running 0 6m 192.168.13.11 k8s01 kube-system kube-apiserver-k8s01 1/1 Running 0 6m 192.168.13.11 k8s01 kube-system kube-controller-manager-k8s01 1/1 Running 0 6m 192.168.13.11 k8s01 kube-system kube-dns-66ffd5c588-fns2f 0/3 Pending 0 6m <none> <none> kube-system kube-proxy-tfwl8 1/1 Running 0 6m 192.168.13.11 k8s01 kube-system kube-scheduler-k8s01 1/1 Running 0 6m 192.168.13.11 k8s01 ããã kube-system kube-dns-66ffd5c588-fns2f 0/3 ãšãªã£ãŠãããdnsãããŸãããããŠããªãããšãããããŸãã falnnel ã®ããã〠kubectl apply -f <(curl -s https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml |sed 's/amd64/arm/g') ãã¹ã¿ãŒïŒk8s01ïŒã«ãnode2å°ãjoinïŒk8s02,k8s03ïŒ masterã§ãinit ãæåããæã«ãããŒã¯ã³ãå«ããjoinã®ã³ãã³ããæµããŸãããããã§nodeãç»é²ãããŸãã kubeadm join --token 6391e6.b4b1bb96a7bdea7c 192.168.13.11:6443 --discovery-token-ca-cert-hash sha256:90be9b3dd4d44c1225d5c3e52af49dbf611baf1a611d926a5a708fe0af36dadb ç»é²åŸ ãŸã NotReadyã§ãããã pi@k8s01:~ # kubectl get nodes NAME STATUS ROLES AGE VERSION k8s01 Ready master 15m v1.8.5 k8s02 NotReady <none> 35s v1.8.5 k8s03 NotReady <none> 34s v1.8.5 Readyã«å€ãããŸãã pi@k8s01:~ # kubectl get nodes NAME STATUS ROLES AGE VERSION k8s01 Ready master 16m v1.8.5 k8s02 Ready <none> 1m v1.8.5 k8s03 Ready <none> 1m v1.8.5 ã§ããŸããããããã§ã¯ã©ã¹ã¿ãŒãçµããŸããã®ã§ãã®äžã«podãäœæããŠã¢ããªã±ãŒã·ã§ã³ãä¹ããŠæ€èšŒã§ããããã«ãªããŸããã ãŸãšã ãKubernetesã®ã©ãºããªãŒãã€å
ã¿ããŠãšã颚ãããäœã£ãŠèŠãŸããã ç©ççã§ããã®ã§å®éã«èªãkubernetesã®åããçè§£ããŠããã®ã«ã¯ãéåžžã«ãããã®ãšãªããŸããããŸããããã€ãã®ãã¿ãŒã³ã§ã®æ§ç¯ããdashbordãmetallbã®ãã¹ããªã©ã«ãèžã¿èŸŒãã§ãããã®ã§ãç ä¿®ãšããŠGoodã§ããããªã©ã€ãªãŒã®å
¥éKubernetesã«ã䌌ãäŸãèŒã£ãŠããã®ã§åèã«ããŠã¿ãŠãã ããã ãšã³ãžãã¢å€§åéäž Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ ãªããŒãžã¥èšäº ãäžè©±ã«ãªããŸãããããããšãããããŸãã 3æ¥éã¯ããã³ã°ãKubernetes ã®ã©ãºããªãŒãã€å
ã¿ãâãµã€ããŒãšãŒãžã§ã³ã颚âã https://developers.cyberagent.co.jp/blog/archives/14721/
SREããŒã ãããšã³ãžãã¢ã®é¿ä¹
接ã§ãã ä»åã¯Nginxã®403 Forbiddenã衚瀺ãããæã®ãã§ãã¯ãã€ã³ãã«ã€ããŠèšäºã«ããããšæããŸãã ç°å¢ Vagrant 1.9.5 CentOS Linux release 7.1.1503 (Core) Nginx 1.14.0 åæ èšå®ãã¡ã€ã« ã/etc/nginx/default.conf DocumentRoot ã/var/hoge ãã¹ãããŒãž ã/var/hoge/index.html äºè±¡ ãã¹ãããŒãžã衚瀺ããããšãããš403 Forbiddenã衚瀺ãããã ãã§ãã¯ãã€ã³ã â Nginxã®åèµ·åãããŠããªã èšå®ãã¡ã€ã«ã倿Žããå ŽåãNginxãåèµ·åããªããšå€æŽãåæ ãããŸããã ãã®ããåèµ·åããŠããªãå Žåã¯å®æœããŸãã â åèµ·å $ sudo systemctl restart nginx.service â ãªããŒã Nginxãçµäºããã«ã倿Žããèšå®ã®åæ ãè¡ããŸãã $ sudo systemctl reload nginx.service â¡ãã¡ã€ã«ã«èªã¿åãæš©éããªã æš©éã«ã¯ãææè
ããææã°ã«ãŒããããã®ä»ã®ãŠãŒã¶ãããããŸãããããã®ä»ã®ãŠãŒã¶ãã«èªã¿åãæš©ïŒrïŒãä»äžãããŠããã確èªããŠãã ããã â»ä»åã®å Žåã ãšã/var/hoge/index.html ã®æš©éã«ãªããŸãã â ãã®ä»ã®ãŠãŒã¶ã«èªã¿åãæš©ããªãå Žå $ ls -l /var/hoge/index.html -rw-r----- 1 root root 9 Jun 1 08:14 index.html â å¯Ÿå¿ ãã¡ã€ã«ã«èªã¿åãæš©ãä»äžããŸãã $ sudo chmod o+r /var/hoge/index.html $ ls -l /var/hoge/index.html -rw-r--r--. 1 root root 9 Jun 1 08:14 /var/hoge/index.html â¢ãã£ã¬ã¯ããªã®æš©éã«å®è¡æš©ããªã DocumentRootãŸã§ã®åãã£ã¬ã¯ããªã§ãããã®ä»ã®ãŠãŒã¶ãã«å®è¡æš©ïŒxïŒãä»äžãããŠããã確èªããŠãã ããã ä»åã ãšã/ã, ã/varã, ã/var/hogeãã®3ã€ã®å
ã®ããããã«ãã£ã¬ã¯ããªã«å®è¡æš©ïŒxïŒããªããšããã¹ãããŒãžã衚瀺ãããŸããã â /var/hoge/ ã«å®è¡æš©ããªãå Žå $ ls -ld /var/hoge/ drwxr-xr--. 2 root root 23 Jun 1 08:14 /var/hoge/ â å¯Ÿå¿ ãã£ã¬ã¯ããªã«å®è¡æš©ãä»äžããã $ sudo chmod o+x /var/hoge $ ls -ld /var/hoge drwxr-xr-x. 2 root root 23 Jun 1 08:14 /var/hoge/ â£ç¹å®ã®URLãžã®ã¢ã¯ã»ã¹å¶éããŠããŸã£ãŠãã Nginxã§ç¹å®ã®URLãžã®ã¢ã¯ã»ã¹å¶éãããå Žåãconfãã¡ã€ã«ã®locationå
ã«èšè¿°ããŸãã locationå
ã§ã¢ã¯ã»ã¹ãæåŠããŠããªãã確èªããŠã¿ãŠãã ããã â ãã¹ãŠã®ã¢ã¯ã»ã¹ãæåŠããå Žå $ cat /etc/nginx/conf.d/default.conf ... location / { root /var/hoge; index index.html index.htm; deny all; # å
šãŠã®ã¢ã¯ã»ã¹ãæåŠ } ... äžèšã®ããã«ãdeny all;ããšèšè¿°ãããšãã©ãããã§ãã¢ã¯ã»ã¹äžå¯ãšãªã£ãŠããŸããã¹ãããŒãžã衚瀺ãããŸããã ãã®ãã以äžã®ãããªæ¹æ³ã§ãã¹ãããŒãžãžã®ã¢ã¯ã»ã¹ãèš±å¯ããããšãã§ããŸãã â ãã¹ãŠã®ã¢ã¯ã»ã¹ãèš±å¯ããå Žå ... location / { root /var/hoge; index index.html index.htm; allow all; # å
šãŠã®ã¢ã¯ã»ã¹ãèš±å¯ } ... â ç¹å®ã®IPã®ã¿ã¢ã¯ã»ã¹ãèš±å¯ããå Žå ... location / { root /var/hoge; index index.html index.htm; allow 192.168.33.1; # ç¹å®ã®IPã®ã¿ã¢ã¯ã»ã¹ãèš±å¯ deny all; } ... äžèšã®æžãæ¹ã ãš 192.168.33.1 ããã®ã¢ã¯ã»ã¹ã®ã¿èš±å¯ããŠããŸãã â€SELinuxãæå¹ã«ãªã£ãŠãã SELinuxãæå¹ã«ãªã£ãŠããå ŽåãDocumentRootãžã®ã¢ã¯ã»ã¹ãæåŠãããŠããå¯èœæ§ããããŸãã SELinuxãå©çšããäºå®ããªãå Žåã¯ç¡å¹ã«èšå®ããŸãããã â€-1. SELinuxãç¡å¹ã«ããå Žå â SELinuxã®ç¶æ
ç¢ºèª $ getenforce Enforcing Enforcingãšè¡šç€ºãããå ŽåãSELinuxã¯æå¹ã«ãªã£ãŠããç¶æ
ã§ãã â SELinuxãç¡å¹ã«ãã SELinuxã®èšå®ãã¡ã€ã«ã¯ /etc/selinux/config ã«ãªãããããã¡ããç·šéããŸãã $ sudo vi /etc/selinux/config ... SELINUX=disabled ← enforcing ãã disabled ã«å€æŽ ... â ãµãŒãåèµ·å SELinuxã®èšå®ãåæ ããããã«ãµãŒãã®åèµ·åãè¡ããŸãã $ sudo shutdown -r now â SELinuxã®ç¶æ
ãååºŠç¢ºèª $ getenforce Disabled Disabledãšè¡šç€ºãããã°ãSELinuxã¯ç¡å¹ã«å€æŽãããŠããŸãã â€-2. SELinuxãæå¹ã®ãŸãŸéçšããå Žå æ°ããDocumentRootã«ã¯SELinuxã®ã©ãã«ãä»ããå¿
èŠããããŸãã â å
DocumentRootã®ã©ãã«ãç¢ºèª $ ls -ld --context /usr/share/nginx/html drwxr-xr-x. root root system_u:object_r:usr_t:s0 /usr/share/nginx/html â ã©ãã«ã®ä»äž æ°DocumentRootã«å
DocumentRootãšåãã©ãã«ãä»äžããŸãã $ sudo chcon system_u:object_r:usr_t:s0 /var/hoge -R â ã©ãã«ã®ç¢ºèª 以äžã®ããã«è¡šç€ºãããŠããã°ãå
DocumentRootãšåãã©ãã«ãä»äžãããŠããŸãã $ ls -ld --context /var/hoge drwxr-xr-x. root root system_u:object_r:usr_t:s0 /var/hoge ãŸãšã ä»åã¯Nginxã§403 Forbiddenã衚瀺ãããæã®ãã§ãã¯ãã€ã³ããèšäºã«ãããŠããã ããŸããã 以åApacheã§ã403ãšã©ãŒã®å£ã«ã¶ã¡åœãã£ãããšãããã®ã§ãããNginxã§ã403ãšã©ãŒã®å£ã«é»ãŸããŠããŸããŸãã…NginxãApacheãšäŒŒãŠããŠããã¡ã€ã«ããã£ã¬ã¯ããªã®æš©éåšããSELinuxãèŠçŽãã°403ãšã©ãŒã¯è§£æ¶ã§ããããšãããããŸããã ãã²åèã«ããŠããã ãããšå¹žãã§ãã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ãSREããŒã ããšã³ãžãã¢ã®è¥¿èïŒ@yasuhiro1711ïŒã§ãã仿¥ã¯ãcircleci/go-ecs-ecrã䜿ã£ãŠãCircleCI ããECS ã«ãããã€ãããŠã¿ãããšæããŸããïŒåèãªã³ã¯ã«ã¯éåžžã«ãäžè©±ã«ãªããŸãããããããšãããããŸããïŒ ä»åã¯é¡æã«ã¡ããã©åããCircleCIãéããŠãAWS ECS/ECR ã«ãããã€ããGoã¢ããªã±ãŒã·ã§ã³ããã£ãã®ã§ãããå©çšããŠãããŸããå匷ã®é¡æã«ãšãŠãããã£ãã§ããïŒãããæ³šæãšããŠãä»åå©çšã®ãcircleci/go-ecs-ecrãã¯ã2018幎6æçŸåšããã§ã«æŽæ°ãããŠããªããããçŸåšã®CircleCIãšAWSç°å¢ã«èªåã§åãããªããšåäœã§ããªãå¯èœæ§ããããŸãããæ³šæãã ãããïŒ circleci/go-ecs-ecr: Example project for deploying a Go application to AWS ECS/ECR via CircleCI. [https://github.com/circleci/go-ecs-ecr](https://github.com/circleci/go-ecs-ecr) æçµçã«ç®æãã®ã¯ãã®ãããªèšèšã§ããïŒECSã¯ã©ã¹ã¿éšåã¯å³ãšããŠã¯è©³çްã«ã¯æžããŠãããŸãããïŒ ä»åã®æ§æã§ã¯ãGitHubã«ãŠãŒã¶ããpushãããããšãCircleCIããããèªåæ€ç¥ããbuildå®è¡ãå§ããŸãããããšææ°ã®ãœãŒã¹ãECRã®ã¬ãžã¹ããªã«ç»é²ãããŠãECSã«ãŠå®çŸ©æŽæ°çãèµ°ããEC2å
ã®Dockerã³ã³ããã«ãããã€ãããä»çµã¿ã§ãã äºåæºå ãããã¯äºåã«æºåããŠãããŸããããä»åã¯è©³çްã¯è§ŠããŸããã GitHubã¢ã«ãŠã³ã CircleCIïŒGitHub飿ºïŒã¢ã«ãŠã³ã AWS Credentials ããŒã«ã«Mac端æ«ã«ãŠaws cliã³ãã³ãå°å
¥æžã¿ã§ããããš circleci/go-ecs-ecræºå æ©éå§ããŸããããzipããŠã³ããŒããforkããŠããŸãã GitHubäžã§ããããããŠãforkããŸãã ãœãŒã¹ã®äžèº«ãèŠãŠã¿ãŸããæ³šæãšããŠã¯ããã®ãŸãŸã ãšãªãŒãžã§ã³ãå
šãŠããŒãžãã¢ã«ãªãã®ã§ãæ±äº¬ã«å
šéšå€æŽããŠããŸããŸãããã 察象ãã¡ã€ã«ïŒcircle.yml ãdeploy.sh 倿Žç¹ïŒããŒãžã㢠(us-east-1) ãããæ±äº¬ (ap-northeast-1) ã«å€æŽããã AWSã®ECRãµãŒãã¹ã«ãªããžããªãäœæ ECR ã« go-sample-webapp ãšããååã§ãªããžããªãäœæããŠãããŸããååã¯ä»åå©çšã®ã¢ããªã±ãŒã·ã§ã³ãšæããŸãã äžèЧããããªããžããªã®äœæãéžæããŸãã ãªããžããªåãèšå®ããŸãã ãªããžããªã®äœæå®äº å®äºãããšãECRãžã®æ¥ç¶æ¹æ³ãããã§è©³ãã衚瀺ãããŸããïŒããã¯åŸããã§ãåç
§ã§ããŸãã®ã§ã倧äžå€«ã§ããïŒ docker-login ã€ã¥ããŠãdocker-pushã®æã«ãã°ã€ã³ãä¿ããããããaws ecr get-login ã³ãã³ãã§ïŒECR ã«ãã°ã€ã³ã§ããããšã確èªããŠãããŸããïŒã¡ãããšã¿ãŠãªãã§ãããä»åã®å Žåã¯å®ã¯ãããªããããããªããïŒ ããŒã«ã«MACã«ãŠã $ $(aws ecr get-login --region ap-northeast-1) 宿œãããšããšã©ãŒãçºçã察å¿ããŸãã以äžãåå ã§ããã å°ãã¿1 å€ãªeãåºåããããããããåèã«ããŠã ãå°ãã¿ãDocker17.06以äžããAmazon ECRãžã®dockerãã°ã€ã³ã³ãã³ããå€ãã£ã dockerã17.06以äžã ãšã –no-include-email ãªãã·ã§ã³ãå¿
èŠãªã®ã ããã $(aws ecr get-login –region ap-northeast-1 –no-include-email) ããã«å€æŽããããšã§ç¡äºã«å®è¡ã ãããŠããäžã€ã å°ãã¿2 ããŒã«ã«macã§ãDockerèµ·åããŠãªããšã以äžã®ãããªãšã©ãŒã«ãªãããããŸã«å¿ããã®ã§ã bash-3.2# $(aws ecr get-login --region ap-northeast-1 --no-include-email) WARNING! Using --password via the CLI is insecure. Use --password-stdin. Warning: failed to get default registry endpoint from daemon (Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?). Using system default: https://index.docker.io/v1/ Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? ãšããããã§ã $(aws ecr get-login --region ap-northeast-1 --no-include-email) ã§å®è¡ã å®è¡å±¥æŽ bash-3.2# $(aws ecr get-login --region ap-northeast-1 --no-include-email) WARNING! Using --password via the CLI is insecure. Use --password-stdin. Login Succeeded ECS ã§ä»®ã®ã¿ã¹ã¯å®çŸ©ãäœæ CircleCIã§å®è¡ããbuildã§ãèªåçã«ECSã®ãã¿ã¹ã¯å®çŸ©ããäœæãããããã«ãããããããã§ã¯ ECSã¯ã©ã¹ã¿ãèµ·åããããã ãã«ä»®ã®ã¿ã¹ã¯å®çŸ©ãäœæããŠãããŸãã ã¿ã¹ã¯å®çŸ©ã«ãŠããæ°ããã¿ã¹ã¯å®çŸ©ã®äœæããéžæãã åå㯠sample-webapp-task ãšããŠãããŸãã â»ã³ã³ããå®çŸ©ãä»åã¯ä»®ã§é©åœã«å
¥ããŠé²ããŸã 次㫠ECSã¯ã©ã¹ã¿ãš ECSãµãŒãã¹ãäœæããŠãããŸãã ECSã¯ã©ã¹ã¿ãäœæ ãŸãã¯ãECSã¯ã©ã¹ã¿ãäœæããŸãããã ã¯ã©ã¹ã¿ãŒã®äœæããéžæã ãã³ãã¬ãŒãéžãã§ã ä»åã¯ä»¥äžã®é
ç®ã§èšå®ããŸããã ã¯ã©ã¹ã¿å : sample-webapp-cluster ã€ã³ã¹ã¿ã³ã¹ã¿ã€ããïŒãt2.micro ã€ã³ã¹ã¿ã³ã¹æ°ãïŒã3 ãããã¯ãŒã¯ãïŒ æ¢åVPCãå©çš ã»ãã¥ãªãã£ãïŒ TCP 80ãIPå¶éãããŠè§£æŸ ã³ã³ããã€ã³ã¹ã¿ã³ã¹ IAM ããŒã«ãïŒãããã©ã«ã äœæå®äºïŒ ç¶ããŠãECSãµãŒãã¹ã®äœæã«åãæãããŸãã ECSãµãŒãã¹äœæ äœæããã¯ã©ã¹ã¿ãŒã«å
¥ã£ãŠããµãŒãã¹ã¿ãã§ããäœæã ãããªæãã§èšå®ããŸãã ãµãŒãã¹å : sample-webapp-service ã¿ã¹ã¯å®çŸ©å : sample-webapp-task-familyïŒèªåçã«ãããã€ãããã®ã§èšå®ã¯ãªããïŒ Desired Count ïŒ 1 æå°ãã«ã¹ç ïŒ ããã©ã«ã æå€§ç ïŒ ããã©ã«ã ELBãïŒãããªã autoscalling : ãªã ç»åãšæ°å€ãéããŸããããã®ç»é¢ã§ãã äœæãå®äºãããšããã®ãããªç»é¢ã«é·ç§»ããŸãã CircleCI ã®èšå® ç¶ããŠãCircleCIã§ã®äœæ¥ã§ããéåžžãåããŠå©çšããå Žåã¯CircleCIãšGithubã®é£æºãããªããšãããŸããããä»åã¯çããŸããŠããããžã§ã¯ãã®è¿œå ããã§ãã project ã远å Add Projectsãéžæ ä»åã®projectã§ããSet up Projectããã¿ã³ãã¯ãªãã¯ããŠãprojectã®èšå®ã«é²ã¿ãŸã â» ä»ã¯CicleCIãversion2.0ãã«ãªã£ãŠããã®ã§ããã®ç»é¢ã§ã¯ã2.0ãä¿ããŠããŸãã 2.0ã«ãããå Žåã¯ããã§ãã®æé ã®ããã«ã2.0ã®æžãæ¹ã«ymlã倿Žããå¿
èŠããããŸããïŒ ããã§ãããžã§ã¯ãã¯ç»é²å®äºã§ãããã®ãŸãŸbuildããããã©ã远å èšå®ãå¿
èŠã§ãã å©çšIAMãŠãŒã¶ãžæš©éä»äžïŒäœæ¥ã¯AWSïŒ CircleCIçšã® IAM User ãäœæããŸãã ä»åã¯ãæ¢åã¢ã«ãŠã³ããå©çšããŸããããå©çšãŠãŒã¶ã«ä»¥äžæš©éãã¢ã¿ããããŸãã AmazonEC2ContainerRegistryFullAccess AmazonEC2ContainerServiceFullAccess Environment Variables ã«ç°å¢å€æ°ãèšå® 以äžã®ç°å¢å€æ°ãèšå®ããŸãã AWS_ACCOUNT_ID xxxxxxxx AWS_ACCESS_KEY_ID xxxxxxxx AWS_SECRET_ACCESS_KEY xxxxxxxx å·Šã¡ãã¥ãŒããinsightsãéžæããä»åã®ãããžã§ã¯ãã®æ¯è»ãã¿ã³ãæŒãã ã¡ãã¥ãŒããç°å¢å€æ°èšå®ãéžã³ãèšå®ã èšå®ããããbuildãèµ°ãããŸãã ãïŒ deploy.sh ã®äžèšã§æ¢ãŸããŸããã 確èªããŠã¿ãŠã æçµçã«ã $(aws ecr get-login --region ap-northeast-1 --no-include-email) ã®èšè¿°ãã $(aws ecr get-login --region ap-northeast-1) ã«å€æŽããããšã§è§£æ±ºããŸãããããŒãããªãã»ã©ã§ãã ãã®çµæ ãã«ãæå ãããã€ãããèµ·åããã¢ããªã®IPã«æ¥ç¶ãããšãç¡äºã«ããHello World!ãã®è¡šç€ºã確èªã§ããŸãã ããã§ãäžé£ã®èšå®ãåºæ¥ãŸããããã£ãããªã®ã§ãã®ãŸãŸãã¢ããªãç·šéããŠã®åãããã€ããŠã¿ãŸãããã ç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ããŠã¿ã ã¢ããªã®åºåããHello World!ããããHello World! weddingparkããšå€æŽããŸããïŒHello World!ã®æåååºåéšåã¯buildã®æã®testã§ãå©çšããŠããã®ã§å€æŽã«ã¯æ°ãã€ããŸããããïŒ ä»åã¯ãã¹ããªã®ã§ãGitHubäžã§ä¿®æ£ããŠpushããŸãããããšãèªåã§CircleCIãããã¯ããbuildãéå§ãããããã€ãŸã§ãããŠãã æåïŒ ç°¡åã«ã¢ããªä¿®æ£ãããªãªãŒã¹ãŸã§ãèªåã§å®è¡ã§ããŸããã ãããã€ã®ä»çµã¿ ä»åã®ä»çµã¿ã§å€§äºãªã®ã¯ãCircleCIåãã®èšå®ãšãdeploy.sh ã®èšå®ã§ããããããã©ããªããšãããŠããã®ããç°¡åã«èŠãŠèŠãŸãã circle.yml docker build ãå®è¡ããŠãDockerã€ã¡ãŒãžãäœæã ãã¹ãã§ã¯ docker runã§ã³ã³ãããå®è¡ãèµ·åãã¢ããªã®èµ·åã確èªããã masterãã©ã³ãã«pushãããå Žåã«ã¯ deploy.sh ãå®è¡ããã deploy.sh AWS CLI ã®èšå®ããã ECR ã« Dockerã€ã¡ãŒãžãpushãã ã¿ã¹ã¯å®çŸ©ã®ãªããžã§ã³ãæŽæ°ãææ°ã®Dockerã€ã¡ãŒãžããµãŒãã¹ã«åæ ãµãŒãã¹ã«çŽä»ãã¿ã¹ã¯å®çŸ©ãæŽæ°ã㊠ECSã¯ã©ã¹ã¿ãŒã«ãããã€ããã ãšã³ãžãã¢å€§åéäž Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ ãšãŠããäžè©±ã«ãªã£ãåèãµã€ã CircleCI ã§ ECS ã«ãããã€ããããµã³ãã«ãããžã§ã¯ã circleci/go-ecs-ecr ã詊ãã – kakakakakku blog CircleCI+ECS+ECRç°å¢ã§Dockerã³ã³ããã®CD(ç¶ç¶çãããã€)ç°å¢ãæ§ç¯ãã -åŸç·š- ïœ Developers.IO
ããã«ã¡ã¯ãQAããŒã ã§ãããŒãžã£ãŒãããŠãããšã³ãžãã¢ã®æè€ïŒ@saik1010ïŒã§ãã åŒç€ŸQAããŒã ã§å質åäžãç®çãšããŠåãçµãã§ããã Python ã® Webã¹ã¯ã¬ã€ãã³ã° ã䜿çšããèªåãªã³ã¯ãã§ãã«ãŒïŒHTTPã¹ããŒã¿ã¹ã³ãŒãã®ãã§ãã¯ïŒã«ã€ããŠã ç°å¢æ§ç¯ãå®éã«ãªã³ã¯ãã§ãã¯ãå®è¡ãããšãããŸã§ã玹ä»ããããšæããŸãã ç°å¢ ç°å¢ ããŒãžã§ã³ macOS Sierra 10.12.6 Python 3.6.4 pyenv 1.2.1 1. Pythonã®ã€ã³ã¹ããŒã« Homebrew ã䜿çšããPython3ãã€ã³ã¹ããŒã«ããŸãã æ±çšæ§ã®èããŠãããŒãžã§ã³åãæ¿ãã容æã«ã§ãã pyenv ã䜿çšããŸãã pyenvã®ã€ã³ã¹ããŒã« $ brew install pyenv ã€ã³ã¹ããŒã«ãããpythonã®ããŒãžã§ã³ãç¢ºèª $ pyenv install --list pythonãã€ã³ã¹ããŒã« $ pyenv install 3.6.4 pythonã®ããŒãžã§ã³å€æŽ $ pyenv global 3.6.4 PATHãéã $ vi ~/.bash_profile â远èšãã export PATH="$HOME/.pyenv/shims:$PATH" èšå®ãåæ ãã $ source ~/.bash_profile 2. Pythonã©ã€ãã©ãªã®ã€ã³ã¹ããŒã« requests HTTPéä¿¡ãè¡ãããã®ã©ã€ãã©ãªã§ãã http://requests-docs-ja.readthedocs.io/en/latest/ $ pip install requests BeautifulSoup HTMLãXMLãã¡ã€ã«ããããŒã¿ãåãåºãããã®ã©ã€ãã©ãªã§ãã https://www.crummy.com/software/BeautifulSoup/bs4/doc/ $ pip install beautifulsoup4 3. HTTPã¹ããŒã¿ã¹ã³ãŒãã®ãã§ã㯠ã€ã³ã¹ããŒã«ããã©ã€ãã©ãªãå©çšããŠãHTTPã¹ããŒã¿ã¹ã³ãŒããå®è£
ããŸãã ãŸãã¯Pythonãã¡ã€ã«ãäœæãã以äžã®ã³ãŒããæžããŸãããã â»ç§ã¯ã test.py ãšããŸãã ãœãŒã¹ã³ãŒã import requests from bs4 import BeautifulSoup # ã¢ã¯ã»ã¹ããURL resp = requests.get("https://www.google.co.jp/") # BeauttifulSoupã䜿çšããŠHTMLæŽåœ¢ soup = BeautifulSoup(resp.text, 'html.parser') # aã¿ã°ããURLãååŸããHTTPãªã¯ãšã¹ããéã for link in soup.find_all('a'): # URLãååŸããHTTPãªã¯ãšã¹ã url = link.get('href') if url is None: continue elif url == '#': continue resp = requests.get(url) # çµæãCSVã«åºåãã f = open('test.csv','a') f.write(str(resp.status_code) + ',' + url + '\n') f.close() å®è¡ãã $ python test.py å®è¡çµæ äžèšå
容ã test.csv ã«åºåãããŠããã°OKã§ãã 200,https://www.google.co.jp/imghp?hl=ja&tab=wi 200,https://www.youtube.com/?gl=JP&tab=w1 200,https://www.google.co.jp/intl/ja/options/ 200,http://www.google.co.jp/history/optout?hl=ja 200,https://accounts.google.com/ServiceLogin?hl=ja&passive=true&continue=https://www.google.co.jp/ 200,http://www.google.co.jp/intl/ja/services/ 200,https://www.google.co.jp/setprefdomain?prefdom=US&sig=__0sQtcCi2TjmCTGxrJwKLaSvy39U%3D ãŸãšã ãããã§ããã§ããããïŒ ããªãã·ã³ãã«ã«HTTPã¹ããŒã¿ã¹ã³ãŒããã§ãã¯ã®å®è£
ãã§ããŸããïŒ HTMLã«ããèŠçŽ ã¯ãªãã§ãååŸã§ããããªã®ã§ãã¹ããŒã¿ã¹ã³ãŒã以å€ã«ãå¹
åºã䜿ãããã§ããæ¬¡åã¯ååž°åŠçãå©çšããŠããªã³ã¯ãæ·±æãããå®è£
ãããŠããããšæããŸãïŒ âçè
å·çã®ã5åã§ã§ããèªååãã·ãªãŒãº 5åã§ã§ããïŒSeleniumã§ãã©ãŠã¶ãã¹ãèªååå
¥é Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ãSREããŒã ã€ã³ãã©ãšã³ãžãã¢ã®ç¶¿åŒã§ãã 2018/4/24 ã« Node.js 10ç³»ããªãªãŒã¹ãããŸãããã ïŒç§ã®èªçæ¥ã§ããïŒ ããã§ä»å㯠Node.js ã®ã¢ããããŒãã Ansible ãçšããŠå®æœãã ãšããèšäºãæžããããšæããŸãã Node.js ã®ã¢ããããŒãæ¹æ³ã«é¢ããŠã¯ã 1. æ¢åã® Node.jsïŒéå»ã« yum ã§ã€ã³ã¹ããŒã«ïŒãã¢ã³ã€ã³ã¹ããŒã«åŸã 2. Ansible ã® shell ã¢ãžã¥ãŒã« ãçšã Node.js ã rpm ã§ã€ã³ã¹ããŒã«ãã ãšãã圢ã«ããŸããã 10 ç³»ã䜿ããã®ã® Node.js ã«é¢ããŠã®æ§èœãæ°æ©èœãªã©ã®æ€èšŒã¯è¡ããªãã®ã§ ã容赊ã®ã»ã©ããé¡ãèŽããŸãã Node.js ã®ããŒãžã§ã³ã«ã€ã㊠ãŸã Node.js ã®ããŒãžã§ã³ã«é¢ããŠã§ããã ä»å 10ç³»ãã€ã³ã¹ããŒã«ããã«ããã£ãŠ LTS ãªã©ã®çšèªãããäžåºŠèª¿ã¹çŽããŠã¿ãŸããã LTS (Long Term Support) Node.js ã®ã¡ãžã£ãŒããŒãžã§ã³ïŒ6.X ã8.X ãªã©ïŒã¯å€§ããåããŠå¶æ°ãšå¥æ°ã«åããããŸãã å¶æ° ã LTSç ãšåŒã°ããããµããŒã(â»1)ãé·æã«åãããããã®ã§ã 奿° ãææ°æ©èœçã§ããµããŒãæéã LTSçã«æ¯ã¹ããšéåžžã«çããªã£ãŠãããŸãã â»1 ⊠ãã°ã®ä¿®æ£ãã»ãã¥ãªãã£ã¢ããããŒã ãªãªãŒã¹ã¹ããŒã¿ã¹ ãªãªãŒã¹ã¹ããŒã¿ã¹ ã» åã¹ããŒã¿ã¹ã®æéãªã©ã«é¢ããŠã¯ã Github ã«ãŠå
¬éãããŠãã以äžãã確èªé ãã®ãæãæ©ããšæãã®ã§ã ãªã³ã¯ãèŒããŠãããŸãã https://github.com/nodejs/Release å ã¿ã«ç§ãªãã«ãŸãšãããšãã Node.js ã®ãªãªãŒã¹ã¹ããŒã¿ã¹ãšããŠã以äžã®3ã€ãååšããŸãã ã»CURRENT ã»ACTIVE LTS ã»MAINTENANCE LTS ãªãªãŒã¹ããããšã LTSçã奿°çãã©ã¡ããã¹ããŒã¿ã¹ãšããŠã¯ãCURRENTãã«ãªãããã®åŸLTSçã®ã¿ã é·æãµããŒãæéã§ãã ãACTIVE LTSãã»ãMAINTENANCE LTSã ã¹ããŒã¿ã¹ã«ç§»è¡ããŸãã 奿°çã«é¢ããŠã¯ããCURRENTããçµäºããæç¹ã§ãµããŒããçµäºããä»çµã¿ã®ããã§ãã ããããã®æéã«é¢ããŠã¯ã ãCURRENTã ã çŽ6ã¶æ ããActiveã ã 18ã¶æ ããMaintenanceã ã 12ã¶æ ãšãªã£ãŠããããã§ãã äžèšãå
šãŠãŸãšãããšä»¥äžã§ãã ãªãªãŒã¹ã¹ããŒã¿ã¹ å
容 æé CURRENT ãçŸåšã®ææ°çã çŽ6ã¶æ ACTIVE LTS ããµããŒããç©æ¥µçã«è¡ãããã 18ã¶æ MAINTENANCE LTS ãæäœéã®ãµããŒããè¡ãããã 12ã¶æ æåŸã« Node.js 10ç³» ã®ãµããŒãæé ã«é¢ããŠã§ããã LTSçãªã®ã§ä»¥äžã®ããã«ãªããŸãã Node.js 10ç³» ã® ãªãªãŒã¹ã¹ããŒã¿ã¹ æé CURRENT 2018/4 ã 2018/10 Active LTS 2018/10 ã 2020/4 Maintenance LTS 2020/4 ã 2021/4 ãã¡ãåèã«ããŠé ããã幞ãã§ãã ç°å¢ ã§ã¯ Node.js ã«ã詳ãããªã£ããšããã§ãæ©éæ§ç¯ããŠããŸãã ç°å¢ã«é¢ããŠã¯ ãµãŒã 1å°ãã¯ã©ã€ã¢ã³ã 2å°ãšããŠãã OS 㯠CentOS 6ã7 ã©ã¡ãã䜿çšãã圢ã§é²ããŠè¡ããããšæããŸãã ç°å¢æ
å ±ã®è©³çްã¯ä»¥äžã§ãã ããŒã«ã« ã»macOS 10.13.3 ã»Vagrant 2.0.3 ãµãŒã (1å°) ã»ãã¹ãå ans ã»CentOS 7.1 ã»Ansible 2.4.2.0 ã¯ã©ã€ã¢ã³ã (2å°) 1å°ç® ã»ãã¹ãå anc ã»CentOS 7.1 ã»Node.js 6.8.1 ïŒéå»ã« yum ã§å
¥ããŠãããŸãïŒ 2å°ç® ã»ãã¹ãå an6 ã»CentOS 6.5 ã»Node.js 6.8.1 ïŒéå»ã« yum ã§å
¥ããŠãããŸãïŒ â» ãã¹ãåã¯é©åœã«ã€ããã®ã§æ°ã«ããªãã§ãã ããã å³ã«ãããã®ãããªæãã§ãã Ansible èšå® Ansible ã®èšå®ã¯ä»¥äžãšãªããŸãã ãã£ã¬ã¯ããªæ§æ ãã£ã¬ã¯ããªæ§æã¯ä»¥äžã®ããã«ããŠãããŸãã ãã¹ããã©ã¯ãã£ã¹ ã«ãªãã£ãŠ ansible-playbook ãå®è¡ããéã¯ã ããããã¬ã€ããã¯ã§ãã node_version_up-YYYYMMDD.yml ãããã¯ãã åŠçèªäœã¯ãã®é
äžã®ãã£ã¬ã¯ããªã® Roles é
äžã§å¶åŸ¡ããŠãããŸãã /opt â ansible/ â node_version_up-YYYYMMDD.yml # ããããã¬ã€ãã㯠â hosts # ã€ã³ãã³ããªãã¡ã€ã« â playbook/ â nodejs_version_up.yml # ããããã¬ã€ããã¯ããèªã¿èŸŒããã¬ã€ãã㯠â nodejs_version_up/ # Roles â tasks â main.yml node_version_up-YYYYMMDD.ymlïŒããããã¬ã€ããã¯ïŒ ããããã¬ã€ããã¯ã®äžèº«ãšããŠã¯ nodejs_version_up.yml ãèªã¿èŸŒãã ãã«ãªã£ãŠãããŸãã --- - include: playbook/nodejs_version_up.yml hostsïŒã€ã³ãã³ããªãã¡ã€ã«ïŒ ã€ã³ãã³ããªãã¡ã€ã«ã«ã¯ãã¯ã©ã€ã¢ã³ã2å°ã an_clients ãšããã°ã«ãŒããšããŠèšå®èŽããŸããã [an_clients] anc an6 nodejs_version_up.yml ïŒããããã¬ã€ããã¯ããèªã¿èŸŒããã¬ã€ããã¯ïŒ ãã¡ã㯠roles ãçšãã nodejs_version_up ãã£ã¬ã¯ããªé
äžã®ãã¡ã€ã«ãå®è¡ãã圢ã«ãªã£ãŠããŸãã # /opt/ansible/playbook/nodejs_version_up.yml - hosts: an_clients remote_user: vagrant become: yes roles: - nodejs_version_up main.yml tasks ãã£ã¬ã¯ããªé
äžã®å®è¡ãã¡ã€ã«ã§ãã åŠçèªäœã¯éåžžã«ç°¡åã§ããã®ã§ãã·ã³ãã«ãªäœããšããŠãããŸãã äžèº«ã«é¢ããŠã¯åé ã§ãèšèŒèŽããŸãããã äžåºŠãã¢ã³ã€ã³ã¹ããŒã«ã㊠rpm ã§ã€ã³ã¹ããŒã«ãã圢ããšã£ãŠãããŸãã # file: /opt/ansible/playbook/nodejs_version_up/tasks/main.yml - name: remove nodejs yum:ã name: nodejs state: absent - name: install nodejs 10.3.0 shell: rpm -Uvh https://rpm.nodesource.com//pub_10.x/el/6/x86_64/nodejs-10.3.0-1nodesource.x86_64.rpm å®è¡ ã§ã¯å®è¡ããŠè¡ããŸãã [vagrant@ans ~]$ cd /opt/ansible [vagrant@ans ansible]$ ansible-playbook -i hosts node_version_up-20180601.yml [DEPRECATION WARNING]: 'include' for playbook includes. You should use 'import_playbook' instead. This feature will be removed in version 2.8. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg. PLAY [an_clients] ************************************************************************************************************************************************************************************************************ TASK [Gathering Facts] ******************************************************************************************************************************************************************************************************* ok: [anc] ok: [an6] TASK [nodejs_version_up : remove nodejs] ************************************************************************************************************************************************************************************* ok: [anc] ok: [an6] TASK [nodejs_version_up : install nodejs 10.3.0] ***************************************************************************************************************************************************************************** [WARNING]: Consider using yum, dnf or zypper module rather than running rpm changed: [anc] changed: [an6] PLAY RECAP ******************************************************************************************************************************************************************************************************************* an6 : ok=3 changed=1 unreachable=0 failed=0 anc : ok=3 changed=1 unreachable=0 failed=0 ã§ã¯ç¢ºèªããŠãããŸãã ã¯ã©ã€ã¢ã³ã 1å°ç®ïŒCentOS7ïŒ ãã¡ãã¯åé¡ãªãããã§ãã [vagrant@anc ~]$ node -v v10.3.0 [vagrant@anc ~]$ [vagrant@anc ~]$ npm -v 6.1.0 ã¯ã©ã€ã¢ã³ã 2å°ç® ïŒCentOS6ïŒ ãã¡ãã倧äžå€«ããã§ããã [vagrant@an6 ~]$ node -v v10.3.0 [vagrant@an6 ~]$ [vagrant@an6 ~]$ npm -v 6.1.0 [vagrant@an6 ~]$ ãŸãšã Node.js ã Ansible ã§ã¢ããããŒãããæ
å ±ãããNode.js ã® LTS ã®æ
å ±ã®æ¹ã«åãå
¥ããŠããŸããŸããã Ansible ã«é¢ããŠã¯ã察象æ©èœã®ãã¬ã€ããã¯ãäžåäœã£ãŠããŸãã°ã ããšã¯äœ¿ãåãã ããªã®ã§éçšãéåžžã«æ¥œã«ãªããªã¹ã¹ã¡ã§ãã åŒãç¶ã Ansible ãæŽ»çšããŠãããããšæããŸããã ãã®åºŠã¯ããæž
芧é ãããããšãããããŸããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ãQAããŒã ã§ãããŒãžã£ãŒãããŠãããšã³ãžãã¢ã®æè€ïŒ@saik1010ïŒã§ãã ä»åã¯ãåŒç€Ÿãš ãŠããã¡æ ªåŒäŒç€Ÿ ããã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããŒã ã§éå¬ããååLTäŒïŒã©ã€ããã³ã°ããŒã¯ïŒã®æ§åãã¬ããŒãããããšæããŸãïŒ ååLTäŒã®ç®ç ä»ç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒãšã®äº€æµãæ
å ±åéãç®çãšããŠã3ã¶æãå幎ã«1åã®ã¹ãã³ã§ååLTäŒãéå¬ããŠãããŸããäºåã«ãäºãã®äŒç€Ÿã«èããŠã¿ããããšãæŠãåãããããŒãèšå®ãããäžã§é²ããŠãããŸããå€éšã®LTäŒãšã¯éãã2瀟ãšããã¯ããŒãºããªå Žãšããããšããããå°ãèžã¿èŸŒãã 話ãã§ãããšããç¹ããååLTäŒãªãã§ã¯ã®å€§ããªé
åã®1ã€ã§ãïŒ éå¬ã«è³ã£ãçµç·¯ åŒç€ŸQAããŒã ã¯ãä»å¹Žã®1æã«ç«ã¡äžãã£ãã°ããã®æ°ããããŒã ã®ãããæ
å ±åéãå
Œã㊠JaSST’18 Tokyo ã®ã€ãã³ãã«åå ããŸããããã®äžã®ïŒã€ã®ã»ãã·ã§ã³ã§ãã ãWeb.JaSST ïœãŠã§ãç³»QAãã¿ããªã®ãæ©ã¿ã«å
šåã§ææ¡ãè¿ãäŒïœã ã«ç»å£ãããŠãããŠããã¡ããã®QAãããŒãžã£ãŒã®æ¹ãšäº€æµããããŠé ããããšãããä»åã®ååLTäŒã宿œããã«è³ããŸããïŒ ããŒãèšå® ä»åã¯ããäºãã«ç¥ãããããšãäºåã«æã¡åãããçµæã以äžã®ããŒãã§LTäŒã宿œèŽããŸããã âŒãŠãšãã£ã³ã°ããŒã¯âãŠããã¡ ã»QAããŒã ãããçµç¹ã®éçºæ¹æ³ ã»èªåãã¹ãïŒãŠããããã¹ãïŒã®é²ãæ¹ âŒãŠããã¡âãŠãšãã£ã³ã°ããŒã¯ ã»ãµãŒãã¹ããªãã¬ã€ã¹ããæã®è©± ã»äºæ¥éšãåãããµãŒãã¹ã§éçºããŠãããšã³ãžãã¢ã®è©± åœæ¥ã®æ§å åœæ¥ã¯ç·åŒµãæ©ãã«ã»ãããŠããªã©ãã¯ã¹ããå Žã«ããããšããæå³ãããããã¢ããã·ã¥åœ¢åŒã§ä¹Ÿæ¯ããã¹ã¿ãŒãïŒãŸãã¯ãäºãã®äŒç€Ÿç޹ä»ãå
ŒããŠãäŒç€Ÿèª¬æã宿œããåŸã«LTçºè¡šãè¡ããŸããïŒ ãã®åŸã¯ããŒãã«æ²¿ã£ãŠããäºãã«LTçºè¡šã宿œããŸããïŒè³ªåãå€ãé£ã³äº€ããäºå®æéããªãŒãããŠããŸãã»ã©å€§çãäžããïŒ LTçºè¡šåŸã¯æèŠªäŒïŒåŒç€ŸåŽã®åå 人æ°ãå€ãããŠããã¡ãããå²ã£ãŠããŸã圢ã«ãªããŸããããæèŠªäŒã倧çãäžããã§æéããã£ãšããéã«ïŒ ãŸãšã ä»åã¯QAããŒã å士ã®ãçžããããååLTäŒãéå¬ããããšãã§ããŸããã ãäºãã«äºåã«ããŒãèšå®ããããšããããå€éšã®å匷äŒã§ã¯ãªããªãèããªããèžã¿èŸŒãã å
容ã®ã話ãããããšãã§ãã䞡瀟ã«ãšã£ãŠéåžžã«ææçŸ©ãªæéã«ãªããŸããïŒãã®å Žã§æ¬¡åãéå¬ããŸããããšã®å£°ãäžããã»ã©ïŒ ãŠããã¡ããããããšãããããŸããïŒïŒ è£è¶³ ãã¡ãã®å
容ã«ã€ããŠã¯ãåŒç€Ÿã® Wantedly ã§ã玹ä»ããŠãããŸãã®ã§ããããããã°ã芧ãã ããã ãŸãããŠããã¡ããã® æè¡ããã° ã Wantedly ã§ãã玹ä»ããŠé ããŠãããŸãã®ã§ãåãããŠã確èªãã ããïŒ â»åŒç€Ÿãšäžç·ã«ååLTäŒããã£ãŠã¿ãããšããäŒæ¥æ§ãããã£ããããŸããããæ¯éã声ããé ãããšå¬ããã§ãïŒ Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
åããŸããŠãSREããŒã ãšã³ãžãã¢ã®é¿ä¹
接ã§ãã ä»åã¯ä»äºã®äžç°ã§LinuC(LPIC) Level1ãååŸããããšã«ã€ããŠèšäºã«ããããšæããŸãã â»åéšããåœæã¯ãLPICããšããåç§°ã§ããããä»ã¯ãLinuCããšããåç§°ã«å€ãã£ãããã§ããã 1. LinuC(LPIC)ã«ã€ã㊠1-1. LinuC(LPIC)ãšã¯ Linuxæè¡ã蚌æããããã®è³æ Œè©Šéšã®äžã€ãæ£åŒåç§°ã¯ãLinux Professional Certificationãã§ãç¥ããŠããªããã¯ããšèªã¿ãŸãã 2016幎12ææç¹ã§ãå
šäžçã§53äžäººä»¥äžïŒåœå
ã ãšçŽ29äžäººïŒãåéšããŠã18äžäººä»¥äžã®èªå®è
ãçãŸããŠããè³æ Œãšã®ããšã§ãã åŒçš : LPI-JAPAN ãLPICã®é
åãããŒã¿ã§èŠãã 1-2. LinuC(LPIC)ã®çš®é¡(ã°ã¬ãŒã) LinuC(LPIC)ã«ã¯ä»¥äž3ã€ã®ã¬ãã«ãååšããŸãã â»ä»åã¯LinuC(LPIC) Level1ã®101詊éšãš102詊éšãåéšããŸãã 1-3. LinuC(LPIC) Level1åºé¡ç¯å² â 101è©Šéš ã·ã¹ãã ã¢ãŒããã¯ã㣠Linuxã®ã€ã³ã¹ããŒã«ãšããã±ãŒãžç®¡ç GNUãšUnixã®ã³ãã³ã ããã€ã¹ãLinuxãã¡ã€ã«ã·ã¹ãã ããã¡ã€ã«ã·ã¹ãã éå±€æšæº â 102è©Šéš ã·ã§ã«ãã¹ã¯ãªãããããã³ããŒã¿ç®¡ç ãŠãŒã¶ã€ã³ã¿ãŒãã§ã€ã¹ãšãã¹ã¯ããã ç®¡çæ¥å éèŠãªã·ã¹ãã ãµãŒãã¹ ãããã¯ãŒã¯ã®åºç€ ã»ãã¥ãªã㣠2. ååŒ·æ¹æ³ 2-1. LinuC(LPIC)ãšLinuxã«ã€ããŠç¥ã ãŸãæåã«LinuC(LPIC)ã詳ããç¥ãããã«å
¥éæžã賌å
¥ããŸããã â»è³Œå
¥ããæ¬ã¯ä»¥äžã«ãªããŸãã 1é±éã§LPICã®åºç€ãåŠã¹ãæ¬ ç¬¬2ç (åŸ¹åºæ»ç¥) ãã®å
¥éæžã¯LinuC(LPIC)ã®åéšæ¹æ³ãLinuxã®åºæ¬æäœã«ã€ããŠæžãããŠããå
容ã«ãªã£ãŠãŸãã LinuC(LPIC)ã詳ããç¥ããããLinuxã®åºç€ãåŠã³ãã人ã«ã¯ãªã¹ã¹ã¡ã§ãã 2-2. LinuC(LPIC)ã®è©Šéšåé¡ãè§£ããŠã¿ã å
¥éæžãããçšåºŠçè§£ã§ããããLinuC(LPIC) Level1ã®åé¡éã賌å
¥ããŸããã â»è³Œå
¥ããæ¬ã¯ä»¥äžã«ãªããŸãã Linuxæç§æž LPICã¬ãã«1 ã¹ããŒããã¹ã¿ãŒåé¡é ãã¡ãã®åé¡éã¯å®éã«LinuC(LPIC)ã®è©Šéšã«åºãåé¡ããŸãšããããŠããŸãã é£æåºŠçã«ã¯é£ããå
容ã§ããããååé¡ã®è§£èª¬ã詳ããæžãããŠããã®ã§çè§£ããããã£ãã§ãã ãŸãLinuC(LPIC) Level1ã®è©Šéšç¯å²ãå
šãŠç¶²çŸ
ããŠããã®ã§ãè²·ã£ãŠãããŠæã¯ãªããšæããŸãã 2-3. Ping-tã§ã²ãããåé¡ãè§£ã(â»è¶
éèŠ) Ping-t ã¯ãLinuC(LPIC)ãCCNAãªã©ã®è©Šéšå¯Ÿççšã®åŠç¿ãµã€ãã§ãã LinuC(LPIC)ã®è©Šéšã¯PCã䜿ãã®ã§ã Ping-t ã®WEBåé¡ãè§£ããŠãããšããã«å®å¿ã§ãã ãŸã101詊éšã®åé¡ã§ããã°ç¡æã§å©çšã§ããã®ã§ããããã§ãã â»102詊éšããã¯ææã«ãªããŸã 3. åéšæ¹æ³ãšçµæ 3-1. åéšæ¹æ³ ãã¢ãœã³VUE ãšãããµã€ãã§åéšã®äºçŽãã§ããŸãã 詊éšäŒå Žã¯ãã¹ãã»ã³ã¿ãŒã«ãªããŸãã 3-2. åéšçµæ 101詊éšã102詊éšãã©ã¡ããååã§åæ Œã§ããŸããã å®ã¯åéšåœæ¥ãŸã§éžæè¢åé¡ããåºé¡ãããªããšæã£ãŠããã®ã§ãããèšè¿°åé¡ãåºé¡ãããããšãç¥ã£ãŠããªããã³ãã£ãèšæ¶ããããŸãã ãããªéã¡ãç¯ããªãããã«ãPing-tã®ã³ãåïŒèšè¿°åé¡ïŒã¯è§£ããŠãããã»ããè¯ãã§ãã 4. ä»äºã§åœ¹ã«ç«ã£ãããš ã»Linuxã®åºç€çãªè©±ã¯çè§£ã§ãã ååŸããåã¯ãå
茩ãèšã£ãŠããããšãäŒè°ã§ã®æè¡çãªäŒè©±ãçè§£ã§ããŸããã§ããã äŸïŒ å
茩ãrootãŠãŒã¶ã«åãæ¿ããŠã¿ãŠã èªåãã…ïŒã ãããæ¬åœã«èŸã… ååŸããŠããã¯ãçµæ§è©±ã«ã€ããŠãããããã«ãªããŸããã ããšä»»ããŠããããä»äºã®é åãåºããããšãã§ããã®ã倧ããªãã€ã³ãã§ãã ã»èªä¿¡ãã€ã ååŸããåã¯ãïŒã€ã®ã³ãã³ãæã€ã ãã§ããã¯ãã¯ããŠããŸããã ããã®ã³ãã³ãæã£ãããµãŒãããŠã³ããªãã㪅ããšããããå®è¡ããŠå€§äžå€«ã㪅ããšãã ååŸããŠããã¯ãåºç€çãªã³ãã³ãã¯çè§£ã§ããŠããã®ã§èªä¿¡ãæã£ãŠã³ãã³ããå®è¡ã§ããŸãã æ£çŽãããäžçªå¬ããã£ãã§ãã 5. ãããã« ä»åã¯LinuC(LPIC) Level1ãååŸãã話ãèšäºã«ãããŠé ããŸããã LinuC(LPIC)ã¯Linuxã®åºç€ãããããããšãã§ããä»äºã«ã¯å¿
ã圹ã«ç«ã€ã®ã§ãªã¹ã¹ã¡ã§ãã æ¬¡ã¯Level2ãåŸ
ã£ãŠããã®ã§ãåŒãç¶ãé 匵ããŸãã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ITÃãã©ã€ãã«ã§æ¥çãå€ããïŒãããã§ãã·ã§ãã«ãªWEBãšã³ãžãã¢åéïŒ
ããã«ã¡ã¯ãSREããŒã ãšã³ãžãã¢ã®é¿ä¹
接ã§ãã ä»å㯠Redash ãš Superset ãšãã2ã€ã®ããŒã«ãæ¯èŒæ€èšŒããŠã¿ãŸããã®ã§ ããã«ã€ããŠèšäºã«ããããšæããŸãã ããŒã«ã«ã€ã㊠䞡è
ã¯ãªãŒãã³ãœãŒã¹ã®ããã·ã¥ããŒãããŒã«ã§ãã ç°¡åã«èšããšãDBçã®ããŒã¿ãå¯èŠåïŒè¡šãã°ã©ãïŒããŠãããããŒã«ã«ãªããŸãã â Redash å
¬åŒãµã€ã : https://redash.io/ â Superset å
¬åŒãµã€ã : https://superset.incubator.apache.org/index.html æ¯èŒããããš ããŒã¿ãœãŒã¹é£æº ããŒã¿æäœ ã°ã©ã ããã·ã¥ããŒã æ¯èŒãŸãšã 1. ããŒã¿ãœãŒã¹é£æº 1-1. Redash Typeãšããé
ç®ã®ãã«ããŠã³ããããŒã¿ãœãŒã¹ãéžæããŸãã éžæããããŒã¿ãœãŒã¹ã«ãã£ãŠå
¥åããé
ç®ãåãæ¿ããã®ã§ãããã«æ²¿ã£ãŠæ
å ±ãå
¥åããŸãã â»ä»¥äžã¯ããŒã¿ãœãŒã¹ãMySQLãéžãã å Žåã«ãªããŸã 飿ºã§ããããŒã¿ãœãŒã¹ã¯ä»¥äžã«ãªããŸãã 1-2. Superset Redashãšã¯äžå€ã㊠SQLAlchemy URI ãšããå
¥åé
ç®ããããèªåãæå
¥åããªããã°ãªããŸããã ãããçè§£ããã®ã« ããã¥ã¡ã³ã ãèŠãªããã°ãªããªãã£ãã®ã§ãæ£çŽå€§å€ã§ããã 飿ºã§ããããŒã¿ãœãŒã¹ã¯ SQLAlchemy ã察å¿ããŠãããã®ã«éããããªæ°ãããŸãã ããã¥ã¡ã³ããèŠããšã以äžã®ããŒã¿ãœãŒã¹ã¯é£æºã§ããããã§ãã ã»Firebird ã»Microsoft SQL Server ã»MySQL ã»Oracle ã»PostgreSQL ã»SQLite ã»Sybase Redashã®ã»ãã飿ºã§ããããŒã¿ãœãŒã¹ã¯å€ããã§ããã 2. ããŒã¿æäœ 2-1. Redash Redashã¯ã·ã³ãã«ã«SQLãæžãåæã§äœãããŠããŸãã åºæ¬çã«SQLãå®è¡ããŠãã®çµæãå¯èŠåïŒè¡šã»ã°ã©ãåïŒããæµãã«ãªããŸãã æ®æ®µæ¥åãªã©ã§SQLã䜿ã£ãŠããæ¹ã«ã¯éåžžã«äœ¿ãããããšæããŸããã ãã®åé¢SQLãè§Šã£ãããšããªãæ¹ã«ãšã£ãŠã¯ããŒãã«ãé«ãããªãšæããŸãã 2-2. Superset Supersetã¯SQLãæžããšãããããGUIããçŽæçã«æäœã§ããããã«äœãããŠããŸãã ãã®ããSQLãæžããããšããªãæ¹ã§ããæ¯èŒçã«è§ŠããããããªãšæããŸãã ãSQL Labããšããæ©èœã䜿ããšãSQLãæžãããšãã§ããã®ã§SQLçµéšè
ã§ã䜿ãããããšæããŸãã 3. ã°ã©ã 3-1. Redash è¡šãæ£ã°ã©ããªã©ã®ã¹ã¿ã³ããŒããªãã®ã¯æã£ãŠããŸãã 以äžã«Redashã® ãã¢ãµã€ã ã®ã°ã©ããèŒããŠãããŸãã ã»ããããããŒãã« ã»ã«ãŠã³ã¿ãŒ ãªã©ãªã©ä»ã«ããããããããŸãã 3-2. Superset ãã¡ããåæ§ã§ã¹ã¿ã³ããŒããªã°ã©ãã¯æã£ãŠããŸãã 以äžã«ãµã³ãã«ã®ã°ã©ããèŒããŠãããŸãã ã»Sankey ã»Directed Force Layout ãªã©ãªã©é¢çœãã°ã©ããæºèŒã§ãã ã©ã¡ããå€çš®ãªã°ã©ããåããŠããã®ã§ãå人çã«ã¯å€§ããªå·®ã¯ãªãããªãšããå°è±¡ã§ããã 4. ããã·ã¥ããŒã 4-1. Redash äœã£ã衚ãã°ã©ãã¯ä»¥äžã®ãããªããã·ã¥ããŒãã«ãŸãšããããšãã§ããŸãã â ããã·ã¥ããŒãã§ã§ããããš ã»ãªãŒããªããŒãæ©èœïŒå®æçã«ã°ã©ããæŽæ°ããïŒ ã»ã°ã©ãã®äžŠã³æ¿ã ã»ã¢ã©ãŒãæ©èœïŒèšå®ããå€ãè¶
ããå Žåã«ãã¡ãŒã«ãSlackã«éç¥ã§ããïŒ å人çã«ã¯ã¢ã©ãŒãæ©èœãããã®ã¯å¬ãããã€ã³ãã§ããã åžžã«ç£èŠããŠããªããšãããªãããŒã¿ãããå Žåã¯ãéç¥ããããšäŸ¿å©ã§ããã 4-2. Superset ãã¡ããRedashãšåæ§ã«ããã·ã¥ããŒãã«ãŸãšããããšãã§ããŸãã â ããã·ã¥ããŒãã§ã§ããããš ã»ãªãŒããªããŒãæ©èœïŒå®æçã«ã°ã©ããæŽæ°ããïŒ ã»ã°ã©ãã®äžŠã³æ¿ã ã»ããã·ã¥ããŒãäžã§ã°ã©ãã®è¡šç€ºé åãã«ã¹ã¿ãã€ãºã§ãã ã°ã©ãã®è¡šç€ºé åãã«ã¹ã¿ãã€ãºã§ããã®ã¯è¯ããã€ã³ãã§ããã è€æ°ã®ã°ã©ãã䞊ã¹ãŠèŠæ¯ã¹ãããè²ã
ã§ãããã§ãã ããããRedashã§ã¯ã§ããªãã£ãã¯ãã§ãïŒééã£ãŠããããããŸããïŒã ããšSupersetã«ã¯æ®å¿µãªããã¢ã©ãŒãæ©èœããããŸããã§ããã 5. æ¯èŒãŸãšã 5-1. Redash è¯ãç¹â¯ ã»ããŒã¿ãœãŒã¹é£æºãç°¡å ã»å€çš®ãªã°ã©ãããã ã»ã¢ã©ãŒãæ©èœããã æªãç¹â ã»SQLåå¿è
ã«ã¯ããŒãã«ãé«ã ã»ããã·ã¥ããŒãã®ã«ã¹ã¿ãã€ãºæ§ãäœã 5-2. Superset è¯ãç¹â¯ ã»GUIæäœãã§ãããããSQLåå¿è
ã§ã䜿ããã ã»å€çš®ãªã°ã©ãããã ã»ããã·ã¥ããŒãã®ã«ã¹ã¿ãã€ãºæ§ãé«ã æªãç¹â ã»ããŒã¿ãœãŒã¹é£æºãé£ããã飿ºã§ããããŒã¿ãœãŒã¹ãå°ãªã ã»ã¢ã©ãŒãæ©èœããªã ãŸãšã ä»åã¯RedashãšSupersetã®æ¯èŒæ€èšŒã«é¢ããŠã話ãããŠé ããŸããã å人çã«ã¯Redashãã·ã³ãã«ã§äœ¿ããããå°è±¡ã§ããããäž¡è
è¯ããšããããã£ãŠè¿·ããŸããã åŒãç¶ãããã·ã¥ããŒãããŒã«ã¯èŠãŠããããã§ãã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ITÃãã©ã€ãã«ã§æ¥çãå€ããïŒãããã§ãã·ã§ãã«ãªWEBãšã³ãžãã¢åéïŒ
ããã«ã¡ã¯ãSREããŒã ã€ã³ãã©ãšã³ãžãã¢ã®ç¶¿åŒã§ãã ä»å㯠Ansible ã§ SSLèšŒææžæŽæ°ãèªååããã¿ããšããã話ã§ãã SSLèšŒææžã®æŽæ°ã£ãŠæéãããããŸãããããåŸãã¥ãŒãã³ãšã©ãŒãæããã ããã§ èªåå åºæ¥ããçŽ æµïŒãšæã vagrant ã§æ€èšŒããŠã¿ãŸããã èå³ã®ããæ¹ã¯æ¯éèŠãŠé ããã°ãšæããŸãã ç°å¢ã»æ§æ ç°å¢ã»æ§æã¯ä»¥äžãšãªã£ãŠãããŸãã â ãµãŒãåŽèšå® ã» ãã¹ãå : ans ã» IP : 172.19.12.101 ã» æ§æç®¡çããŒã« : ansible/2.4.2.0 ã» ïŒé
åžçšïŒèšŒææžã®ä¿åãã£ã¬ã¯ã㪠: /opt/ansible/ssl/ â ã¹ã¬ãŒãåŽèšå® ã» ãã¹ãå : anc ã» IP : 172.19.12.102 ã» WEBãµãŒã : Apache/2.4.6 ã» èšŒææžã®ä¿åãã£ã¬ã¯ã㪠: /etc/httpd/conf/ssl.crt/ â èšŒææžæ
å ± ã» ãµãŒãèšŒææžãã¡ã€ã«å : test.crt ã» äžéCAèšŒææžãã¡ã€ã«å : test.cer ã» ç§å¯éµãã¡ã€ã«å : test.key ããããããš ããããããšã®æµããšããŠã¯ã以äžã§ãã 1. ansible ãµãŒãåŽã«æ°ãã SSL èšŒææžãé
眮 2. ãµãŒãåŽã§ã¹ã¯ãªããããã㯠3. ãµãŒãåŽã®æ°ãã SSL èšŒææžããã¯ã©ã€ã¢ã³ãã«é
åž 4. ãã®åŸãã¯ã©ã€ã¢ã³ãåŽã® apache ã reload ããŠæ°ããèšŒææžãé©çš ã§ã¯æ©éãã£ãŠã¿ãããšæããŸãã ãŸãAnsibleãšã¯ ãã®åã«ãããã Ansible ãšã¯äœãããç¹åŸŽã¯äœã ãšããã®ãç°¡åã«ãã ã»æ§æç®¡çããŒã« ïž åããããªãããã¯ããšããŠã¯ chef ã puppet ãªã©ã§ãã ã»ãšãŒãžã§ã³ãã¬ã¹ ïž ã¯ã©ã€ã¢ã³ãåŽã«ãšãŒãžã§ã³ããå
¥ããªããŠæžãã®ã¯ããããã ã»ã·ã³ãã« ïž ä»ã®æ§æç®¡çããŒã«ãšæ¯ã¹ããšèšè¿°ãªã©ãã·ã³ãã« å人çã«ã¯ãšãŒãžã§ã³ãã¬ã¹ã¯å¬ããéãã§ãã 察象ãµãŒãã®å°æ°ãå€ããšãšãŒãžã§ã³ããã€ã³ã¹ããŒã«ããã®ãé¢åã§ããã ãšãŒãžã§ã³ãã®ã€ã³ã¹ããŒã«ã«åŒãããããŠãä»ã®ããã±ãŒãžããœãŒã¹ãå
¥ããããšããªãã®ã§ã Ansible ã®ã€ã³ã¹ããŒã« yum ã§ Absible ã€ã³ã¹ããŒã«ããŸããããããªãéåžžã«ç°¡åã§ããã $ yum install epel-release $ yum install ansible $ ansible --version ansible 2.4.2.0 config file = /etc/ansible/ansible.cfg configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Jun 24 2015, 00:41:19) [GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] èšå®ãã¡ã€ã«ã®äœæ ã€ã³ã¹ããŒã«ãå®äºããã®ã§ã次ã¯èšå®ãè¡ã£ãŠãããŸãã å®è¡ã«å¿
èŠãªãã¡ã€ã«ã¯(åºæ¬çã«)以äžã®2ã€ã§ãã â ã€ã³ãã³ããªãã¡ã€ã« (hosts ãã¡ã€ã«) ã»æäœããããªã¢ãŒããµãŒãã®ãã¹ãåãIPãèšè¿° ã»ã€ã³ãã³ããªãã¡ã€ã«ã«èšèŒããããªã¢ãŒããµãŒãã«å¯Ÿãæäœãå®è¡ããã ã»å°ããªã¢ãŒããµãŒãã¯ã°ã«ãŒãåããããšãã§ãããã®ã°ã«ãŒãã«å¯Ÿãæäœãã§ãã â playbookïŒã¢ãžã¥ãŒã«ïŒ ã»yaml åœ¢åŒ ã»ãªã¢ãŒããµãŒãã«å®è¡ããããåŠçãèšè¿°ããå®çŸ©ãã¡ã€ã« ã»Ansible ã® ã¢ãžã¥ãŒã« ã䜿çšãããã¡ã€ã«ã³ããŒããµãŒãã¹èµ·åãªã©æ§ã
ãªåœä»€ãå¯èœ ã¢ãžã¥ãŒã«ã®æ°ã¯çŸåš 1,300 ã»ã©ããã¿ãããªã®ã§ãããªãå€ãã®èŠæã«å¯Ÿå¿ã§ãããã§ãã ãã æ®æ®µäœ¿ãããã®ã¯ãããŸã§å€ããªããããã ä»å䜿çšããã®ã¯ä»¥äžã®ã¢ãžã¥ãŒã«ã§ãã â 䜿çšããã¢ãžã¥ãŒã«ïŒäžéšïŒ No. ã¢ãžã¥ãŒã«å çšé 1 file ãã£ã¬ã¯ããªã®äœæãã察象ãã¡ã€ã«ã®æåå眮æ 2 copy ãã¡ã€ã«ã³ã㌠3 service ãµãŒãã¹éå§ã忢 4 shell OSã³ãã³ãã®å®æœ ã¢ãžã¥ãŒã«ã«ã¯ä»ã«ã yum ãªã©ãããã ããã±ãŒãžã€ã³ã¹ããŒã«ã ansible ã«ãŠå¯èœãªã®ã§ ãµãŒãã®èªåæ§ç¯ãè¡ãéãªã©ã«äŸ¿å©ããã§ãã ã€ã³ãã³ããªãã¡ã€ã«äœæ ãŸãã¯ã€ã³ãã³ããªãã¡ã€ã«ããäœæããŠãããŸãã é©åœã« /opt é
äžã« ansible ãã£ã¬ã¯ããªãäœãã ãã®çŽäžã« hosts ãšããååã®ã€ã³ãã³ããªãã¡ã€ã«ãäœæããŸãã $ sudo mkdir /opt/ansible/ $ cd /opt/ansible/ $ sudo vi hosts å
ã»ã©ã®ã°ã«ãŒãæå®ã®æžãæ¹ãããŸãã “[ ]” å
ã«ã°ã«ãŒãåãèšèŒããåå ãããããªã¢ãŒããµãŒããçŸ
åããŸãã [test1] 172.19.12.102 ãã®èšèŒã ãš test1 ãéžã¹ã°ã第4ãªã¯ããã 102 ïŒancãµãŒãïŒ ã«å¯Ÿãå®è¡ããŸãã ãŸããã¹ãåã§èšèŒããããšãå¯èœã§ãã ãã¡ãã以äžã®ããã«è€æ°å°ãéžæããããšãå¯èœã§ãã [test2] 172.19.12.103 172.19.12.104 yaml ãã¡ã€ã«äœæ 次ã¯ã¯ã©ã€ã¢ã³ãåŽã®æäœãå®çŸ©ãã yaml ãã¡ã€ã«ãäœæããŸãã $ cd /opt/ansible/ $ sudo vi ssl_update.yaml ä»åã¯ãã®ãããªåœ¢ã§æžããŠã¿ãŸãããïŒæ±ãã§ããããïŒ ãŸã倿°ã䜿ãããã£ãããã vars_files ãšããã¢ãžã¥ãŒã«ã䜿çšããŠãããŸãã vars_files ã¯å€æ°ãå®çŸ©ãããã¡ã€ã«ãå€ã«åºãããšãã§ããã®ã§éå®ããŸããã - hosts: test1 remote_user: vagrant become: yes vars_files: - /opt/ansible/vars.yml tasks: - name: 1. create backupdir file: path={{ dest_ssl_dir }}/{{ date }} state=directory owner=root group=root mode=0644 - name: 2. backup file shell: cp -p {{ dest_ssl_dir }}/{{ crt_file }} {{ dest_ssl_dir }}/{{ date }}/{{ crt_file }}; cp -p {{ dest_ssl_dir }}/{{ ica_file }} {{ dest_ssl_dir }}/{{ date }}/{{ ica_file }}; cp -p {{ dest_ssl_dir }}/{{ key_nopw_file }} {{ dest_ssl_dir }}/{{ date }}/{{ key_nopw_file }} - name: 3. check file shell: diff -s {{ dest_ssl_dir }}/{{ crt_file }} {{ dest_ssl_dir }}/{{ date }}/{{ crt_file }}; diff -s {{ dest_ssl_dir }}/{{ ica_file }} {{ dest_ssl_dir }}/{{ date }}/{{ ica_file }}; diff -s {{ dest_ssl_dir }}/{{ key_nopw_file }} {{ dest_ssl_dir }}/{{ date }}/{{ key_nopw_file }} - name: 4. update crt_file copy: src={{ new_ssl_dir }}/{{ crt_file }} dest={{ dest_ssl_dir }}/{{ crt_file }} owner=root group=root mode=0644 - name: 5. update ica_file copy: src={{ new_ssl_dir }}/{{ ica_file }} dest={{ dest_ssl_dir }}/{{ ica_file }} owner=root group=root mode=0644 - name: 6. update key_nopw_file copy: src={{ new_ssl_dir }}/{{ key_nopw_file }} dest={{ dest_ssl_dir }}/{{ key_nopw_file }} owner=root group=root mode=0644 - name: 7. httpd configcheck shell: httpd -t - name: 8. httpd reload for CentOS 7 service: name=httpd state=reloaded when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7") - name: 9.httpd reload for CentOS 56 shell: /etc/init.d/httpd graceful when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "5") or (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6") yaml ãã¡ã€ã«ã®å
容ã§ãããåã³ã¡ã³ãã®éšåã¯ä»¥äžã®éãã§ãã é
ç® å
容 1. create backupdir èšŒææžããã¯ã¢ããçšã®ãã£ã¬ã¯ããªãäœæïŒYYYYMMDDïŒ 2. backup file èšŒææžã®ããã¯ã¢ãããååŸ 3. check file çŸåšã®ãã¡ã€ã«ãšããã¯ã¢ããã«å·®åããªããç¢ºèª (â»1) 4. update crt_file ãµãŒãèšŒææžãã¡ã€ã«ãæŽæ° 5. update ica_file äžéCAèšŒææžãã¡ã€ã«ãæŽæ° 6. update key_nopw_file ç§å¯éµãã¡ã€ã«ãæŽæ° 7. httpd configcheck Apache ã® configcheck ãè¡ã (â»2) 8. httpd reload for CentOS 7 apache ã® reload ãå®è¡ããã (â»3) 9. httpd reload for CentOS 56 apache ã® reload ãå®è¡ããã (â»4) â»1 ã»ã»ã» å·®åããã£ãå Žå㯠diff ã®è¿ãå€ã “0” 以å€ãšãªããããšã©ãŒãšãªã â»2 ã»ã»ã» httpd.conf ã®èšè¿°ã«åé¡ãããå Žåã¯è¿ãå€ã â0â 以å€ãšãªããããšã©ãŒãšãªã â»3 ã»ã»ã» CentOS 7 systemctl reload htttpd ãå®è¡ããã â»4 ã»ã»ã» CentOS 5 ã 6 ã ã£ãå Žåã« /etc/init.d/httpd graceful ãå®è¡ããã æåŸã« /opt/ansible/vars.yml ã®äžèº«ã§ãã date: "{{ lookup('pipe','date +%Y%m%d') }}" crt_file: test.crt ica_file: test.cer key_nopw_file: test.key new_ssl_dir: /opt/ansible/ssl dest_ssl_dir: /etc/httpd/conf/ssl.crt å®è¡ ansible ãå®è¡ããã«ã¯ ansible-playbook ã³ãã³ããå®è¡ããŸãã (äœ¿ãæ¹äŸ) : $ ansible-playbook -i hostsãã¡ã€ã« yamlãã¡ã€ã« $ ansible-playbook -i hosts ssl_update.yaml PLAY [test1] ******************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************************************************************************************************************** ok: [anc] TASK [1. create backupdir] ****************************************************************************************************************************************************************************************** changed: [anc] TASK [2. backup file] *********************************************************************************************************************************************************************************************** changed: [anc] TASK [3. check file] ************************************************************************************************************************************************************************************************ changed: [anc] TASK [4. update crt_file] ******************************************************************************************************************************************************************************************* ok: [anc] TASK [5. update ica_file] ******************************************************************************************************************************************************************************************* ok: [anc] TASK [6. update key_nopw_file] ************************************************************************************************************************************************************************************** ok: [anc] TASK [7. httpd configcheck] ***************************************************************************************************************************************************************************************** changed: [anc] TASK [8. httpd reload for CentOS 7] ********************************************************************************************************************************************************************************* changed: [anc] TASK [9.httpd reload for CentOS 56] ********************************************************************************************************************************************************************************* skipping: [anc] PLAY RECAP ********************************************************************************************************************************************************************************************************** anc : ok=9 changed=5 unreachable=0 failed=0 å®è¡åŸããã©ãŠã¶ã§èšŒææžã®æŽæ°æ¥ã確èªãããåé¡ãªãæŽæ°ãããŠãããŸãããæåã§ãã hostsãã¡ã€ã«ã®ã°ã«ãŒãåãããã£ã¬ã¯ããªæ§æãyamlãã¡ã€ã«ã®èšèŒãªã©ã ãŸã ãŸã ãã©ãã·ã¥ã¢ãããå¿
èŠã§ããäžæŠäœ¿ãããã§ãã ãŸãšã ä»å㯠Ansible ã§ SSL èšŒææžãã¢ããããŒãããŸããã èªèº«ã®ç°å¢ã§ããããäžæããã£ãã®ã§ããµãŒãã¹ã«èŒããããªããæ€èšäžã§ãã çããŸããŸã Ansible 䜿ã£ãããšãªããã ãããŒãšããæ¹ãããã£ãããã°ã åèã«ããŠé ããŸããšå¹žãã§ãã ãæž
芧é ãããããšãããããŸããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ã岩æ©è¡åŸã§ãã ãã£ãŠã¿ããïŒAWSã§WEBãµãŒããŒç°å¢æ§ç¯ãä¹
ãã¶ãã®ç¶ç·šã§ãã 第4åã¯ãAWS LambdaããAmazon API Gatewayãã䜿ã£ããµãŒããŒã¬ã¹ãªç»åãªãµã€ãºAPIãã¯ã©ãŠãäžã«æ§ç¯ããŠèŠãããšæããŸãã ã¢ãŒããã¯ãã£ã»èšèšæŠèŠ ä»åã¯ä»¥äžã®ãããªã¢ãŒããã¯ãã£ã§ãClientãæå®ããä»»æã®ãµã€ãºã®ç»åãè¿åŽããAPIãæ§ç¯ããŠãããŸãã âS3ïŒ ã¯ã©ãŠãã¹ãã¬ãŒãžã [èšèšæŠèŠ] ãªãªãžãã«ç»åã®çœ®ãå Žãäœæã âLambdaïŒ æäœéã®ããã°ã©ã ã®ã¿ã§ã¢ããªã±ãŒã·ã§ã³ã®éçšãå¯èœãªãµãŒããŒã¬ã¹ãã©ãããã©ãŒã ãä»ã®AWSãµãŒãã¹ãšé£æºãå¯èœã [èšèšæŠèŠ] S3ããç»åããŒã¿ãåãåãããªãµã€ãºã宿œããããBase64圢åŒã«ããŠè¿åŽãããããäœæã âAPI GatewayïŒ APIã®çé¢ãæè»œã«æè»ã§æ¡åŒµçãªAPIããŒã¹ã®æ§ç¯ãå¯èœã [èšèšæŠèŠ] Lambdaããåãåã£ãBase64圢åŒã®ç»åããŒã¿ããã€ããªã«å€æããŠè¿åŽãããããäœæã âCloudFrontïŒ ååã¢ã¯ã»ã¹æã«è¿åŽããã³ã³ãã³ãããã£ãã·ã¥ã次å以éã¯æå¹æéå
ã§ããã°ãã£ãã·ã¥ããã³ã³ãã³ããè¿åŽã [èšèšæŠèŠ] åãããªã¯ãšã¹ãã«ããããŒãèšå®ããŠããã¯ãšã³ãã«æž¡ããããªãªã¯ãšã¹ãçªå£ãäœæã ãã®ïŒã€ã®ãµãŒãã¹ã飿ºãããŠã ã https://xxx.xxx.xxx/{ãã¡ã€ã«å}?width={暪å¹
} ã®ãããªåœ¢ã§åŒã³åºããã§ããAPIãæ§ç¯ããŠãããŸãã S3 S3ïŒAmazon Simple Storage ServiceïŒã¯ã€ã³ã¿ãŒãããçšã®ã¯ã©ãŠãã¹ãã¬ãŒãžã§ãããããåç¥ã®æ¹ãå€ããšæããŸãã®ã§çްããªèª¬æã¯å²æããŠãæ©éèšå®ããŠãããããšæããŸãã ä»åã¯ããªãµã€ãºå
ã®ãªãªãžãã«ç»åã®çœ®ãå ŽãäœããŸãã ãã±ããäœæ ã³ã³ãœãŒã«ããS3ã®ããŒãžã«é·ç§»ãããŠãã+ãã±ãããäœæããããã¿ã³ãã¯ãªãã¯ãã¢ãŒãã«ã衚瀺ãããŸãã ã»ãã±ããå ã»ãªãŒãžã§ã³ ãèšå®ããŠãäœæããã¿ã³ãã¯ãªãã¯ããŸãã ãªãªãžãã«ç»åã»ãã æ€èšŒçšã«å
ã»ã©äœã£ããã±ããã«çŽæ¥ç»åãã¢ããããŸãïŒneko.jpgïŒã å ã¿ã«ä»åã¯ãã®ããã¡ããã®ç»åãã¢ããããŸããã Lambda AWS Lambda ã¯ãµãŒããŒãããããžã§ãã³ã°ããã管çããªããŠãã³ãŒããå®è¡ã§ããã³ã³ãã¥ãŒãã£ã³ã°ãµãŒãã¹ã§ãæäœéã®ããã°ã©ã ã®ã¿ã§ã¢ããªã±ãŒã·ã§ã³ã®éçšãå¯èœã§ããä»ã®AWSãµãŒãã¹ã®ã€ãã³ããåãåããããã§èšå®ãã颿°ãããã¯ããããã§ããã®ã§ããããŸã§ä»¥äžã«AWSäžã§ããªãšãŒã·ã§ã³è±ããªã¢ãŒããã¯ãã£ãŒãå®çŸããããšãã§ããŸãã ä»åã¯ããªã¯ãšã¹ããããç»ååããšãæå®ãµã€ãºãåãåããS3ããããªãªãžãã«ç»åããååŸããæå®ãµã€ãºãã«å å·¥ãè¿åŽãããããªé¢æ°ãèšå®ããŸãã 颿°ã®å€æ äœæ ã³ã³ãœãŒã«ããLambdaã®ããŒãžã«é·ç§»ãããŠãã颿°ã®äœæããã¿ã³ãã¯ãªãã¯ããŸãã ã»åå ã»ã©ã³ã¿ã€ã ïŒC#, Go, Java, Node.js, Python ããéžæ ã»ããŒã«ïŒããã³ãã¬ãŒãããæ°ããããŒã«ãäœæããéžæ ã»ããŒã«å ã»ããªã·ãŒãã³ãã¬ãŒãïŒãS3 ãªããžã§ã¯ãã®èªã¿åãå°çšã¢ã¯ã»ã¹æš©éãã远å ãèšå®ããŠã颿°ã®äœæããã¿ã³ãã¯ãªãã¯ããŸãã ããã§LambdaãšS3ã®é£æºãèšå®ïŒLambdaãšCloudWatchLogsãšã®é£æºã¯ããã©ã«ãã§èšå®ãããŸãïŒããã颿°ã®å€æ ãã§ããŸããã 颿°ã®äžèº«äœæ ã颿°ã³ãŒãã ã»ã³ãŒã ãšã³ã㪠ã¿ã€ãïŒãã³ãŒããã€ã³ã©ã€ã³ã§ç·šéããéžæ ã»ã©ã³ã¿ã€ã ïŒä»åã¯Node.js 6.10ãšããŸããïŒ ã»ãã³ãã©ïŒããã©ã«ãïŒ ã»index.jsïŒä»åã¯ä»¥äžã®å
容ã§äœæïŒ 'use strict'; const imgmgck = require('imagemagick'); const aws = require('aws-sdk'); const s3 = new aws.S3({ apiVersion: '2006-03-01' }); exports.handler = (event, context, callback) => { // S3ã«ãããªãªãžãã«ç»åæ
å ± const s3OrgImageFile = { Bucket: 'resize-s3-images', // S3ã§äœã£ããã±ãã Key: event.filename, // ãªã¯ãšã¹ãã§æå®ãããç»åå }; // ãªã¯ãšã¹ãã§æå®ãããç»å暪å¹
const width = event.width; // S3ã«ãããªãªãžãã«ç»åååŸ s3.getObject(s3OrgImageFile, (err, data) => { if (err) { // ååŸå€±æ console.log('ååŸå€±æ:' + err); throw err; } else { // ååŸæå console.log('ååŸæå'); // ãªãµã€ãºå®æœ imgmgck.resize({ srcData: data.Body, width: width }, function(err, stdout, stderr) { if (err) { // ãªãµã€ãºå€±æ console.log('ãªãµã€ãºå€±æ:' + err); throw err; } else { // ãªãµã€ãºæå console.log('ãªãµã€ãºæå'); callback(null, new Buffer(stdout, 'binary').toString('base64')); } }); } }); }; ãåºæ¬èšå®ã ã»ã¡ã¢ãªïŒMBïŒïŒä»åã¯256MBãšããŸããïŒ â»å€§ããã«å¿ããŠèª²éé¡ãå€ãããŸã ã»ã¿ã€ã ã¢ãŠãïŒããã©ã«ãïŒ å³äžã®ãä¿åããã¿ã³ãã¯ãªãã¯ããŸãã ãã¹ã Lambdaã§ã¯äœæãã颿°ãã¯ã©ãŠãäžã§ãã¹ãããããšãå¯èœã§ãã å
ãã¯ãã¹ããèšå®ããŠãããŸãã å³äžã®ããã¹ãããã¿ã³ãã¯ãªãã¯ãã¢ãŒãã«ã衚瀺ãããŸãã ã»ã€ãã³ããã³ãã¬ãŒãïŒãAPI Gateway Authorizerããéžæ ã»ã€ãã³ãåïŒä»åã¯FromApiGatewayãšããŸããïŒ ïŒã€ãã³ãå
容ã¯ä»¥äžïŒ { "authorizationToken": "incoming-client-token", "methodArn": "arn:aws:execute-api:[region]:[account_id]:[restApiId]/[stage]/[method]/[resourcePath]", "type": "TOKEN", "filename": "neko.jpg", "width": "300" } ãäœæããã¿ã³ãã¯ãªãã¯ããŸãã ããã§ãã¹ãã®èšå®ãã§ããŸãããå³äžã®ãã«ããŠã³ãããFromApiGatewayããéžæãããã¹ãããã¿ã³ãã¯ãªãã¯ããã¹ãã宿œããŸãã äžæããã£ãããã§ããç¡äºBase64圢åŒã®ç»åããŒã¿ãè¿åŽãããŸããã API Gateway Amazon API Gateway ã¯ã¹ã±ãŒã©ãã«ãªAPIã®çé¢ãäœãã®ã«åªããŠããŸãããŸãç°¡åã«ãä¿å®ãç£èŠãä¿è·ãªã©ãè¡ããŸããLambdaãšã®çžæ§ãè¯ãçµã¿åãããããšã§ããµãŒããŒã¬ã¹ãªAPIã®æ§ç¯ãå¯èœã§ãã ããã§ã¯ããªã¯ãšã¹ããåãä»ããçºã®ãšã³ããã€ã³ããšãã®åãæž¡ãå
ïŒå
ã»ã©äœã£ãLambda颿°ïŒãèšå®ããŠãããŸãã APIã®å€æ äœæ ã³ã³ãœãŒã«ããAPI GatewayããŒãžã«é·ç§»ãããŠãã+APIã®äœæããã¿ã³ãã¯ãªãã¯ããŸãã ã»APIåïŒä»åã¯resize-s3-imagesãšããŸããïŒ ã»ãšã³ããã€ã³ãã¿ã€ãïŒããšããžæé©åããéžæ ãèšå®ããŠãAPIã®äœæããã¿ã³ãã¯ãªãã¯ããŸããããã§APIã®å€§æ ãã§ããŸããã æ¬¡ã«ãªãœãŒã¹ïŒAPIã®ãšã³ããã€ã³ãïŒãäœã£ãŠãããŸãã ãªãœãŒã¹ã®ã/ãäžã§ããã¢ã¯ã·ã§ã³ããã¯ãªãã¯ãããªãœãŒã¹ã®äœæããéžæããŸãã ã»ãããã·ãŒãªãœãŒã¹ãšããŠèšå®ïŒãã§ãã¯ãªã ã»ãªãœãŒã¹å ã»ãªãœãŒã¹ãã¹ïŒæ³¢æ¬åŒ§ã§ãã©ã¡ãŒã¿å®çŸ©ïŒãªã¯ãšã¹ãåãæã®Lambdaã«æž¡ããã©ã¡ãŒã¿ã ä»åã¯{filename}ãšããŸããïŒ ãèšå®ããŠããªãœãŒã¹ã®äœæããã¿ã³ãã¯ãªãã¯ããŸããããã§ãªãœãŒã¹ïŒAPIã®ãšã³ããã€ã³ãïŒãã§ããŸããã API諞èšå® ãã¡ãœããã ã¡ãœãããäœæããŸãã çŽåã§äœã£ããªãœãŒã¹ã/{filename}ãäžã§ããã¢ã¯ã·ã§ã³ããã¯ãªãã¯ããã¡ãœããã®äœæããéžæãããã«è¡šç€ºããããã«ããŠã³ãããGETããéžæããŸãã ã»çµåã¿ã€ãïŒãLambda 颿°ããéžæ ã»Lambda ãããã·çµ±åã®äœ¿çšïŒãã§ãã¯ãªã ã»Lambda ãªãŒãžã§ã³ïŒåè¿°ã®Lambdaã§èšå®ãããã®ãšåãªãŒãžã§ã³ãæå® ã»Lambda 颿°ïŒåè¿°ã®Lambdaã§èšå®ãããã®ãæå® ã»ããã©ã«ãã¿ã€ã ã¢ãŠãã®äœ¿çšïŒãã§ã㯠ãèšå®ããŠãä¿åããã¿ã³ãã¯ãªãã¯ããŸãã ãçµ±åãªã¯ãšã¹ãã 以äžã®ãããªåœ¢ã§APIã®åŒã³åºããæ³å®ããŠããçºã{ãã¡ã€ã«å}ã»{暪å¹
}ã«åœããéšåã®ãã©ã¡ãŒã¿ãLambdaã«æž¡ãããã«èšå®ããå¿
èŠããããŸãã ã https://xxx.xxx.xxx/{ãã¡ã€ã«å}?width={暪å¹
} ã¡ãœããã®å®è¡ç»é¢ã§ãçµ±åãªã¯ãšã¹ãããã¯ãªãã¯ãæ¬æãããã³ã°ãã³ãã¬ãŒããéããŸãã ã»ãªã¯ãšã¹ãæ¬æã®ãã¹ã¹ã«ãŒïŒããã³ãã¬ãŒããå®çŸ©ãããŠããªãå Žå (æšå¥š)ããéžæ ïŒContent-Type㯠image/png,image/jpeg,image/gif ãšããŠãã³ãã¬ãŒãå
容ã¯ä»¥äžïŒ { "filename": "$input.params('filename')", "width": "$input.params('width')" } ãèšå®ããŠãä¿åããã¿ã³ãã¯ãªãã¯ããŸãã ãçµ±åã¬ã¹ãã³ã¹ã Lambdaããã¯Base64圢åŒã§ç»åããŒã¿ãè¿åŽãããã®ã§ãããã§ãã€ããªããŒã¿ã«å€æããå¿
èŠããããŸãã ã¡ãœããã®å®è¡ç»é¢ã§ãçµ±åã¬ã¹ãã³ã¹ããã¯ãªãã¯ããŸãã ã»ã³ã³ãã³ãã®åŠçïŒããã€ããªã«å€æïŒå¿
èŠãªå ŽåïŒããéžæ ãèšå®ããŠãä¿åããã¿ã³ãã¯ãªãã¯ããŸãã ãããã€ãšããŒã«ã«ç¢ºèª ããããã€ã ãããã€ãããŠå
¬éããŸãã ãã¢ã¯ã·ã§ã³ããã¯ãªãã¯ããAPIã®ãããã€ããéžæãã¢ãŒãã«ã衚瀺ãããŸãã ã»ãããã€ãããã¹ããŒãžïŒãæ°ããã¹ããŒãžããéžæ ã»ã¹ããŒãžåïŒä»åã¯productionãšããŸããïŒ ãèšå®ããŠããããã€ããã¿ã³ãã¯ãªãã¯ããŸãã ãããŒã«ã«ç¢ºèªã ã·ã§ã«ããŒã¡ãã¥ãŒãããã¹ããŒãžããéžæããproductionããã¯ãªãã¯ããŸãããURLã®åŒã³åºãããååŸã§ããŸãã ããŒã«ã«ã®ã¿ãŒããã«äžã§curlã³ãã³ã䜿ã£ãŠãªãµã€ãºç»åååŸã®ç¢ºèªã§ããŸãã $ curl --request GET "Accept: image/jpeg" -H "Content-Type: image/jpeg" https://zwhfujd9te.execute-api.us-west-2.amazonaws.com/production/neko.jpg?width=300 > neko_resized.jpg 以äžã®ãããªãªãµã€ãºç»åãååŸã§ããŠããã°æåã§ãã CloudFront CloudFrontã¯AWSã¯ã©ãŠãäžã®CDNïŒã³ã³ãã³ãããªããªãŒãããã¯ãŒã¯ïŒã§ãããã¡ã㯠第3å ã§ç޹ä»ãããŠé ããã®ã§çްããªèª¬æã¯å²æããŸãã äœæ
CloudFrontãå¿
èŠã ããŠãäœæ
ä»åã®ã¢ãŒããã¯ãã£ãŒã«CloudFrontãå¿
èŠã«ãªãã®ã§ããããã ã https://zwhfujd9te.execute-api.us-west-2.amazonaws.com/production/neko.jpg?width=300 äžã¯ãããŸã§ã«äœæããŠããAPIã®URLã§ãããããimgã¿ã°ã«ã»ããããã°ïŒãããã¯çŽæ¥ãã©ãŠã¶ã§å©ãã°ïŒäœ¿ããïŒãšæããããããããŸããããäžæããããŸããããã®å Žå以äžã®ãããªã¬ã¹ãã³ã¹ãè¿ãããŸãã imgã¿ã°ã«ã»ããããã ãã§ã¯ããªã¯ãšã¹ãããããŒã«ãContent-Type:image/xxxããAccept:image/xxxããã»ãããããªãçºãAPI GatewayåŽã®ãçµ±åãªã¯ãšã¹ããã®ãæ¬æãããã³ã°ãã³ãã¬ãŒããã§ãµããŒãããŠããªãããããŒãšãªããUnsupported Media Typeããè¿åŽãããŸãã ã§ã¯ãAPI GatewayåŽã®ãçµ±åãªã¯ãšã¹ããã®ãæ¬æãããã³ã°ãã³ãã¬ãŒããã調æŽããã°ããã®ã§ã¯ïŒãšèããŸãããã…確ãã«ãã®å Žåããã®ãã±ããã¯Lambdaã«ãã©ãçããã®ã§ãããä»åºŠã¯ãçµ±åã¬ã¹ãã³ã¹ãã§ãã€ããªå€æããããªããªããŸããããã¯ãçµ±åã¬ã¹ãã³ã¹ãããã€ããªå€æãããã©ãããããªã¯ãšã¹ãããããŒãContent-Type:image/xxxããAccept:image/xxxããèŠãŠæ±ºããŠããçºã§ãã ããã§CloudFrontã®ç»å Žã§ããCloudFrontããOriginïŒä»åã§ãããšãzwhfujd9te.execute-api.us-west-2.amazonaws.comãïŒãžãã±ããã転éããéã«ãã«ã¹ã¿ã ããããŒãèšå®ã§ããæ©èœããããŸããããã䜿ã£ãŠãªã¯ãšã¹ãã«åŒ·å¶çã«ãContent-Type:image/xxxããAccept:image/xxxãã®ããããŒãã€ããŠããããšäžæãããããã§ãããã£ãŠã¿ãŸãããã CloudFrontã«ã«ã¹ã¿ã ããããŒãã€ããŠèšå® ã³ã³ãœãŒã«ããCloudFrontã®ããŒãžã«é·ç§»ãããŠããCreate Distributionããã¿ã³ãã¯ãªãã¯ããŸãã WebïŒäžïŒã®æ¹ã®ãGet Startedããã¿ã³ãã¯ãªãã¯ããŸãã ãOrigin Settingsã ã»Origin Domain NameïŒãzwhfujd9te.execute-api.us-west-2.amazonaws.comããéžæ ã»Origin IDïŒä»åã¯resize-imagesãšããŸããïŒ ã»Origin Protocol PolicyïŒãHTTPS Onlyããéžæ ã»Origin Custom HeadersïŒAcceptã»Content-Typeå
±ã«image/png,image/jpeg,image/gifãèšå® â»ãããäžçªããããã£ãããš ãDefault Cache Behavior Settingsã ã»Query String Forwarding and CachingïŒãForward all, cache based on allããéžæ â»ãããèšå®ããªããšGETãã©ã¡ãŒã¿ãOriginãžæž¡ããŸãã ãèšå®ããŠãCreate Distributionããã¿ã³ãã¯ãªãã¯ããŸãã ããã§CloudFrontã®èšå®ãå®äºããŸãããä»äœã£ãDistributionãèŠãŠã¿ãŸãããã äžã®ç»é¢ã®ãGeneralãã¿ãã§ãé
åžããããDomain Nameãã確èªã§ããŸããããã䜿ã£ãŠãã©ãŠã¶ã§ä»¥äžã®ãããªURLãå©ããŠç»åã衚瀺ããããã確èªããŸãã ã https://d298y89zsryi7u.cloudfront.net/production/neko.jpg?width=300 äžæããããŸããïŒèšå®ããDistributionãåæ ããããŸã§æ°åãããå ŽåããããŸãïŒãURLã®widthãä»»æã®å€ã«å€ããŠãååŸããããšã確èªã§ããŸãããCloudFrontã®ãã£ãã·ã¥æ©èœã®èª¬æã«ã€ããŠã¯å²æããŠããŸãããLambdaã§ã®ç»åãªãµã€ãºã¯æ±ºããŠè»œãåŠçã§ã¯ãªãã®ã§CloudFrontã§äžæããã£ãã·ã¥ãã§ããããã«ãã¥ãŒãã³ã°ããããšããèŠãããŸãã ããã§ããµãŒããŒã¬ã¹ãªç»åãªãµã€ãºAPIã®å®æã§ãã 第4åç®ã®æåŸã« ä»åã®ãã£ãŠã¿ããAWSã·ãªãŒãºã§ã¯ããLambdaãã䜿ã£ããµãŒããŒã¬ã¹ãªç»åãªãµã€ãºAPIãã¯ã©ãŠãäžã«æ§ç¯æé ããã£ãšã玹ä»ããŸããããAWSã§ã¯ãŸã ãŸã å€ãã®ã€ã³ãã©ãµãŒãã¹ãæäŸãããŠããããã®ãã¡ã®ã©ãããå®éã®WEBãµãŒãã¹éå¶ã«åœ¹ç«ã€åŒ·åãªæŠåšãšãªããŸããä»åŸããã®ãããªã·ãªãŒãºèšäºãéããŠçããã«æçãªæ
å ±ãæäŸã§ããã°ãšæããŸãã ãŸããã®ã·ãªãŒãºã§ãããŸã§ã€ã³ãã©ãšçžé ãã£ãæ¹ã§ãAWSã«å¯Ÿããçè§£ãå°ãã§ãæ·±ãŸã£ãŠããã°å¹žãã§ãã ãæž
芧é ãããããšãããããŸããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã âã·ãªãŒãº ã»ãã£ãŠã¿ããïŒAWSã§WEBãµãŒããŒç°å¢æ§ç¯ïŒã·ãªãŒãºç¬¬1åïŒ ã»ãã£ãŠã¿ããïŒAWSã§WEBãµãŒããŒç°å¢æ§ç¯ïŒã·ãªãŒãºç¬¬2åïŒ ã»ãã£ãŠã¿ããïŒAWSã§WEBãµãŒããŒç°å¢æ§ç¯ïŒã·ãªãŒãºç¬¬3åïŒ âçè
ã®ããããèšäº ã»ãDBèšèšå
¥é|ERå³|MySQLãã³ã³ããã¬ã·ãŒãããåŠã¶ïŒããŒã¿ã¢ããªã³ã°ææ³ ã»ãæ©æ¢°åŠç¿å
¥é|Python|scikit-learnãçµå±äœãã§ããïŒcheat-sheetãã解説ããŠã¿ãç¯
ããã«ã¡ã¯ãããããæ°åå
¥ç€ŸããŠ2幎ç®ã«ãªãé«å¶ïŒ@__1016tïŒã§ãã ãããã¯ã³ãŒãã¬ãã¥ãŒã§ãåºæ¬çãªã³ãŒãã®æžãæ¹ãPHPã§ã€ãããäŸ¿å©æ©èœãªã©ãããããå匷ããŠããŸããã ä»åã¯ãã®äžéšããŸãšããŠã¿ãŸããã 1. ã€ã³ãã³ãããããã ã€ã³ãã³ããšã¯ïŒ ãœãŒã¹ã³ãŒãã®èŠãç®ãæŽããŠããããã®ã§ã ifãforãªã©æ³¢ã«ãã³{}ã§å²ãŸãããããã¯å
ã®åè¡ãtabããŒãã¹ããŒã¹ã§åäžãããããšããããŸãã âŒã€ã³ãã³ããªã if ($dessert == 'papico') { for ($i = 0; $i <= 3; $i++) { echo 'ãã¶ãŒãã¯ããã³ã§ã'; } } else { echo 'ãã¶ãŒãã¯ããã³ã§ã¯ãããŸãã'; } âŒã€ã³ãã³ããã if ($dessert == 'papico') { for ($i = 0; $i <= 3; $i++) { echo 'ãã¶ãŒãã¯ããã³ã§ã' } } else { echo 'ãã¶ãŒãã¯ããã³ã§ã¯ãããŸãã' } ã€ã³ãã³ãããŠããã³ãŒãã®ã»ãããèŠãããã®ãããããŸãã å
¥ç€ŸããŠããç¥ã£ãæ étabã€ã³ãã³ã tabããŒã§ã€ã³ãã³ãããè¡ãå
ã®äœçœ®ã«æ»ãããïŒ ãããªãšãããã€ãdeleteããŒã§æ»ããŠããŸããã ãããshift + tabããŒã§æ»ããã®ã§ãïŒ è€æ°è¡äžæ¬åäžã ã€ã³ãã³ããããè¡ãè€æ°ããïŒ ãããªãšãããã€ãäžè¡ãã€ã€ã³ãã³ãããŠããŸããã ããããè€æ°è¡ãç¯å²éžæãtabããŒããããšã»ã»ã» äžæ¬ã§ã€ã³ãã³ãããããšãã§ããã®ã§ãïŒétabã€ã³ãã³ãããããïŒ 2. phpdocããã phpdocãšã¯ãã¯ã©ã¹ã颿°ãªã©ã®å®çŸ©åã«èšè¿°ãããããã¯ã³ã¡ã³ãã®ããšã§ãã phpdocãæžããŠãããšã – åŸã«ãœãŒã¹ãèŠè¿ããæçè§£ããæéãççž®ããã – ããã¥ã¡ã³ããèªåçæã§ããããã«ãªã ãšããã¡ãªããããããŸãïŒ /** * @return string */ public function sample() { $dessert = 'papico'; return $dessert; } 詳ããæžãæ¹ã«ã€ããŠã¯ãã¡ããããããã§ãïŒ phpDocumentorã®æžãæ¹ – Qiita 3. æŒç®åãã€ããããªã æŒç®åã«ã¯ããŸããŸãããŸãããããããææãããã®ã¯ æ¡ä»¶æŒç®å(äžé
æŒç®å) ãš NullåäœæŒç®å ã§ãã æ¡ä»¶æŒç®å(äžé
æŒç®å)ãšã¯ïŒ æ¡ä»¶ã«ããè¿ãå€ãåãæ¿ããããšãã§ããæŒç®ã®ããšã§ãã ããšãã°ãanswerã10ããå°ãããšãã¯ãã®ãŸãŸanswerãã 10以äžã®ãšãã¯10ãšè¿ãããã°ã©ã ãifæãæ¡ä»¶æŒç®åã§ãããšãã ãããã以äžã®ããã«ãªããŸãã âŒifæ if ($answer < 10) { $result = $answer; } else { $result = 10; } âŒæ¡ä»¶æŒç®å // [æ¡ä»¶] ? [TRUEã®å Žåã®è¿ãå€] : [FALSEã®å Žåã®è¿ãå€] ; $result = ($answer < 10) ? $answer : 10; ifæãããæ¡ä»¶æŒç®åã®ã»ããã·ã³ãã«ã«ãããŸãã ãããã¯ãã£ãšæ¡ä»¶æŒç®åã¯ifæã®çç¥åœ¢ã ããšæã£ãŠããã®ã§ããéãããã§ãã ã€ããããã«ã€ããŠã¯ãã®èšäºã§ãå匷ãããŠããã ããŸããïŒ äžé
æŒç®åã¯æªãïŒ – Qiita NullåäœæŒç®åãšã¯ïŒ PHP7ãã远å ãããæ°æ©èœã§ãããããªãã£ããããšããåŠçãç°¡åã«ããããšãã§ããŸãã ããšãã°ãdessertããªãã£ããè²·ãã«ããããã£ããdessertãšè¿ãåŠçã ããã»ã©ã®æ¡ä»¶æŒç®åãNullåäœæŒç®åã§ãããšããããã以äžã®ããã«ãªããŸãã âŒæ¡ä»¶æŒç®å $result = isset($dessert) ? $dessert : 'è²·ãã«ãã'; âŒNullåäœæŒç®å // [æªå®çŸ©ãå€å®ããã倿°] ?? [ããã©ã«ãå€] $result = $dessert ?? 'è²·ãã«ãã'; æ¡ä»¶æŒç®åãããã·ã³ãã«ã«æžããããšãããããŸãã ãããã¯å®çŸ©ãããŠããªã倿°ã«ãããšã©ãŒãé²ãããã ?? ãä¹±çšããŠããŸããã¡ãªã®ã§ããã åŠçã³ã¹ãããããããã€ããããã«ã¯æ³šæãå¿
èŠã§ãã æåŸã« ä»åã³ãŒãã¬ãã¥ãŒã§ææãããããšãèšäºã«ãŸãšããŠã¿ãŠã ããã£ãã€ããã§ãæç« ã«ã§ããã»ã©çè§£ã§ããŠããªãäºãå€ããªããšæããŸããã ä»åŸãææããããããšã¯ãŸãšããŠãã§ãã¯ããæææ°ãæžãããŠãããããããªãšæããŸãïŒ Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã âª19åâ«ITÃãã©ã€ãã«ã§æ¥çãå€ãããšã³ãžãã¢åéïŒâªæªç¥å€ããâ«
ããã«ã¡ã¯ããµãŒããµã€ããšã³ãžãã¢å
ŒQAãšã³ãžãã¢ã®æè€ïŒ@saik1010ïŒã§ãã åŒç€ŸQAããŒã ã§ãåãçµã¿ãå§ããã Selenium ã䜿çšãããã©ãŠã¶ãã¹ãèªååã«ã€ããŠã ç°å¢æ§ç¯ãç°¡åãªããã°ã©ã ãå®è¡ãããŸã§ãã玹ä»ããããšæããŸãïŒ åäœç°å¢ ç°å¢ ããŒãžã§ã³ macOS Sierra 10.12.6 Ruby 2.4.2 rbenv 1.1.1 RSpec 3.7.0 Capybara 2.16.0 Selenium Webdriver 3.60 ChromeDriver 2.35 ããã æŠèŠ æ§ç¯æé ããã°ã©ã äœæãå®è¡ ãŸãšã æŠèŠ ä»åã¯ãæå
ã®Macã« Selenium+Ruby+Capybara ãã€ã³ã¹ããŒã«ããŠã æè»œã§ã·ã³ãã«ãªãã©ãŠã¶ãã¹ãã®ç°å¢ãæ§ç¯ããŠãããŸãã åŒç€Ÿã®ã¡ã€ã³èšèªã¯PHP/Goãæ¡çšããŠãããŸãããäž¡èšèªãšã Selenium ã§å
¬åŒãµããŒããããŠããªããããå°æ¥çãªéçšä¿å®ãèæ
®ããŠã Ruby ãæ¡çšããŸããã ãŸãã Ruby ã«ã¯ Capybara ãšãã匷åãªãµãŒãããŒãã£è£œã®ã©ãããŒããããããªãã·ã³ãã«ïŒâ»1ïŒã« Selenium ã®ã³ãŒããæžãããšãã§ããããšãïŒã€ã®å€§ããªéžå®èŠå ã«ãªã£ãŠããŸãã â»1 å人çãªæèŠã§ããããã¥ã¢ãªJavaScriptãjQueryã§æžããããã«ãªããããã®é¢ä¿æ§ã«è¿ã æ§ç¯æé ã§ã¯æ©éãç°å¢æ§ç¯ãããŠãããŸãããïŒ HomeBrewã®ã€ã³ã¹ããŒã« ã€ã³ã¹ããŒã«ã«ã¯ HomeBrew ã䜿çšãããšç°¡åã«ç°å¢æ§ç¯ãè¡ãããšãã§ããŸãã â»æ¢ã«ã€ã³ã¹ããŒã«æžã¿ã®å Žåã¯ã¹ãããããŠãã ãã $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" $ brew -v Homebrew 1.5.11 Homebrew/homebrew-core (git revision 847b9; last commit 2018-03-20) Rubyã®ã€ã³ã¹ããŒã« ãã®ãŸãŸãææ°çã® Ruby ãå
¥ããŠããŸã£ãŠãè¯ãã®ã§ããã è€æ°ããŒãžã§ã³ã管çããããšãæ³å®ããŠã rbenv ãå©çšãã Ruby ãã€ã³ã¹ããŒã«ããŸãã ãŸã㯠rbenv ããã€ã³ã¹ããŒã«ãããŠãããŸãããïŒ # rbenvã®ã€ã³ã¹ããŒã« $ brew install rbenv $ rbenv --version rbenv 1.1.1 # åæèšå®ã®ã¹ã¯ãªãããèšå®ãã $ vi ~/.bash_profile eval "$(rbenv init -)" #è¿œèš $ source ~/.bash_profile # æ£ããã€ã³ã¹ããŒã«ã§ããŠãããç¢ºèª $ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash Checking for `rbenv' in PATH: /usr/local/bin/rbenv Checking for rbenv shims in PATH: OK Checking `rbenv install' support: /usr/local/bin/rbenv-install (ruby-build 20180224) Counting installed Ruby versions: 2 versions Checking RubyGems settings: OK Auditing installed plugins: OK ç¶ã㊠rbenv ãå©çšããŠã Ruby ãã€ã³ã¹ããŒã«ããŸãïŒ # ã€ã³ã¹ããŒã«å¯èœãªrubyã®ããŒãžã§ã³ç¢ºèª $ rbenv install -l # Rubyã®ã€ã³ã¹ããŒã« $ rbenv install 2.4.2 $ rbenv global 2.4.2 $ rbenv rehash $ ruby -v ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16] Seleniumã®ã€ã³ã¹ããŒã« Rubygems ã䜿çšããŠã Selenium ãã€ã³ã¹ããŒã«ããŸãïŒ ä»åã¯ãèªåãã¹ã察象ãšããŠChromeãå©çšãããããWebDriverã¯ChromeDriverã®ã¿ãã€ã³ã¹ããŒã«ããŠããŸãããIEãFirefoxãªã©ã§ãå°çšã®WebDriverãã€ã³ã¹ããŒã«ããããšã§ãåäœãããããšãå¯èœã§ãã â»å¯Ÿè±¡ã®ãã©ãŠã¶ã¯ã ãã¡ã ãã確èªãã ããïŒ $ gem install selenium-webdriver $ brew install chromedriver é¢é£ã©ã€ãã©ãªã®ã€ã³ã¹ããŒã« ç¶ã㊠Capybara ãš RSpec ãã€ã³ã¹ããŒã«ããŸãïŒ ãã¡ãã Rubygems ã§ç°¡åã«å
¥ããããšãã§ããŸãã $ gem install capybara $ gem install rspec ããã°ã©ã äœæãå®è¡ ããã§ã¯ã€ã³ã¹ããŒã«ãã Selenium+Ruby+Capybara ãå©çšããŠãç°¡åãªãµã³ãã«ããã°ã©ã ãå®è£
ããŠã¿ãŸãããïŒ Selenium ã®å
¬åŒãµã€ãã§ããµã³ãã«ãµã€ããæäŸãããŠããã®ã§ããã¡ããã¢ã¯ã»ã¹ããŠå
¥åãã©ãŒã ã®èªåãã¹ããå®è£
ããŠãããŸãïŒ # 䜿çšããã©ã€ãã©ãªãæå® require 'capybara/rspec' # seleniumã§choromeã䜿çšãã Capybara.default_driver = :selenium Capybara.register_driver :selenium do |app| Capybara::Selenium::Driver.new(app, :browser => :chrome) end # ãã¹ãã±ãŒã¹ feature 'Seleniumã§ãã¹ããµã³ãã«' do scenario 'å
¥åãã©ãŒã ã®ç¢ºèª' do # ãµã³ãã«ãµã€ããžã¢ã¯ã»ã¹ visit 'http://example.selenium.jp/reserveApp/' # ãã©ãŒã ãžå
¥åïŒhtmlã¿ã°ã®idæå®ïŒ fill_in('reserve_year', with: '2018') fill_in('reserve_month', with: '4') fill_in('reserve_day', with: '1') fill_in('reserve_term', with: '3') fill_in('headcount', with: '5') fill_in('guestname', with: 'Selenium ãã¹ã') # ã©ãžãªãã¿ã³ãéžæïŒhtmlã¿ã°ã®idæå®ïŒ choose('breakfast_off') # ãã§ãã¯ããã¯ã¹ãéžæïŒhtmlã¿ã°ã®idæå®ïŒ check('plan_a') # ãã¿ã³æŒäž click_on '次ãž' end end å®éã«å®è£
ããããã°ã©ã ãå®è¡ããŠã¿ãŸãïŒChromeãèªåã§ç«ã¡äžããããã¹ããå®è¡ãããã°OKã§ãïŒ $ rspec äœæãããã¡ã€ã«å.rb . Finished in 4.76 seconds (files took 0.25653 seconds to load) 1 example, 0 failures ãŸãšã ãããã§ããã§ããããïŒ ã5åã§ã ã¯ã¡ãã£ãšçããããŸãããã»ã»ã»ïŒç¬ïŒ ã·ã³ãã«ãã€ãå°ãªãã³ãŒãéã§ãã©ãŠã¶ãã¹ãã®èªååãå®çŸã§ããŸããïŒä»ã«ãã¹ã¯ãªãŒã³ã·ã§ãããæ®ããªã©ã Selenium ã«ã¯å€ãã®æ©èœãæäŸãããŠããã®ã§ãåŒç€Ÿã§ã¯ååž°ãã¹ããªã©ã«å©çšããŠããããšèããŠããŸãã æ¬çªéçšã«åããŠã¯ããã¹ããµãŒããžã®ç°å¢æ§ç¯ããããã¬ã¹ãã©ãŠã¶ã®å©çšãªã©ããŸã ãŸã 課é¡ã¯ãããŸãããã²ãšãŸãéçšã«ä¹ããŠããæ€èšŒãé²ããŠã¿ãããšæããŸãã ãŸãåŸæ¥ããã¡ãã®ããã°ã§æ€èšŒçµæãå ±åãããŠé ããŸãã®ã§ãç¶ç·šã«ä¹ããæåŸ
ãã ããïŒ Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ãSREããŒã ã€ã³ãã©ãšã³ãžãã¢ã®ç¶¿åŒã§ãã MySQL ã®ç¹å®ã®ããŒãžã§ã³ãã€ã³ã¹ããŒã«ãããïŒ ã ãã© yum ã§ããã£ãšã€ã³ã¹ããŒã«ããããšãããããã€ããŒããŒãžã§ã³ãäžãã£ãŠããŠåãã«ãªããªããã ãªããŠããšãããããŸããããããã§ããå
é±ã®ç§ã§ãã ããã§ä»åã¯å€ãããŒãžã§ã³ã® MySQL ã yum ã€ã³ã¹ããŒã«ããæé ãèšèŒããããšæããŸãã æé 1. äŸåé¢ä¿è§£æ±ºã®ããã«ãææ°ã®ãªããžããªã远å ãã ãŸãã¯ææ°ã®ãªããžããªãã€ã³ã¹ããŒã«ããŸãããã $ cd /etc/yum.repos.d/ $ ls -l $ sudo rpm -ivh http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm $ ls -l 2. wget ãã€ã³ã¹ããŒã«ãã ãã®åŸãã¡ã€ã«ãèœãšããŠããã®ã§ãå
¥ã£ãŠãªããã° wget ãã€ã³ã¹ããŒã«ããŸãããã $ sudo yum list installed wget $ sudo yum install wget $ sudo yum list installed wget 3. éå»ã«ãã€ããŒããŒãžã§ã³ãå
¥ã£ã tar ãã¡ã€ã«ãååŸãã MySQL ã®å
¬åŒãµã€ãã«ã¯éå»ã®ããŒãžã§ã³ã® MySQL éãã¢ãŒã«ã€ããããŠããŸãã MySQL Product Archives äŸãã°ã MySQL Community Server ãæ¬²ããæã«ã¯ãäžèšURLã«ã¢ã¯ã»ã¹ã 以äžã宿œããŠãããšã奜ã¿ã®ããŒãžã§ã³ã«åºäŒããŸãã ã» MySQL Community Server ãéžæ ã» Product Version ãéžæ ã» Operating System ãéžæ ã» OS Version ãéžæ ããã§ãç®åœã® tar ãã¡ã€ã«ã衚瀺ãããŸããã ããããµãŒãã«ããŠã³ããŒãããŠãå±éåŸã«ã€ã³ã¹ããŒã«ããŠãããŸãã $ cd /usr/local/src $ ls -l $ sudo wget https://downloads.mysql.com/archives/get/file/mysql-5.7.19-1.el7.x86_64.rpm-bundle.tar $ ls -l $ sudo tar -xvf mysql-5.7.19-1.el7.x86_64.rpm-bundle.tar $ ls -l $ sudo yum list installed | grep mysql 4. rpm ãæå®ã㊠localinstall ãã rpm ã³ãã³ãã§ãã€ã³ã¹ããŒã«ã§ããŸãããäŸåé¢ä¿ãé¢åãªã®ã§ yum ã® localinstall ã宿œããŠãããŸãã ãããŠå¿
èŠãªããã±ãŒãžã¯ãŸãšããŠã€ã³ã¹ããŒã«ããŸãããã ãmysql-community-server ã ã 5.7.19 å
¥ããã°ãäŸåé¢ä¿ããã£ãšäœãããŸãããšãã£ãŠãå¿
èŠãªããã±ãŒãžå
šéš 5.7.19 ã«ãªãã ãïŒã $ sudo yum localinstall mysql-community-server-5.7.19-1.el7.x86_64.rpm ãšäœãèãããã£ããçãç®ãèŠãŸããããã§ããå
é±ã®ç§ã§ãã (åŸã§èŠãã server ã 5.7.21 ã§ client ã 5.7.21ã§ãããã) ãŸãšããŠã€ã³ã¹ããŒã«ããŠãããŸãã $ sudo yum localinstall mysql-community-server-5.7.19-1.el7.x86_64.rpm \ mysql-community-client-5.7.19-1.el7.x86_64.rpm \ mysql-community-common-5.7.19-1.el7.x86_64.rpm \ mysql-community-devel-5.7.19-1.el7.x86_64.rpm \ mysql-community-libs-5.7.19-1.el7.x86_64.rpm \ mysql-community-libs-compat-5.7.19-1.el7.x86_64.rpm $ sudo yum list installed | grep mysql ããã§ ããŒãžã§ã³ã 5.7.19 ã«ãªã£ãŠããã°OKã§ãïŒ ãŸãšã ä»åã¯å€ãããŒãžã§ã³ã® MySQL ã yum ã€ã³ã¹ããŒã«ããŠã¿ãŸããã å人ç°å¢ãæŽãããæ¹ãè² è·åæ£çšã® DB ãµãŒããæ§ç¯ãããæ¹ãªã©åèã«ããŠé ããã°å¹žãã§ãã ãæž
芧é ãããããšãããããŸããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããããŠé ããã°ãšæããŸãã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ããµãŒããŒãµã€ããšã³ãžãã¢ã®@akane_256ã§ãã 仿¥ã¯ãPHP_CodeSniffer+GitHub+CircleCIã䜿ã£ãŠãPHPã®ã³ãŒãã¬ãã¥ãŒïŒã³ãŒãã£ã³ã°ã«ãŒã«ã®åŸ¹åºïŒãäžéšèªååããããšã«ã€ããŠæžããããšæããŸãã ç®æ¬¡ èå³ãæã£ãèæ¯ ä»åãã£ãããš å©çšããŒã«ã«ã€ã㊠å®è£
ã®æµã ããã£ããšãã ãŸãšã èå³ãæã£ãèæ¯ éçºãé²ãã«ã€ããŠãä»ã®äººãæžããã³ãŒããšèªåãæžããã³ãŒãã§ãçµ±äžæãä¿ã€ã®ãé£ãããªã£ãŠãããªããšãã宿ããã£ãã®ãšã³ãŒãã£ã³ã°ã«ãŒã«ã«ãã£ãŠããªãã³ãŒããèªåã§èŠã€ããããã䟿å©ã ããããšååãšè©±ãæ©äŒããã£ãã®ã§è©ŠããŠã¿ãŸããããã®ä»ã«ããäžèšã®ãããªã¡ãªãããããã®ã§ã¯ãªãããšèããŸããã å°ãªã人æ°ã§ã³ãŒãã¬ãã¥ãŒæéãååã«åããªãå Žåã§ããœãŒã¹ã³ãŒãã®å質ãä¿ãŠãã ãã人ãå¢ããæã§ãããœãŒã¹ã³ãŒãã®æžãæ¹ã«çµ±äžæãããããããã èªåã®ã³ãŒãã®ãããªãéšåããããã®ã§ã¬ãã«ã¢ããã«ç¹ããã ä»åãã£ãããš ä»åã¯äžèšã®ãããªæµãã§äœæããŸããã 1. ãœãŒã¹ã³ãŒããGitHubã«pushãã 2. CircleCIãpushãããã¯ã«ãã¹ããå®è¡ããããã¹ãã®äžã§ã PHP_CodeSniffer ã®ã³ãã³ããå©ããŠãœãŒã¹ã³ãŒãã®éçè§£æãå®è¡ãã 3. çµæãPull Requestã«ã³ã¡ã³ããšããŠè¡šç€ºããã 4. ãã¹ãçµæãSlackã«éç¥ãã 宿ã€ã¡ãŒãžãã³ãŒãã£ã³ã°ã«ãŒã«ã«åããªãéšåãææããŠã³ã¡ã³ãããŠãããŸãã å©çšããŒã«ã«ã€ã㊠PHP_CodeSnifferãšã¯ïŒ GitHubäžã«ãããPHPã®ãœãŒã¹ã³ãŒãæŽåœ¢OSSã§ãã PHP_CodeSniffer å®çŸ©ãããã³ãŒãã£ã³ã°ã«ãŒã«ã®éåãæ€åºããããèªåæŽåœ¢ããŠãããŸãã ã³ãŒãããããã«ããŠäžè²«æ§ãä¿ã€ããã«äœ¿ããŸãã CircleCIãšã¯ïŒ ã¢ããªã±ãŒã·ã§ã³äœææã®å質æ¹åãçŽæã®ççž®ã®ããã«äœ¿ãããŒã«ã§ããä»åã¯å質æ¹åïŒïŒã³ãŒãã£ã³ã°ã«ãŒã«ã®çµ±äžïŒã«äœ¿ããŸãã CIããŒã«ã¯ãããããã£ãŠéžã¶ã®ã倧å€ã§ããããäž»ã«äžèšã®çç±ããCircleCIã«ããŸããã GitHubãšã®é£æºãç°¡åãGitHubã®ã¢ã«ãŠã³ããäœæããã°ãCircleCIã¯GitHubã®ã¢ã«ãŠã³ãã§ãã°ã€ã³ããã°çµããã èšå®ã¯ãWebã®UIãããã¯ymlãã¡ã€ã«ã§ç®¡çã§ããã 1ã¶æ1500å(=25æé)ãŸã§ãªãç¡æïŒïŒã³ã³ããïŒãâ»2018/2æç¹ CircleCI 2.0ãã§ãã¿ã€ãã³ã°ã§ãéçºãçãã«è¡ãããŠããã meetupãªã©çãã«è¡ãããŠããçãäžãã£ãŠããã UIã綺éºã å®è£
ã®æµã ã¢ã«ãŠã³ãæºå GitHubã¢ã«ãŠã³ãäœæ ãªããžããªãpush CircleCIã®ã¢ã«ãŠã³ãäœæïŒGitHubã¢ã«ãŠã³ãã§ãã°ã€ã³ïŒ å©çšããŒã«ã®é£æºæºå GitHubãšCircleCIã®é£æº CirlcleCIãšSlackã®é£æº ãããžã§ã¯ãã®èšå®æºå composer.jsonã®ç·šé ãã¹ãã³ãã³ãããŸãšãã check_syntax.sh ããªããžããªã«è¿œå CircleCIã®èšå®ãã¡ã€ã« circle.yml ããªããžããªã«è¿œå 1ã®ã¢ã«ãŠã³ãæºåã¯ç°¡åã ãšæãã®ã§å²æããŸããå©çšããŒã«ã®é£æºæºåããæžããŠãããŸãã å©çšããŒã«ã®é£æºæºå GitHubãšCircleCIã®é£æº GitHubã®Pull Requestã«ã³ãŒãã®è§£æçµæãã³ã¡ã³ãã§æžã蟌ã¿ããããã«ãGitHubã®ã¢ã¯ã»ã¹ããŒã¯ã³ãCircleCIã«ç»é²ããå¿
èŠããããŸãã ããããªããšCircleCIãGitHubã«ã¢ã¯ã»ã¹ã§ãããè¥å¹²ããããŸãããã GitHubã®ã¢ã¯ã»ã¹ããŒã¯ã³ã¯ã Setting > Developer settings > Personal access tokens > Generate new token ããçºè¡ããŸãã çºè¡ããããŒã¯ã³ã®å€ã¯ã³ããŒããŠãããŸããã³ããŒãå¿ãããšããŸãå床çºè¡ããããšã«ãªãã®ã§å¿ããã«ã ååã¯ããããããã CircleCI ãšãã«ããŠãããšè¯ããšæããŸãã æ¬¡ã¯ãCircleCIåŽã®èšå®ã§ãã CircleCIã®ç»é¢ãéãããããžã§ã¯ãã® Setting > Environment Variables > Add variable ãããå
ã»ã©ã®å€ãããŒã¹ãããŠä¿åããŸãã ãã¡ãã®ååãããããããã GITHUB_ACCESS_TOKEN ãšãã«ããŠãããšè¯ããšæããŸãã CircleCIãšSlackã®é£æº CircleCIã®ç»é¢ãã飿ºã§ããããã«ãªã£ãŠããŸãã Setting > Chat Notifications ãããSlackã®Webhook URLãç»é²ããéšåãããã®ã§ããã¡ãã«Slackã®Webhookã®URLãç»é²ããŸãã ã¡ãªã¿ã«ã飿ºãå®äºãããšããã«ãçµäºæã«éç¥ãããŸãããã¹ã倱ææã¯èµ€è²ãæåæã¯ç·è²ã§è¡šç€ºãããŸãã ïŒäžéšæåãäŒããŠããŸãïŒ ä»åã¯Pull Requestã®éãå€ããªãã®ã§ããã«ãã«ããçµãã£ããããSlackãžéç¥ããã¡ãªããã¯ããŸãæããããŸããã§ããããã«ããæ°å以äžãããå Žåã¯ããã£ããã§éç¥ããŠããããšäŸ¿å©ã§ãã ããã§å©çšããŒã«ã®é£æºæºåãæŽããŸããïŒ ãããžã§ã¯ãã®èšå®æºå 次ã¯ãå®éã«ãœãŒã¹ã³ãŒããªã©ã管çããŠãããããžã§ã¯ãã®èšå®æºåã§ãã åææ¡ä»¶ãšããŠãä»åã®æ€èšŒã«äœ¿ã£ããããžã§ã¯ãã®ãã£ã¬ã¯ããªæ§æã¯ãã®ãããªåœ¢åŒã§ãã PHPã®ããã±ãŒãžç®¡çã«ã¯ãcomposerãå©çšããŸãã âââ application â âââ composer.json â : âââ check_syntax.sh âââ circle.yml : composer.jsonã®ç·šé composer.jsonãç·šéããŠã php_codesniffer ãã€ã³ã¹ããŒã«ããèšè¿°ã远å ããŸãã ãããã£ãæŽåœ¢ããŒã«ã¯éçºç°å¢ã®ã¿ã§äœ¿ãã®ã§ã require-dev ã®éšåã«è¿œèšããŸãã application/composer.json "require-dev": { "squizlabs/php_codesniffer": "^3.1" } ãã¹ãã³ãã³ãããŸãšãã check_syntax.sh ããªããžããªã«è¿œå ãããä»åã®äžçªã®èã®éšåã§ããPHPã®äžè¬çãªã³ãŒãã£ã³ã°èŠçŽã§ãã PSR-2 ã«ã®ã£ãšã£ãŠè§£æããããã«ããŠããŸãã #!/bin/bash set -v if [ "${CIRCLE_BRANCH}" != "develop" ]; then # GitHubã®Pull Requestã«ã³ã¡ã³ããããããã«å¿
èŠãªgemã®ã€ã³ã¹ããŒã«ãããŸã echo gem install gem install --no-document checkstyle_filter-git saddler saddler-reporter-github # pull requestããªãã確èªããŸã if [ -z "${CI_PULL_REQUEST}" ]; then # when not pull request REPORTER=Saddler::Reporter::Github::CommitReviewComment else REPORTER=Saddler::Reporter::Github::PullRequestReviewComment fi # git diffããphpãã¡ã€ã«ãåãåºããphp_codesniferã®ã³ãã³ããå®è¡ããŸã echo saddler git diff --name-only origin/develop \ | grep -e '.php$' \ | xargs application/vendor/bin/phpcs -n --standard=PSR2 --report=checkstyle \ | checkstyle_filter-git diff origin/develop \ | saddler report --require saddler/reporter/github --reporter $REPORTER fi CircleCIã®èšå®ãã¡ã€ã« circle.yml ããªããžããªã«è¿œå ã³ãŒãã®è§£æãå®è¡ããããã°ã©ã ãçšæã§ããã®ã§ããã®ããã°ã©ã ãCircleCIããå®è¡ã§ããããã«èšå®ããŸãã CircleCIã®èšå®ãã¡ã€ã« circle.yml ããããžã§ã¯ãã«ãŒããã£ã¬ã¯ããªã«è¿œå ããŸããCircleCIã¯ãã®ymlãã¡ã€ã«ãã¿ãŠããã«ããå®è¡ããŸãã ä»åã¯ã test éšåãoverrideïŒäžæžãïŒããŠãå
ã»ã©è¿œå ãã .check_syntax.sh ãå®è¡ããããã«èšèŒããŸããã circle.yml machine: timezone: Asia/Tokyo php: version: 5.6.17 test: override: - composer install --dev --no-interaction --working-dir=application - ./check_syntax.sh ããã§å®æã§ããGitHubã®pushã«å¿ããŠãCircleCIã§ãã¹ããå®è¡ãããçµæãéç¥ããŠãããããã«ãªããŸãã ããã£ããšãã CircleCIã¯ã¯ã©ãŠããµãŒãã¹ãªã®ã§ãã¡ãã£ãšããããã°ã©ã ã®ä¿®æ£åŸã®åäœç¢ºèªã§ããpushããªããã°ãããªãã£ãã®ãèŸãã£ãã§ããïŒCircleCI2.0ããããŒã«ã«ã§å®è¡ã§ãããããªã®ã§è©ŠããŠã¿ããã§ããïŒ CircleCIãšGitHubã®é£æºãã¢ã¯ã»ã¹ããŒã¯ã³ã®ç»é²ãã§ããŠããªãã®ãæ°ã¥ããªããŸãŸå®è£
ãé²ããŠããã®ã§ãCircleCIããPull Requestãªããããšãšã©ãŒã«ãªã£ãŠããŸããå°ãããããŸããã ãŸãšã PHPã¯ãæšæºã§ã¯ã³ãŒããæŽåœ¢ããæ©èœãä»ããŠããªãã®ã§ãæ°ãã€ããªããšè€æ°äººã§ãã©ãã©ã®ã³ãŒãã£ã³ã°ã¹ã¿ã€ã«ã«ãªããã¡ã§ããããããŠæŽåœ¢çšã®ããŒã«ã䜿ã£ãŠã³ãŒãã®äžè²«æ§ãä¿ã€ããšã¯ãèªå以å€ã®ãšã³ãžãã¢ã®ããã«å€§äºãªããšã ãšæããŸãããŸããããããŠCIã䜿ã£ãŠèªåã§ææããããããã«ããŠãããšãæ°ãã人ãå
¥ã£ãŠãäžè²«ããã«ãŒã«ãä¿ã€ããšãã§ããã®ã§ããã²æŽ»çšããŠãããããšæããŸãã ãŸããå®è£
ã«ããããã¡ãã®èšäºããã£ã€ãåèã«ãããŠããã ããŸãããããããšãããããŸãã èŠçŽã«æ²¿ã£ãŠãªãPHPã³ãŒããé§éãã CircleCIããESLintã®ææçµæãPull Requestã«ã³ã¡ã³ããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ããµãŒããµã€ããšã³ãžãã¢å
ŒQAãšã³ãžãã¢ã®æè€ïŒ@saik1010ïŒã§ãã æ¬æ¥ã¯ãä»å¹Žã®1æ9ã1æ12æ¥ã«éå¬ãããšã³ãžãã¢è·ã€ã³ã¿ãŒã³ã·ããã®éå¶ã«ã€ããŠãã話ããããŠé ãããšæããŸãã åœæ¥ã®æ§å㯠Wantedly ã§ãã芧ã«ãªããŸãã®ã§ãåãããŠã確èªé ããã°ãšæããŸãïŒ åãçµãã ããŒã äŸå¹Žã察象ãµãŒãã¹ã«æ©èœè¿œå ããããšããããŒãèšå®ã§è¡ã£ãŠããŸããããå°ããã³ããªåããŠããããšããããä»å¹Žã¯æ°ããããŒããæš¡çŽ¢ããŠããŸããã ããã§ãåŒç€Ÿãšã³ãžãã¢ã»ãã¶ã€ããŒã§ããã€ãã®ããŒã ã«åããã瀟å
ã³ã³ãã宿œããŠããŒããæ±ºå®ããããšã«ã èŠäºãç±æŠãå¶ããããŒã ãèããããŒãã¯ãã¡ãïŒïŒ æããåŒå ŽèŠåŠã«ãããããªãïŒ ãšã³ã£ããã®ã¿ã€ã¢ããããŒãžïŒåºåããŒãžïŒãèãããïŒ å®éã« çµå©åŒå ŽãèŠåŠ ããŠãããäŒç»ãéçºããŸã§ãè¡ãã«ãªãã¥ã©ã ãšããã®ã倧ããªç®çãšãªã£ãŠããŸãïŒ ä»å¹Žã®ããŒãã®ãã€ã³ã 瀟å
ã³ã³ãã®äžã§ããã®æ¡ãæ¡çšãããã€ã³ããã玹ä»ããŸãã ãã©ã€ãã«ã«æ¥ç¹ã®å°ãªãåŠçã«çµå©åŒå ŽãèŠåŠããŠãããã ãã©ã€ãã«ãžã®çè§£ ãæ·±ããŠããããããš äŒç»ããç«æ¡ããããšã§ããšã³ãžãã¢ã ãã§ãªãã ãã£ã¬ã¯ã¿ãŒãšã®ã³ãã¥ãã±ãŒã·ã§ã³ ãåãããšãã§ããããš LPããŒãããäœãã®ã§ãããã¶ã€ã³ããµãŒããµã€ãããŸã§ å¹
åºãéçº ãçµéšã§ããããš éå¶ã¡ã³ã㌠ä»å¹Žã®éå¶ã¡ã³ããŒã¯ã2017幎床ã«å
¥ç€Ÿããæ°åã»äžéã¡ã³ããŒã®ãã¬ãã·ã¥ãª3åã§è¡ããŸããã å
šå¡ãåŒç€Ÿã®ãšã³ãžãã¢ã€ã³ã¿ãŒã³ãéå¶ããçµéšã¯ãããŸãããïŒç¬ïŒ åå äººæ° ä»åã¯9åã®åŠçãåå ããŠãããŸããïŒ 1ããŒã 3åã®å
š3ããŒã ã§ åªå ããããŠç«¶ãåããŸãã ã¡ã³ã¿ãŒã«ã¯ãçŸåœ¹ãšã³ãžãã¢ã 1ããŒã 2åå°å±ã§ä»ãæåããµããŒã ãåŒç€Ÿã€ã³ã¿ãŒã³ã®é
åã®äžã€ïŒ ã¡ãªã¿ã«åªåããããŒã ã¯ã代衚åç· åœ¹ç€Ÿé·ã§ããæ¥çŽ«å㚠豪è¯äŒé£ ã«è¡ãããšãã§ããŸãïŒïŒåŠçã«ãšã£ãŠã¯è²ŽéãªçµéšïŒïŒ äž»ãªã€ã³ã¿ãŒã³ã®æµã åŒç€Ÿã®ã€ã³ã¿ãŒã³ã§ã¯ããæ®æ®µè¡ãªã£ãŠããããŒã éçºãäœéšããŠãããããïŒããšã®æããããå®éã«çŸåœ¹ãšã³ãžãã¢ãè¡ãªã£ãŠããéçºãããŒã«æ²¿ã£ãŠäœæ¥ãé²ããŠãããŸããç°¡åã«ã§ãããä»åã®äœæ¥ãããŒã玹ä»ããŸãã äŒç»äœæ äŒç»ã¬ãã¥ãŒ 仿§èšèš 仿§èšèšã¬ãã¥ãŒïŒä»åã¯æªå®æœïŒ éçº ã³ãŒãã¬ãã¥ãŒ ãã¹ã æçµãã¬ãŒã³çºè¡š éå¶ããäžã§æ³šåãããã€ã³ã çŸå Žç€Ÿå¡ããã®ã¬ãã¥ãŒ ãå®éã®éçºçŸå Žãèã§æããŠãããããïŒããšã®æããããå®éã®éçºã§ãã¬ãã¥ãŒãã¡ã€ã³ã§æ
åœããŠããã¡ã³ããŒã«ãã¬ãã¥ãŒããã£ãŒãããã¯ããŸã§åããããæéãäœããŸãããåå ããŠãããåŠçã®å£°ãèããšãæ®æ®µã¯ã³ãŒããªã©ã®ææç©ã第äžè
ã«ã¿ãŠããããæ©äŒã¯å°ãªãããã§ãéåžžã«å¥œè©ã§ããïŒ ç©ã¥ããã®æ¥œãããæããŠããã ä»åã¯ãããŠã仿§èšèšã¬ãã¥ãŒãã岿ããŸãããæå³ãšããŠã¯ãèªåãã¡ã§èãæããã³ã³ãã³ããæ©èœãå®è£
ããŠåœ¢ã«ããŠããããšã®æ¥œãããæããŠããã£ãæ¹ããããããããã ãããšèããããã§ãã ããŒã éçºãäœéšããŠããã ãŠãšãã£ã³ã°ããŒã¯ã§ã¯ãããŒã ïŒçµç¹ïŒã§éçºãããšããã¹ã¿ã€ã«ã匷ã¿ãšããŠããŸãããäºãã®åŒ·ã¿ã匱ã¿ãã¿ããªã§äžã€ã®ãã®ãäœãäžããæ¥œãããæããŠãããããšã³ãžãã¢ãšããŠåãããšã®ã€ã¡ãŒãžãæã£ãŠããããããšèããŸããã å®éã«åå ããåŠçããã¯ãããŒã éçºãçµéšããããšã§ããšãŠãè¯ãäœéšãã§ãããããããŒã éçºã®é£ãããæããããšã®å£°ãå€ããããåŠçã«ãšã£ãŠãéåžžã«è¯ãçµéšã«ãªã£ãããïŒïŒ éå¶ããäžã§å·¥å€«ãããã€ã³ã æºåã¿ã¹ã¯ã®æŽç ä»åã¯ç€Ÿå
ã³ã³ãã宿œãããšããããšããããæºåæéã2é±éçšåºŠãããããŸããã§ããããã®äžã§éå¶äž»å°ã§èµãåããããã«åæ»ã«é²ããŠãããããã€ã³ã¿ãŒã³ãæåãããããã®å€§ããªéµãæ¡ããŸãã ã§ãããããããæãããšã³ãžãã¢ã®è
ã®èŠãæïŒïŒæ®æ®µã®éçºçµéšã掻ããããŸããïŒç¬ïŒ ãšã«ãããããã¹ãããšããªã¹ãåããŠæŽãåºããŸããããã®äžã§ã èªåãã¡ã§ã¯ã§ããªãïŒå¥éšçœ²ã«äŸé Œããªããã°ãªããªãã¿ã¹ã¯ ãããåªå
çã«äœæ¥ãããŠãããŸãã äŸãã°ã»ã»ã»äžèšã®ãããªã¿ã¹ã¯ã該åœããŸãã éçºç°å¢ã®æ§ç¯âSREããŒã â»1 ã€ã³ã¿ãŒã³çã䜿çšããPCã®æé
âISããŒã â»2 â»1 åŒç€ŸãµãŒãã¹ã®ã€ã³ãã©åšãã管çããŠããããŒã â»2 瀟å¡ã®PCãã¡ãŒã«ãªã©ç€Ÿå
æ
å ±ã·ã¹ãã ã管çããŠããããŒã ã¡ã³ã¿ãŒéã®æ
å ±å
±æ åããŒã ã«å°å±ã§2åã®ã¡ã³ã¿ãŒãä»ããŸãããèªããŒã 以å€ã®ç¶æ³ãææ¡ã§ããããã«ãã€ã³ã¿ãŒã³çãåž°å®
åŸã«æ¯æ¥æ¯ãè¿ãã宿œããŸãããéå¶å
šäœã§ãã©ããŒããŠãããäœå¶ã¥ãããæèããããšã«ãããä»ããŒã ãžã®ãã©ããŒãªã©ãå«ããåœæ¥ã®é²è¡ãéåžžã«ã¹ã ãŒãºã«é²ã¿ãŸããã 瀟å¡ãšã®ã³ãã¥ãã±ãŒã·ã§ã³ ã¡ã³ã¿ãŒç€Ÿå¡ãšã®ã³ãã¥ãã±ãŒã·ã§ã³ã¯å€ãåããŸããããã®ä»ã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã£ã¬ã¯ã¿ãŒãšäº€æµããæ©äŒã¯ããªããªããããŸããããã ãä»ååå ããŠãããåŠçã®äžã«ã¯ããã¶ã€ã³ãå匷ããŠããåŠçãWebéçºããã£ãããšããªãåŠçãããã®ã§ãããå€ãã®ç€Ÿå¡ãšäº€æµãããŠããããä»åŸã®å°±è·æŽ»åã®åèã«ããŠã»ãããšèããŠããŸããã ç¹ã«åŒç€Ÿã®ãªãã£ã¹ããã衚åéã¯ã©ã³ããçŸå³ããã®ã§ãæ¥æ¿ããã§ç€Ÿå¡ãšã©ã³ãã«è¡ã£ãŠããããŸãããã©ã³ãã®çŸå³ããã¯åŠçã®ã¿ããªãæ°ã«å
¥ã£ãŠãããããã§ãã仿¥ã¯ã©ãã«é£ããŠã£ãŠããããããªãŒïŒããšã¯ã¯ã¯ã¯ããŠããŸãããïŒç¬ïŒ éå¶ããäžã§èŠåŽãããã€ã³ã ã¡ã³ã¿ãŒç€Ÿå¡ã®ã¹ã±ãžã¥ãŒã«ç¢ºä¿ ã¡ã³ã¿ãŒãšããŠåå ããŠããã瀟å¡ã«ã¯ãããçšåºŠäºåã«ã¹ã±ãžã¥ãŒã«ã¯ç¢ºä¿ããŠããŸããããéåžžæ¥åãããããšãããå°ãè² æ
ãå€ãããã£ãŠããŸããŸããã ãã ãåŒç€Ÿã«ã¯ããããæãã ããŒã ã§ã«ããŒãã è¯ãããããŸããã¡ã³ã¿ãŒç€Ÿå¡ã¯èªåã®æéãç ç²ã«ããŠã§ããã€ã³ã¿ãŒã³ãåªå
ããŠåŸ¹åºçã«ãµããŒããããŠãããŸããã â»ã¡ã³ã¿ãŒä»¥å€ã®ç€Ÿå¡ãå¿æŽã«é§ãã€ããŠãã€ã³ã¿ãŒã³çããµããŒãããŠãããå Žé¢ãïŒïŒ ã©ããŸã§ãµããŒãããã¹ããã®ç·åŒã ã¡ã³ã¿ãŒãšããŠã®åœ¹å²ã¯ãã€ã³ã¿ãŒã³çãéçºã§ããããã«ãµããŒãããããšã§ãããã ãå
šãŠããµããŒãããŠããŸãã°è¯ãããšãããšããããšã¯éããŸããããããŸã§äž»åœ¹ã¯ã ã€ã³ã¿ãŒã³ã«æ¥ãŠãããåŠç ããªã®ã§ãã€ã³ã¿ãŒã³çã®æèŠãå°éãã€ã€ãç©äºãèãããã³ãã«ãªããããªããšãå¿æããŠãµããŒãããŸããã ãŸãšã ãããã§ããã§ããããïŒ ä»åã¯ããšã³ãžãã¢ã€ã³ã¿ãŒã³ã®éå¶ãéããŠãå€ãã®ããšãçµéšãåŠã¶ããšãã§ããŸããã®ã§ãã玹ä»ãããŠé ããŸããã ãã²ãããããã€ã³ã¿ãŒã³ãå§ããããšæã£ãŠããäŒæ¥æ§ãã€ã³ã¿ãŒã³ã®åå ããããšæã£ãŠããåŠçããã®åèã«ãªãã°å¹žãã§ãã ç¹ã«åŠçã®ã¿ãªããïŒãšã³ãžãã¢ã€ã³ã¿ãŒã³ã¯ãæ¯å¹Žè¡ãªã£ãŠãããŸãã®ã§ã æ¥å¹ŽåºŠã®åå ããåŸ
ã¡ããŠãããŸãïŒ åŒç€Ÿã®çŸåœ¹ãšã³ãžãã¢ã培åºããŠãµããŒãããŸããïŒ Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ãSREããŒã ããšã³ãžãã¢ã®è¥¿èïŒ@yasuhiro1711ïŒã§ãã仿¥ã¯ãããŒã éçšæ¹åã®è©±ãããããšæããŸããããããããŒã éçšãããŠããæ¹ã
ã«å°ãã§ãé¿ãã°ãããªãåèäºäŸã«ãªãã°ãããªããšæã£ãŠæžããŠãããŸããã¡ãªã¿ã«ãããŒããå€ããŠç¶ç·šãæžãäºå®ã§ãã®ã§æ¥œãã¿ã«ããŠããããã°ãšæããŸãã ããŒã ã«èª²é¡ãåºãŠæ¥ã ç§ã®SREããŒã ã¯ãããŸã§ã¯2人ãšå°æ°ç²Ÿéã§ãããããã«æšå¹Žå
šãéãèæ¯ãæã€ã¡ã³ããŒãå
¥ã£ãŠæ¥ãŸãããïŒã¡ãªã¿ã«SREããŒã ã«æ¹åããä»¶ãè¿ã
ã©ããã§æžãããšæããŸããïŒæåã¯ä»äºã®ããæ¹ãå€ããã«ãã£ãŠãããã®ã®ãä»äºãå¢ããŠé£æºããå Žé¢ãå¢ãããšã2人ã®ãšãã®é¿åœã®åŒåžã ãã§ã¯ã©ãããŠãåããªããªãããšãå¢ããŠããŸãããä»ã«ãæèã®ããéããªã©å¹Ÿã€ã課é¡ãåºå§ããŸãããé
ç®ã«ãããšãããªæãã§ãã å°æ°ã¡ã³ããŒã®ããã人ã«äŸåããã¿ã¹ã¯ãå€ãã£ãã ããŒã ã¡ã³ããŒå士ã§ã®çŸç¶ææ¡ãåºæ¥ãŠããªãã ã¿ã¹ã¯ã®å¯èŠåãåªå
åºŠã®ææ¡ãäžååã ããŒããããã®åªå
床ä»ãã匱ãã ãããããããŸã§ãããŠãªããŠåºãŠæ¥ã課é¡ãªã®ã§ãåãåã£ãŠé²ããã°ããã®ã§ããã ããŠãã©ããã£ãŠè§£æ±ºããŠããã®ã楜ãããããããªã楜ããé²ããããã®ã§ãã ããã ïŒ ãã¡ã¯Redmineã䜿ã£ãŠãã®ã§ã Redmineããã«æŽ»çšããã°ããããŒããŠãããããŠããçµæ§ããããã ãšæãã€ããŸãããæãã€ããã忥ã峿¥åããŸããã RedmineãæŽ»çšããã Redmineã§ããŒã ã®èª²é¡ã«å¯ŸããŠäœãã§ãããããããšãããŒã ã®éçšã¯ã©ãããã¹ãããæ
å ±åéããŠèããŠã以äžã掻çšããŠã¿ãŸããã远å ãããã©ã°ã€ã³ã¯3ã€ã ãã§ãã ãã«ã³ãã³æ¹åŒããå°å
¥ããã èª²é¡æãããäžçªã«ããããã£ãããšã¯ããã«ã³ãã³æ¹åŒããå°å
¥ããããšã§ãã æšå¹Žãªã©ã€ãªãŒããåºçãããŠããããã®æžç±ã§ãæåã§ãããã O’Reilly Japan – ã«ã³ãã³ä»äºè¡ https://www.oreilly.co.jp/books/9784873117645/ ãã®æžç±ã®äžã§ãããããŠããŸããããã«ã³ãã³æ¹åŒããåãå
¥ãããšå¹æã®ããç¶æ³ãšããã®ã¯ä»¥äžã®ãããªç¶æ³ã§ãã çŽæã«ããé
ãã èŠç©ãããäžæ£ç¢ºãªããšãå€ã ããŒã ã¯ä»äºã«è¿œãããŠãã åªå
床ãããåãããªã è²ã
ãªãšããããããŒã ã«ä»äºããã 誰ãäœããã£ãŠããã®ãããããããªã ãããŸãã«ããŒã ã®ç¶æ
ãããŒãæ··ä¹±ç¶æ
ã ããšæããŸããã ãããžã§ã¯ãã1人ãã€ã§è€æ°æ±ãããã®äžã§å
šãµãŒãã¹ã®éçšã»é害察å¿ãå
¥ãã賌買ãã»ãã¥ãªãã£å¯Ÿå¿ãããã©ãŒãã³ã¹ãã¥ãŒãã³ã°çãããŠããã®ã§ãä»äºã®å¹
ãåºããè€æ°äººã§ãããžã§ã¯ãå
šäœãèŠéãã®ã¯ãªããªã倧å€ãªç¶æ³ã§ããã ä»åã¯ããã«ã³ãã³æ¹åŒãå°å
¥ã«ããããRedmineã§ã¯æåãªãã©ã°ã€ã³ Redmine Agile plugin http://redmineup.com/pages/plugins/agile ãå©çšããŸããã slack飿ºããã ããã¯ããããã£ããããã£ãŠã¿ãŸããã slack飿ºããã©ã°ã€ã³ã§ç°¡åã«å¯èœã§ããéç¥ãé£ã°ãããšã§ããã±ãããwikiãªã©ã®æŽæ°æ
å ±ãå
¥æãããããªããŸããããå°å³ã«ä»ã®ã¡ã³ããŒããã®éç¥ãå€ããšãããããªã«ä»äºé²ãã§ããã®ãããšããåºæ¿ãåããŸãã Redmine Slack https://github.com/sciyoshi/redmine-slack å·¥æ°ç®¡çãèªåã§ããã ããŒã éçšã ãããããå·¥æ°ã®æŠå¿µãšãå·¥æ°ã®ã¬ãã«æãããŒã ã§å
±éèªèã§æã€ããã«ãå
šãŠã®ãã±ãããå·¥æ°ç®¡çããŠãããŸãã æåãªãã®ãã©ã°ã€ã³ãå°å
¥ããŸããã Redmine Work Time plugin http://www.redmine.org/plugins/redmine_work_time Redmineéçšã«ãŒã« ããããã©ã°ã€ã³ã§å®çŸã§ããå°æããããããããŸãããããããããŸããããŒã ã®å
±éã«ãŒã«ãäœããŸããã 1ãäŒç€Ÿã§æéã䜿ãäºãå
šãŠããã±ããåãããã ãããžã§ã¯ãã¿ã¹ã¯ãéçšã¿ã¹ã¯ã ãã§ãªããåäººã®æè¡æ€èšŒããåäººç®æšãžã®åãçµã¿ãå Žåã«ãã£ãŠã¯ãæ¥åã«ã¯é¢ä¿ãªã瀟å
ã¿ã¹ã¯ãçãŸã§ãã¡ã³ããŒãäŒç€Ÿã§æéã䜿ãããšã«ãªãã¿ã¹ã¯ãã¹ãŠããã±ããåããŠèŠããåãããŸãããã¡ããããã®ããã°ã®èšäºå·çããã±ããåããŠããŸãã ããããããšã§ãæ¥åãã±ããã§ããŒã ã¡ã³ããŒã«é²æãäŒããã®ã¯ãã¡ããã®ããšãå人ã¿ã¹ã¯ãããŒã ã®Redmineã§ç®¡çããããšã§ã仲éãä»ãäœãç®æšã«é 匵ã£ãŠãããäœã®æè¡ã远æ±ããããŠä»äºãããŠããã®ãåããããããªããããŒã ã¡ã³ããŒåå£«ã§æ¯ãåãããšãã§ããŸãã 2, å®äŸã§ã¯ãã£ãŠãããšãèªãåãããåšãã«åºæ¿ãäžãåããã çŸåšãé±1ã§å®äŸãããŠããŸããããã§ã¯ãã«ã³ãã³ããèŠãŠé²æç¢ºèªãåããŸãã ãŸãã¯åèªã®å®äºãã±ããã®å ±åããå§ããŸããèªåãå®äºãããã¿ã¹ã¯ãèžã匵ã£ãŠèªæ
¢ã説æããŠããããŸããæ¯é±ãã¡ã³ããŒãã©ãã ãã®ãã±ãããã©ã®ããã«å®äºãããŠããããèããããã®ã§ãé¡ã«ã¯åºããªããã®ã®åºæ¿ãããã£ãŠã¢ãããŒã·ã§ã³ã¢ããã«ãªã£ãŠãŸãã ã¢ãããŒã·ã§ã³ã¢ãã以å€ã«ãããã¹ããªãããããããªèãæ¹ãç¥ããåçºé²æ¢ãé²ãããªã©ãšãŠãè¯ãéçšã«ã€ãªãããŸãã 説æå®äºãããã®ã¯ãã®å Žã§ãå®äºã¹ããŒã¿ã¹ããããç¢ºèªæžã¿ãã®ã¹ããŒã¿ã¹ã«ããéçšã«ããŠããã®ã§ãããæ°ãå€ãã»ã©ãã«ã³ãã³äžã§ãã©ãã°ïŒããããããŠããã®ã¯å¿«æãèŠããŸãw ãã®åŸã¯æ
åœäžã¿ã¹ã¯ã®é²æç¢ºèªãæ°èŠæ¡ä»¶ã®è©±ãªã©ãããŸããããã±ããæ°ãå€ãããã®ã§ã§ããã ãçæéã§ããã€ã³ãã«çµã£ãŠé²ããŸãã å
šå¡ã§å
šäœãèŠãããšã«ãªãã®ã§ä¿¯ç°çã«ç©äºãèŠãããããã«ãªããŸããäººã«ææãããŠåããŠãããããšã人éã«ã¯çµ¶å¯Ÿã«ãããŸãããããªäž»èгã客芳ã«å€ããäœæ¥ã§ããããŸãã 3, äºå®å·¥æ°ãšå·¥æ°ã®èšé²ãé©åœã§ããã®ã§ã€ãããã ãããä»ãŸã§ãã£ãŠããªããšæ£çŽé¢åã§ããã§ãé©åœã§ããã®ã§ãã宿œã¿ã¹ã¯ã«ãããå·¥æ°èŠç©ããšãå®éã«ããã£ãå·¥æ°ãã¯èšé²ãããããã«ããŠããŸããé©åœãšããã®ã倧äºã§ããå
¥åã®ç²Ÿç¥çã³ã¹ããäžããããã«å¿
èŠã ãšæã£ãŠããŸããã§ããã ããèªç¶ã«èšé²ãä»ããããããã«å
¥åã«ãŒã«ãã·ã¹ãã åãããããäºãææããããäžåºŠèšé²ãã€ããçãã€ããã°ãå°ããã€èŠã§ã¯ãªããªã£ãŠããŠããŸããïŒãŸã èŠã§ã¯ãããŸãïŒããã¯ã¡ã³ããŒã«ã¯èªåã®èŠç©ã®ç²ŸåºŠããããŠããã®ã«åœ¹ç«ã¡ãŸããããããŒãžã£ãŒãããããšããŒã ã®çç£æ§ãèããäžã§éåžžã«æå¹ãªããŒã¿ãšãªããŸãã å°å
¥ã®çµæ éçšã倿ŽããŠãã£ãçµæãææãåºãŠããŸããã ä»äºãèŠããåãããã é ããŠèŠããªãã£ãä»äºãèŠããäºã§ã誰ãäœãã©ã®ãããããŠããã®ãããRedmineãèŠãã°ãããããã«ãªããŸããããã±ããã®é²æããèŠãã°ãæ¥ãªä»£ææ¡ä»¶ã§ãããªããŸãã ã¿ã¹ã¯ã®æµããæç¢ºã«ãªã£ãã ã¯ãŒã¯ãããŒã§ã¹ããŒã¿ã¹ç®¡çããããšã§ãä»äºé²æãè¯ãã®ããæªãã®ããã©ã®ã¹ããŒã¿ã¹ã§æ¢ãŸããããã®ãããŸããå€éšã®ããŒã ããã®ä»äºã®äŸé Œããå®äºã®ç¢ºèªãŸã§ã®ãããŒãåããããããªããŸããããŸããWIPå¶éãããäºã§ãã¡ã³ããŒå士ã§ä»äºéã調æŽãåãæåãçãŸããŸããã â»ãWIPå¶éãšã¯ãæ
åœäžã®ã¿ã¹ã¯ã®äžéæ°ã決å®ãããããè¶
ããªãããã«éçšããŠããããšã§ããæ°ãæãããããããxxãããæ¥åå€ããªãïŒãã£ãŠäŒè©±ãçãŸãããããã®ãæå€ãšå€§äºã§ãã ã¡ã³ããŒã®èªäž»æ§ã倧ãã䌞ã³ãã å
šå¡ããªãŒããŒã®ããã«ãäž»äœçã»èªäž»çãªåããããããåãããã«ãªã£ããšæããŸããããã«ããå°ããªæ
å ±ã§ããã±ãããã³ã¡ã³ãã«æ
å ±ãéãŸãããã«ãªããæ
å ±æŽçã®æéãççž®ã§ããŠããŸãããŸããä»ã®ã¡ã³ããŒã®ã¿ã¹ã¯ãžã®ã³ã¡ã³ããæŽ»çºã«ãªãçµæãããŒã ã§å質ãäžãã£ãŠããŸãã å€åããŠããããšã楜ãããããã«ãªã£ãã ãã®éçšãããŠãããšãæ¹åããŠããããšã楜ãããããã«ãªããŸããäœããé²ããŠææã«ãªãããšã楜ãããªã£ãŠããŸãã ããŒã ã®ä¿¡é ŒåºŠã¢ãã ãäºãã®ã¿ã¹ã¯ãèŠããŠããããšã¯ãèªç¶ãšãäºãã®ä¿¡é ŒåºŠãäžããŠãããŸãããã®éçšãããŠãããšèªç¶ã«ä¿¡é ŒåºŠã¯äžãã£ãŠããŸããã 以äžã®çµæãããæåã®èª²é¡ãèŠçŽããŠã¿ããšãã å°æ°ã¡ã³ããŒã®ããã人ã«äŸåããã¿ã¹ã¯ãå€ãã£ãããâã¯ãªã¢ïŒ ããŒã ã¡ã³ããŒå士ã§ã®çŸç¶ææ¡ãåºæ¥ãŠããªãããâã¯ãªã¢ïŒ ã¿ã¹ã¯ã®å¯èŠåãåªå
åºŠã®ææ¡ãäžååããâã¯ãªã¢ïŒ ããŒããããã®åªå
床ä»ãã匱ãããâã¯ãªã¢ïŒ ããŒãïŒ ä»åã¯2ã¶æã»ã©ã®æ¥ã
ã®æ¹åã§ãããŸã§åºæ¥ãŸããã ãŸãæ¬¡ã®æ°ãã課é¡ãèŠããŠããã®ã§ã次åã¯ãããžã®åãçµã¿ãã話ãã§ããããšæããŸãã ãŸãšã ä»åããŒã éçšæ¹åãããŠã¿ãŠæãããšã¯ããä»äºãææãèŠããåããããšã¯ãåšãã«åºæ¿ãäžããããšããããšã§ãã人ã¯åºæ¿ãããã£ãŠã¢ãããŒã·ã§ã³ã«å€ããŠåãçãç©ã§ãã®ã§ãåºæ¿ã倧äºãšããã®ãæ¹ããŠããåãããŸãããä»åã¯ããŒã éçšæ¹åã®ãã·ãªã§ãã®ã§ããã£ãšéçšçµéšã貯ããŠã©ãã©ãããã°ã§ãå
¬éããŠãããããšæããŸãããå·¥æ°ãã€ããŠããã®ã§ãä»åŸã¯äœæ¥ã®ãªãŒãã¿ã€ã ãã¹ã«ãŒããããã¯ãããçç£æ§ã¢ããã«æ³šç®ããŠèŠãŠã¿ãããšæã£ãŠããŸãã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ããµãŒããŒãµã€ããšã³ãžãã¢ã®è
åã§ãã ä»åã¯JavaScriptã®éåæåŠçã«ã€ããŠä»æŽãªããåŠãã§ã¿ãŸãããæãªããã®CallbackãES6ãã远å ãããPromiseãES7ãã远å ãããasync awaitãããã«ã¯RxJsã«ã€ããŠã調ã¹ãŠã¿ãŸããã èæ¯ æšä»ã¯UXã®éèŠã®é«ãŸãããéåæåŠçãæžãããšãå€ããªãããªã¢ã«ã¿ã€ã æ§ããã£ããæ©èœãããã©ãŒãã³ã¹æ¹åã®ããã«ãéåæåŠçã®ã³ãŒããæžãããšãå¢ããŠããŸãããã éåæåŠçã®JavaScriptã®ã³ãŒãã¯åŠçãå¢ããããšã«ã³ãŒã«ããã¯å°çãšåŒã°ããå¯èªæ§ãæãªãããå±éºæ§ãããããšãäºå®ã§ãã ä»åã¯ä»¥äžã®ããã°ã©ãã³ã°æ¡ä»¶ããéåæåŠçã«ã€ããŠç°¡åãªã³ãŒããçšããŠã®ç޹ä»ãšè£è¶³ã§RxJsãçšããéåæåŠçã玹ä»ããŠãããŸãã å®è¡ããã°ã©ã ã®æ¡ä»¶ 1, èªèšŒãŠãŒã¶ããã§ãã¯ãè¡ãã 2, 1ãæåãããšãŠãšãã¡ããã衚瀺ããã 3, 1,2ãé ã«å®è¡ããã ãŠãšãã¡ãã ãŠãšãã£ã³ã°ããŒã¯å
¬åŒãã£ã©ã¯ã¿ãŒã§ãã ãŠãšãã£ã³ã°ããŒã¯ã®ãµã€ããªã©ã§ã掻èºããŠããŸãã CallbackãçšããéåæåŠç ããã¯éåæåŠçã§ãåºæ¬çãªCallbackãããŠããJavaScriptã³ãŒãã§ãã â â¡ãšãã«setTimeoutã®äžã§cbã¡ãœããã䜿ãCallbackããŠããŸãã â¢ã®å®è¡ã§ã¯checkAuthã®é¢æ°ãåŒã³åºããäžã«ãã¹ãããŠfetchWpã®é¢æ°ãåŒã³åºããŠããŸãã 以äžã®ã³ãŒãéã®æã¯ç¹ã«å¯èªæ§ãæªãã¯ãªãã§ããã远å ãã颿°ãå¢ããã°å¢ããã»ã©ãã¹ããæ·±ããªã£ãŠããŸããå¯èªæ§ããªããªãåé·ãªãœãŒã¹ã«ãªã£ãŠããŸããŸãã // â èªèšŒãŠãŒã¶ããã§ãã¯ãè¡ãã const checkAuth = cb => { console.log('Checking Auth...') setTimeout(() => { cb(true); }, 2000); }; // â¡ãŠãšãã¡ããã衚瀺ããã const fetchWp = cb => { console.log('Fetching WP...') setTimeout(() => { cb({ name: "ãŠãšãã¡ãã" }); }, 2000); }; // â¢å®è¡ checkAuth(auth => { if (auth) { fetchWp(wp => { console.log(wp.name) }); } }); PromiseãçšããéåæåŠç (ES6) ES2015(ES6)ãã远å 仿§ãšããŠå ãã£ãPromiseã Promiseã¯3ã€ã®ç¶æ
(resolve, reject, done)ãæã¡ãŸãã â â¡ã®é¢æ°ãPromiseã§ãªããžã§ã¯ãã«ã©ããããŠãããŸãã â¢ã®å®è¡æã«thenãšãããã§ãŒã³ã¡ãœããã§ãã®åŸã®åŠçãèšè¿°ããŸãã ç¶ããŠåŠçãæžãå Žåãã¡ãœãããã§ãŒã³ã§ã€ãªããŠããããšã§ãã¹ããæ·±ããªããã«ã³ãŒãããã£ããããã§ããã // â èªèšŒãŠãŒã¶ããã§ãã¯ãè¡ãã const checkAuth = () => { return new Promise((resolve, reject) => { console.log('Checking Auth...'); setTimeout(() => { resolve(true); }, 2000); }); }; // â¡ãŠãšãã¡ããã衚瀺ããã const fetchWp = () => { return new Promise((resolve, reject) => { console.log('Fetching Wp...'); setTimeout(() => { resolve({ name: "ãŠãšãã¡ãã" }); }, 2000); }); }; // â¢å®è¡ checkAuth() .then( isAuth => { if (isAuth) { return fetchWp() } } ) .then( wp => { console.log(wp.name) } ) async awaitãçšããéåæåŠç (ES7) ES2016(ES7)ãã远å 仿§ãšããŠå ãã£ãasync await Promiseãšå
±åããŠäœ¿çšã§ããŸãã â â¡ã§Promiseã§ã©ããããâ¢ã®å®è¡æã«asyncã®äžã§awaitã§é¢æ°ãåŒã³åºããŠããŸãã awaitã¯asyncã§å®çŸ©ããã颿°å
ã«ãã䜿ããŸããããŸãéåžžã®ã³ãŒã«ããã¯ãNodeã³ãŒã«ããã¯ã¯å
±çšã§ããŸãããawaitã¯é¢æ°ã®å®è¡ãçµãããŸã§åŸ
æ©ããŸãããŸãPromiseã§ã©ããããŠããç®æãasync颿°ã§å®çŸ©ããããšãå¯èœã§ãããã®å Žåasync颿°ãæé»çã«Promiseãè¿ãã颿°ã®æ»ãå€ãPromiseã®åŠçå®äºã®å€ã«ãªããŸãã // â èªèšŒãŠãŒã¶ããã§ãã¯ãè¡ãã const checkAuth = () => { return new Promise((resolve, reject) => { console.log('Checking Auth...'); setTimeout(() => { resolve(true) }, 2000) }) } // â¡ãŠãšãã¡ããã衚瀺ããã const fetchWp = () => { return new Promise((resolve, reject) => { console.log('Fetching Wp...'); setTimeout(() => { resolve({ name: "ãŠãšãã¡ãã" }); }, 2000) }) } // â¢å®è¡ (async function(){ const isAuth = await checkAuth() let user = null; if (isAuth) { wp = await fetchWp() } console.log(wp.name); })(); RxJsãçšããéåæåŠç (è£è¶³) è£è¶³ã«RxJs(Reactive Extensions)ãçšããŠã³ãŒããæžããŠããŸãããObserverãã¿ãŒã³ãã§ã€ãã³ããããŒã¿ãã¹ããªãŒã ãšããŠæ±ããããšããããã°ã©ãã³ã°ã®å¯èªæ§ãåäžãããŠããŸããéçºå
ã¯Microsoftã§ãããã©ã€ãã©ãªãšããŠã®ä¿¡é Œæ§ããããŸããã³ãŒãã§ã¯Observable.createã§ããŒã¿ãäœãObservableããã³ããªã³ã°ããæåŸã«subscribeã§åºåããŠããŸãã // â èªèšŒãŠãŒã¶ããã§ãã¯ãè¡ãã const checkAuth = () => { return Rx.Observable.create(observer => { console.log('Checking Auth...') setTimeout(() => { observer.next(true); }, 2000); }) }; // â¡ãŠãšãã¡ããã衚瀺ããã const fetchWp = () => { return Rx.Observable.create(observer => { cosole.log('Fetching Wp...'); setTimeout(() => { observer.next({name: 'ãŠãšãã¡ãã'}); }, 2000); }) }; // â¢å®è¡ Rx.Observable.of(true) .switchMap(event => checkAuth()) .switchMap(isAuth => { if (isAuth) { return fetchWp() } }) .subscribe(wp => { console.log(wp.name); }) ãŸãšã ãããã§ããã§ããããïŒéåæåŠçã ãã§æ§ã
ãªæžãæ¹ãã§ããŸãã å人çã«ã¯ES7ã®async awaitãä»åŸäž»æµã«ãªã£ãŠããã®ã§ã¯ãšæããŸããããPromiseãå°å
¥ãããŠããå¯èªæ§ãäžæ°ã«äžãã£ãã®ã§Promiseã§ãåé¡ãªããšæããŸãããç¹ã«ES7ãå°å
¥ããŠããªããµã€ããªã©ãããã®ã§Promiseã§è³ã£ãŠãããã®ã§ã¯ãªãããšæããŸãããŸããã©ã³ã¹ãã€ã©ãå°å
¥ããŠããªããŠãjQueryã®Defferd+Promiseã§ããçšåºŠã«ããŒã§ãããšæããŸããã ãŸã ãŸã ç±ãéåæåŠççéã§ããçããããã²è©ŠããŠã¿ãŠãã ããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
ããã«ã¡ã¯ããµãŒããŒãµã€ããšã³ãžãã¢ã®@akane_256ã§ãã 仿¥ã¯ãHeadless Chromeã䜿ã£ããã©ãŠã¶ãã¹ãã®èªååïŒå
¥éïŒã«ã€ããŠæžããããšæããŸãã ç®æ¬¡ Headless Chromeãšã¯ïŒ èå³ãæã£ãèæ¯ ä»åãã£ãããš å®éã®ãœãŒã¹ã³ãŒã ãŸãšã Headless Chromeãšã¯ïŒ Chrome59ïŒ2017/6æé ïŒããæèŒãããæ©èœ ChromeãGUIãªãã§ã³ãã³ãã©ã€ã³ããå®è¡ã§ãã DOMã®ããŒããååŸããããç»é¢ãã£ããã£ãæ®ã£ããã§ãã ããŒã«ãšçµã¿åãããŠèªåãã¹ãã«äœ¿ã£ãããã ãã©ãŠã¶ãéããŠãç¹å®ã®ããŒãžãéããèªåã§ç®èŠç¢ºèªããªããŠãã ãããããäœã£ãããã°ã©ã ãã³ãã³ãããå®è¡ãããã° èªåã§ãã£ããã£ããšã£ããæå®ã®èŠçŽ ãååŸãããããããšãã§ããŸãã èå³ãæã£ãèæ¯ ç§ã¯æ®æ®µ Ringraph ãšããçµå©æèŒªã»å©çŽæèŒªã®å£ã³ããµã€ãã®éçºãããŠããŸãã ãµã€ãã¯æ¯é±ã®ããã«ãªãªãŒã¹ããããæ¥ã
æ¹åãããŠããŸãã ãªãªãŒã¹ãããéã«ãã¹ãã宿œããŠããŸããã ããŒãžããã¡ããšè¡šç€ºãããŠã㊠åºãã¹ãèŠçŽ ãåºãŠããããš ãŠãŒã¶ãŒãã°ã€ã³ã»å£ã³ãã®æçš¿ããã¡ããšã§ããããš ãªã©ãªã©ã確èªããããšã¯ããããããããããæ¯å確èªããã®ã¯ãšãŠã倧å€ã§ãã ãã¹ãã®è² æ
ãæžããããšã³ãžãã¢ã®å¿ã®è² æ
ãå°ãã§ãæžããããã®ã§ïŒç¬ïŒã å°ããã€èªååã§ããªãããªããšæã£ãŠèª¿ã¹ãŸããã ä»åãã£ãããš ä»åã¯å
¥éç·šãšããããšã§ããšãŠãã·ã³ãã«ã§ããã Headless Chromeã䜿ã£ãŠè€æ°ããŒãžã®titleã®ããã¹ããååŸããããã°ã©ã ãäœæããŸããã ããã ãã§ããå¿çšããã°titleãdescriptionãããŒãžã®èŠçŽ ã®äžèº«ã®ç¢ºèªçãèªåã§ããã®ã§ãå®éã«éçšã§ããã䟿å©ã§ãã å®éã®ãœãŒã¹ã³ãŒã ä»åã¯ã PuppeteerïŒãããã£ã¢ãŒïŒ ãšããã©ã€ãã©ãªã䜿ã£ãŠéçºãããŸããã PuppeteerïŒãããã£ã¢ãŒïŒ ãšã¯ãGoogleãéçºã»å
¬éããŠããHeadless Chromeãæäœããããã®Node.jsã®ã©ã€ãã©ãªã§ãã ããã¥ã¡ã³ããããããããã䜿ããããã§ãã JSãªã®ã§ããã³ããšã³ãžãã¢ããã¯äœ¿ããããã®ã§ã¯ãªãã§ããããã ãããChromeãéçºããŠããGoogleã®å
¬åŒã©ã€ãã©ãªãªã®ã§ããšãŠãå®å¿æããããŸããæè¿ãéçºãçãã«è¡ãããŠããããã§ãã https://github.com/GoogleChrome/puppeteer Puppeteerãå©çšããã«ã¯ãNode.js v6.4.0以äžãšã Node.jsã®ããã±ãŒãžç®¡çããã yarn ããã㯠npm ãå¿
èŠã§ãã ãªãå Žåã¯ã€ã³ã¹ããŒã«ãå¿
èŠã§ãã ä»åã¯äžèšã®ããŒãžã§ã³ã§è©ŠããŸããã <br />node -v node v8.4.0 yarn --version 0.27.5 æ©éã詊ããŠã¿ãŸãã ãŸãã¯é©åœã«ãã£ã¬ã¯ããªãäœæã»ç§»åããŸãã ãã£ã¬ã¯ããªå
ã§ yarn ã®ã³ãã³ããå®è¡ããŸãã <br />mkdir puppeteer_test cd puppeteer_test yarn add puppeteer yarn add ãå®è¡ããããšã¯ã package.json ãšããããã±ãŒãžã管çããããã®ç®¡çãã¡ã€ã«ãäœæãããã®ãšã node_modules ãã£ã¬ã¯ããªé
äžã«ã puppeteer ãšäŸåã¢ãžã¥ãŒã«çŸ€ãã€ã³ã¹ããŒã«ãããŸãã æ¬¡ã«ãããã°ã©ã ãæžããã¡ã€ã«ãäœæããäžèº«ãèšè¿°ããŠãããŸãã <br />touch main.js vi main.js äžèº«ã®ã€ã¡ãŒãžãå
¬åŒã®GitHubã«ããµã³ãã«ã³ãŒããèŒã£ãŠããŸãã <br />const puppeteer = require('puppeteer'); // URL you want to access const urls = [ 'https://example.com', 'https://www.google.com' ]; const title = []; (async () =&gt; { // The method launches a browser instance with given arguments. const browser = await puppeteer.launch(); // return new page object const page = await browser.newPage(); for(i = 0; i &lt; urls.length; i++){ await page.goto(urls[i], {waitUntil: 'networkidle2'}); // add title to array title.push(await page.title()); } console.log(title); browser.close(); })(); ãã¡ã€ã«ãäœæã§ããããæåŸã«å®è¡ããŸãã ããŸããããšãããã°ã©ã ã§æå®ããWebãµã€ãã®ã¿ã€ãã«ã¿ã°ãconsoleã«è¡šç€ºãããŸãã <br />node main.js [ 'Example Domain', 'Google' ] ã€ã³ã¹ããŒã«ãããã¡ã€ã«äœæã»å®è¡ãŸã§ãã·ã³ãã«ã§ãçµæ§ç°¡åã«ã§ããŸããã ãŸãšã ä»ã«äºã€ããã詊ããŸãããPuppeteerãäžçªç°¡åããã§ããã«åããŸããã ïŒ Lighthouse ãšãããšããäžã€ããã詊ããŸãããïŒ ãã¹ãã±ãŒã¹ãæžãã°å®éã«éçšã§ãããã§ãäœ¿ãæ¹ãã·ã³ãã«ã§ãã Puppeteerã¯APIã®ããã¥ã¡ã³ãããã£ããæžããŠãããã©ãŠã¶ãã¹ãå
¥éè
ã«ãããããããã§ãã ä»åŸã¯ãJSã絡ãã æäœã®åäœç¢ºèªããããã§ãã èªãã§ãã ãããããããšãããããŸããã Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ
çµå©åçãæ®åœ±ã§ããã¹ã¿ãžãªæ€çŽ¢ãµã€ããPhotoraitãæ
åœãšã³ãžãã¢ã®æŠç°(@takedajs)ã§ãã å
æ¥ãèªåãæ
åœããŠããPhotoraitã§ã¹ã¿ãžãªãæ¢ãå®éã«çµå©åçãæ®åœ±ããŠããŸãããèªåãæºãã£ãŠããµãŒãã¹ããŠãŒã¶ãšããŠäœ¿ãã®ã¯ãææ
šæ·±ãã§ããïŒäžã€å€¢ãå¶ããŸããæ¶ ããŠæ¬é¡ã§ãã æè¿Firefoxã®å€§ããªããŒãžã§ã³ã¢ãã(Firefox Quantum)ããããããŒãžèªã¿èŸŒã¿é床ã®å€§å¹
ãªæ¹åãªã©ãããŸãããããã®äžæ¹ã§ææ°ã®éçºææ³(以äžãWebExtensions)ã§ã¯ãªãFirefoxã¢ããªã³ãå©çšã§ããªããªããŸãããåã®å Žåãå©çšããŠããFirefoxã¢ããªã³ãå
šãŠå©çšäžå¯ã«ãããããžãããã ããã§ä»åã¯ãææ°ã®Firefoxã§ãå©çšã§ãããäœæ¥ãã¹ãæžããFirefoxã¢ããªã³ãéçºãå
¬éããŸããã®ã§ç޹ä»ããŸãïŒã¿ãŒã²ãããŠãŒã¶ãå°ãªããšæãã®ã§ãããªãããããªã¢ããªã³ã§ãç¬ éçºããã¢ããªã³ éçºããFirefoxã¢ããªã³ãTabColorãã¯ãæå®ããããŒã¯ãŒãã衚瀺ããããŒãžã®URLã«å
¥ã£ãŠãæããã©ãŠã¶ã®ã¿ãå
šäœãèµ€ãããã·ã³ãã«ãªã¢ããªã³ã§ãã TabColor â Firefox åãã¢ããªã³: https://addons.mozilla.org/ja/firefox/addon/tabcolor/ äŸãã°ãããŒã¯ãŒãã«ãwikipediaããšå
¥åããŸãã 衚瀺ããŠããURLã«ãwikipediaãããããšãæ£èŠè¡šçŸã§ãããããããã®ããã«ã¿ãå
šäœãèµ€ãããŸãã éçºããçç± æ¬çªç°å¢ã§ããããšã«æ°ã¥ããã«ãééããŠäœæ¥ããŠããŸããã¹ããªããããã§ãã Photoraitã§ã¯ãŠãŒã¶ãæ®åœ±ã¹ã¿ãžãªã«è³æè«æ±ãæ¥åºäºçŽãè¡ãããæããµã€ãäžã®ãã©ãŒã ããç³èŸŒãè¡ãããšãã§ããŸããç³èŸŒããã床ã«ã該åœã®æ®åœ±ã¹ã¿ãžãªå®ã«ã¡ãŒã«ãéãããŸãã ãã©ãŒã ã¯ãŠãŒã¶ããªãã£åäžã®ããã«æ¹ä¿®ãæ©èœè¿œå ãããããšãå€ããéçºããåºŠã«æ£ããç³èŸŒãã§ãããã©ããéçºç°å¢ã§ãã¹ããããŠããŸãã ããããã®æã®ãã¹ããäœãã®ééãã§éçºç°å¢ã§ã¯ãªãæ¬çªç°å¢ã§è¡ã£ãŠããŸã£ãå Žåãæ®åœ±ã¹ã¿ãžãªã«ãã¹ãã§å
¥åããæ
å ±(XSSãã¹ãçšã®æåãªã©)ãéãããŠããŸãããµã€ãéå¶ã®ä¿¡é Œã«é¢ãã£ãŠããŸãã 以äžã«éçºç°å¢ãšæ¬çªç°å¢ã®ãã©ãŒã ç»é¢ã䞊ã¹ãŠã¿ãŸãããURL以å€ã«å€§ããªéãããªããéçºç°å¢ãã©ããäžç¬ã§å€æããããšãã§ããããã¹ãèµ·ããå¯èœæ§ããããŸããã å·Š: éçºç°å¢ å³: æ¬çªç°å¢ (ç»åã¯ã»ãã¥ãªãã£çã«URLãæžããŠããã¢ãã¬ã¹ããŒã衚瀺ãããŠããŸãããããã®ãšãã¿ãã¯èµ€ã衚瀺ãããŠããŸããã) ãã®ãããªæã«ãTabColorãå©çšããŠæ¬çªç°å¢ã ãèµ€ãããã°ãæ¬çªç°å¢ã§ãªãããšãäžç¬ã§å€æã§ããã®ã§ãã¹ãéããªã0ã«ã§ããŸãã å®éã«åã¯ããã¿ãå
šäœãèµ€ããªã = æ¬çªç°å¢ããšããããã«ã以äžã®ããŒãžãèµ€ããªãããŒã¯ãŒããTabColorã«ç»é²ããŠããŸãã ã»æ¬çªç°å¢ã®å
¬éãµã€ãããŒãž ã»æ¬çªç°å¢ã®ç®¡çç»é¢ããŒãž ã»æ¬çªç°å¢ã®phpMyAdmin phpMyAdminã¯éçºç°å¢ãšæ¬çªç°å¢ã§ãµã€ãèªäœã®ãã¶ã€ã³ãå€ããŠããŸããã念ã®ããã¿ãå
šäœãèµ€ããªãããã«ããŠããŸãã äžèº«ã®èª¬æ 倧ãŸãã«ã§ããå®è£
éšåã«ã€ããŠèª¬æããŠãããŸããWebExtensionsã§ã¯ãæ§ã
ãªæ©èœããã£ãJavaScript APIãæäŸãããŠãããTabColorã§ã以äžã®2ã€ã®APIãäž»ã«å©çšããŠãŸãã ã»storage API – ããŒã¯ãŒããä¿åæã«å©çš ã»theme API – ã¿ãå
šäœãèµ€ãããæã«å©çš ãã¡ã€ã«æ§æ 以äžã¢ããªã³ã®ãã¡ã€ã«æ§æã§ãã % tree . âââ background.js /* ã¿ããèµ€ãããåŠç */ âââ icons â âââ tab_color_30.png â âââ tab_color_60.png âââ manifest.json âââ popup /* ããŒã¯ãŒãå
¥åãã©ãŒã é¢é£ */ â âââ keyword_save.css â âââ keyword_save.html â âââ keyword_save.js /* ããŒã¯ãŒãç»é²åŠç */ âââ tab_red.jpg takedajs/TabColor: https://github.com/takedajs/TabColor ããŒã¯ãŒãç»é²åŠç keyword_save.jsã§ã¯ãããŒã¯ãŒãã®ç»é²åŠçãè¡ã£ãŠããŸãã ã»storageã«ä¿åãããŠããããŒã¯ãŒããããå ŽåãããŒã¯ãŒããvalueã«èšå®ããŠãã©ãŒã ãäœæããŠããŸãã ã»ãã©ãŒã ã®ä¿åãã¿ã³ãæŒäžãããæãstorageå
ã®ããŒã¯ãŒããå
šãŠåé€ãããã©ãŒã ã«å
¥åãããŠããããŒã¯ãŒããstorageã«ä¿åããŠããŸãã keyword_save.js //ããŒã¯ãŒããç»é²ããããã®ãã©ãŒã ãäœæ var storage_keywords = []; browser.storage.local.get('value', function(items) { storage_keywords = items.value; }); window.setTimeout( function(){ // ããŒã¯ãŒãç»é²ãã©ãŒã äœæ for (var i=0; i &lt; 10; i++) { var input = document.createElement("input"); input.setAttribute("type","text"); input.setAttribute("class","text"); // ç»é²ãããŠããèŠçŽ ãããå Žå if (storage_keywords != undefined) { input.setAttribute("value", storage_keywords[i]); } document.getElementById("keywords").appendChild(input); } }, 300 ); // ããŒã¯ãŒããã¹ãã¬ãŒãžã«ä¿å document.addEventListener("click", function(e) { if (e.target.classList.contains("save")) { // ã¹ãã¬ãŒãžå
ã®ããŒã¿ãåé€ browser.storage.local.remove("value"); var keywords = document.getElementsByClassName("text"); var array_keywords = []; for (var i = 0; i &lt; keywords.length; i++) { array_keywords.push(keywords[i].value); } browser.storage.local.set({'value': array_keywords}, function() {}); browser.tabs.reload(); alert("Completion of registration"); } }); ã¿ããèµ€ãããåŠç ãã®åŠçã®å®è£
ã¯è©Šè¡é¯èª€ããŸããã 詊è¡é¯èª€â åœåTabColorã¯ãWebExtensionsã§ã¯ãªãå€ãéçºææ³ã§ããAdd-on SDKãå©çšããŠéçºããŸãããã¿ãå
šäœãèµ€ãããçŸåšãšã¯éãã該åœããããŒãžã®ã¿ãã ããèµ€ãããŠããŸããã ããã¯XPCOMãšããä»çµã¿ãå©çšããFirefoxã®ãã¶ã€ã³ã倿Žã§ãããŠãŒã¶ã®ããŒã«ã«ãã¡ã€ã«ã§ããuserchrome.cssãäžæžãããšã§è¡šçŸããŠããŸãããã§ãããWebExtensionsã§ã¯XPCOMãå©çšäžå¯ã«ãªããæå®ã®ã¿ãã ãèµ€ãããããšãæå¿µããããšã«ã 詊è¡é¯èª€â¡ WebExtensionsã§éçºãçŽããåœåã¯ã以äžã®ããã«ã¿ãã§ã¯ãªããµã€ãã®å·ŠåŽãèµ€ãããè¡šçŸæ¹æ³ããšã£ãŠããŸããã Javascriptã§bodyã¿ã°ã«ä»¥äžã®styleã远å ãåé€ããã ããªã®ã§ç°¡åã«å®è£
ã§ããŸãã border-left: solid 15px red; 瀟å
LTäŒã§ãã®æã®TabColorã玹ä»ããã®ã§ãããããµã€ãã®ã¬ã€ã¢ãŠãã厩ãããã䜿ããªãç¬ããšã®æž©ãã声ã倿°é ããã®ã§ããç°¡åãªå®è£
ã«éãããäœãšãããŠã¿ããèµ€ããããïŒïŒããšãã®æ¥ã¯æãæ¿¡ãããªããæ±ºæããã®ãä»ã§ãèŠããŠããŸãã 宿ç ããŒã«ã«ãã¡ã€ã«ã®userchrome.cssã¯äžæžããªãã®ã§ãä»£æ¿æ¡ã¯ãªãããšæäŸãããŠããJavaScript APIäžèЧãçºããããæ¢ã«å
¬éãããŠããFirefoxã§åæ§ã®å®è£
ãããŠãããã®ã¯ãªãã調æ»ããŸããããã®çµæãããŒããšããŠèµ€ãèæ¯ãèšå®ããããšã§å®è£
ãå¯èœã§ãããšåãããŸããã ããŒããšã¯ããã©ãŠã¶ãŒã®ãã¶ã€ã³ãå€ãããããã®ããŒãã§ãã theme API ãå©çšããããšã§ãèªåãäœæããç»åãããŒããšããŠãã©ãŠã¶ã«èšå®ã§ããŸãã以äžã®èµ€ã暪é·ç»åãèšå®ããããšã§ãã¿ãã®èæ¯ã ãèµ€ããªã£ãŠããããã«ããŸãããŠããŸããç»åã®é«ãã¯ãã¿ãã®é«ããäœåºŠã枬ã£ãŠåãé«ãã«ãªãããã«è¯ãæãã«èšå®ããŠããŸããã¡ãªã¿ã«ãé«ã32px x å¹
2500px ãè¯ãæãã§ããã background.jsã§ã¯ãããŒã¯ãŒãã«ãããããURLã®ããŒãžãã¢ã¯ãã£ãã«ãªã£ãæãå
çšèª¬æããèµ€ãæšªé·ç»åãããŒããšããŠèšå®ããŠããŸãããããããªãURLã®ããŒãžãã¢ã¯ãã£ãã«ãªã£ãæã¯ãããŒããåé€ããŠããŸãã background.js // ã¿ããèµ€ãèŠããããŒã const themes = { images: { headerURL: '../tab_red.jpg', }, colors: { accentcolor: '#F9F8F8', textcolor: 'black', } }; // ã¿ããæŽæ°ãããæ browser.tabs.onUpdated.addListener((id, changeInfo, tab) =&gt; { url_match(tab); }); // ã¿ããã¢ã¯ãã£ãã«ãªã£ãæ browser.tabs.onActivated.addListener((activeInfo) =&gt; { var active_tab = browser.tabs.get(activeInfo.tabId); active_tab.then((tab) =&gt; { url_match(tab); }) }); // ããŒãèšå®ãåé€åŠç function url_match(tab) { var storage_keywords = []; browser.storage.local.get('value', function(items) { storage_keywords = items.value; }); window.setTimeout( function(){ // çŸåšèŠãŠããããŒãžããç»é²ããããŒã¯ãŒãã«äžèŽãããç¢ºèª var isMatch = false; for (var i = 0; i &lt; storage_keywords.length; i++) { if (storage_keywords[i]) { var regexp = new RegExp(storage_keywords[i], 'i'); isMatch = regexp.test(tab.url); if (isMatch) { break; } } } if (isMatch) { browser.theme.update(themes); } else { browser.theme.reset(); } }, 300 ); } ãŸãšã äœæ¥ãã¹ãæžããããã«éçºããFirefoxã¢ããªã³ãTabColorãã®ç޹ä»ãããŸããã æ¬çªç°å¢ã®æã ãã¿ãã®è²ãèµ€ããªãããšã§ãäžç¬ã§éçºç°å¢ãšæ¬çªç°å¢ã®åºå¥ãã€ããããšãã§ããŸãã TabColorãåããŠã®Firefoxã¢ããªã³éçºã ã£ãã®ã§ãããå
¬åŒãµã€ããå
å®ããŠããã®ãšè±å¯ãªAPIæäŸã®ãããã§ãæ³åããŠããããç°¡åã«ã¢ããªã³ãäœãããšãã§ããŸããã WebExtensionsã§éçºããFirefoxã¢ããªã³ã¯Chromeã®æ©èœæ¡åŒµãšãäºææ§ãããã¿ãããªã®ã§ã次ã¯Chromeçã®TabColorãäœæããŠã¿ãããšæããŸãã瀟å
ã®äººéã¯ã»ãšãã©ChromeãŠãŒã¶ãªã®ã§ãChromeçéçºãããã¿ããªäœ¿ã£ãŠããããšè¯ããªãŒç¬ Wedding Parkã§ã¯äžç·ã«æè¡ã®ãŠãšãã£ã³ã°ããŒã¯ãåµã£ãŠãããšã³ãžãã¢ãåéããŠããŸãã èå³ã®ããæ¹ã¯ãã²äžåºŠæ°è»œã«ãªãã£ã¹ã«éã³ã«ããŠãã ããã ãã©ã€ãã«æ¥çã®ããžã¿ã«ã·ãããå éããããªãŒããšã³ãžãã¢åè£åéïŒ åè WebExtensions – Mozilla | MDN https://developer.mozilla.org/ja/Add-ons/WebExtensions