<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://dololgun.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://dololgun.github.io/" rel="alternate" type="text/html" /><updated>2025-02-12T14:35:07+00:00</updated><id>https://dololgun.github.io/feed.xml</id><title type="html">돌로구니의 기술 블로그</title><subtitle>개발자로서 기억하고 싶은 것을 남겨두는 공간입니다.</subtitle><author><name>이건호</name><email>dololgun@gmail.com</email></author><entry><title type="html">Argo CD - 1 : 개요</title><link href="https://dololgun.github.io/argocd/argocd-01/" rel="alternate" type="text/html" title="Argo CD - 1 : 개요" /><published>2025-02-12T00:00:00+00:00</published><updated>2025-02-12T00:00:00+00:00</updated><id>https://dololgun.github.io/argocd/argocd-01</id><content type="html" xml:base="https://dololgun.github.io/argocd/argocd-01/"><![CDATA[<h2 id="argo-cd-란">Argo CD 란?</h2>

<p>ArgoCD는 쿠버네티스에 쿠버네티스 오브젝트(Service, Deploment 등)를 배포하는 것을 도와주는 도구이다. 공식 홈페이지에서는 다음과 같이 설명한다. ▼</p>

<p>“Argo CD는 GitOps를 활용하여 쿠버네티스에 지속적으로 배포(delivery)하는 도구이다.”</p>

<p>지금 이 글을 읽는 독자라면 아래와 같은 내용을 미리 알고 있어야 이 글의 내용을 이해하는데 큰 문제가 없을 것이다. ▼</p>

<ul>
  <li>yaml</li>
  <li>쿠버네티스(kubernetes) : kubectl, manifest</li>
  <li>GitOps, Git</li>
  <li>CD(Continous delivery/deployment)</li>
</ul>

<h2 id="argo-cd를-사용하지-않을-때의-배포-환경">Argo CD를 사용하지 않을 때의 배포 환경</h2>

<p>쿠버네티스 환경에서는 일반적으로(아니 모든 상황에서) 개발한 애플리케이션을 배포하기 위해 컨테이너 이미지를 생성하게 된다. 그리고 이 컨테이너 이미지를 컨테이너 레지스트리에 저장한다.</p>

<p>예를 들어, 여러분이 생성한 컨테이너 이미지의 이름이 다음과 같다고 가정해 보자. ▼</p>

<p><em>컨테이너 이미지</em> :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my/my-app:0.0.1
</code></pre></div></div>

<p>위의 이미지를 쿠버네티스에 배포하기 위해서 Deployment를 생성하기로 했다면 이 Deployment를 위한 manifest(매니페스트) YAML은 대략 다음과 같을 것이다. ▼</p>

<p><em>Deployment.yaml</em> :</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">apps/v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Deployment</span>
<span class="na">metadata</span><span class="pi">:</span>
  <span class="na">name</span><span class="pi">:</span> <span class="s">my-app</span>
  <span class="na">namespace</span><span class="pi">:</span> <span class="s">default</span>
<span class="na">spec</span><span class="pi">:</span>
  <span class="na">replicas</span><span class="pi">:</span> <span class="m">2</span>
  <span class="na">selector</span><span class="pi">:</span>
    <span class="na">matchLabels</span><span class="pi">:</span>
      <span class="na">app</span><span class="pi">:</span> <span class="s">my-app</span>
  <span class="na">template</span><span class="pi">:</span>
    <span class="na">metadata</span><span class="pi">:</span>
      <span class="na">labels</span><span class="pi">:</span>
        <span class="na">app</span><span class="pi">:</span> <span class="s">my-app</span>
    <span class="na">spec</span><span class="pi">:</span>
      <span class="na">containers</span><span class="pi">:</span>
          <span class="na">image</span><span class="pi">:</span> <span class="s1">'</span><span class="s">my/my-app:0.0.1'</span>
          <span class="na">imagePullPolicy</span><span class="pi">:</span> <span class="s">Always</span>
          <span class="na">name</span><span class="pi">:</span> <span class="s">my-app</span>
</code></pre></div></div>

<p>위의 Deployment 매니페스트를 배포하기 위해 kubectl을 사용(물론 다른 방법들도 있다)한다. ▼</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>kubectl apply <span class="nt">-f</span> Deployment.yaml
</code></pre></div></div>

<p>애플리케이션에 변경 사항이 생긴다면 my-app 이미지의 태그는 아마 다음과 같이 변경될 것이다. ▼</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>my/my-app:0.0.2
</code></pre></div></div>

<p>우리는 변경된 태그에 맞춰서 Deployment.yaml을 바꿀 것이고 변경된 이미지로 새로운 컨테이너를 배포하기 위해 위에서 사용했던 kubectl 명령어를 사용할 것이다.</p>

<p>우리는 이런 작업을 개발 또는 운영에서 반복적으로 할 것이고 my-app과 같은 이미지는 한 두개가 아닐 것이다.</p>

<h2 id="argo-cd를-사용할-때의-배포-환경">Argo CD를 사용할 때의 배포 환경</h2>

<p>컨테이너 이미지는 어떤 방식으로든 생성 했을 것이다. 이 부분은 Argo CD의 영역이 아니다.</p>

<p>Argo CD환경(정확히는 GitOps 환경)에서는 위의 Deployment.yaml을 Git Repository에 저장한다.</p>

<p>Argo CD는 Git Repository에 있는 Deployment.yaml을 읽고 이 매니페스트를 쿠버네티스에 배포한다. 마치 우리가 kubectl을 사용하여 배포한 것처럼 말이다.</p>

<p>또한, Argo CD는 Git Repository에 있는 Deployment.yaml을 주기적(대략 3분마다)으로 읽는다. 만약, Deployment.yaml이 쿠버네티스에 배포된 Deployment와 다르다면 자동(설정에 따라 수동)으로 Git Repository의 Deployment.yaml을 쿠버네티스에 배포(이를 동기화라고 함) 한다.</p>

<p><img src="../../assets/images/post/argocd/argocd-01.drawio.svg" alt="" /></p>

<h2 id="참고">참고</h2>

<p><a href="https://argo-cd.readthedocs.io/en/stable/">Argo CD - Declarative GitOps CD for Kubernetes</a></p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="ArgoCD" /><summary type="html"><![CDATA[Argo CD 란? ArgoCD는 쿠버네티스에 쿠버네티스 오브젝트(Service, Deploment 등)를 배포하는 것을 도와주는 도구이다. 공식 홈페이지에서는 다음과 같이 설명한다. ▼ “Argo CD는 GitOps를 활용하여 쿠버네티스에 지속적으로 배포(delivery)하는 도구이다.” 지금 이 글을 읽는 독자라면 아래와 같은 내용을 미리 알고 있어야 이 글의 내용을 이해하는데 큰 문제가 없을 것이다. ▼ yaml 쿠버네티스(kubernetes) : kubectl, manifest GitOps, Git CD(Continous delivery/deployment) Argo CD를 사용하지 않을 때의 배포 환경 쿠버네티스 환경에서는 일반적으로(아니 모든 상황에서) 개발한 애플리케이션을 배포하기 위해 컨테이너 이미지를 생성하게 된다. 그리고 이 컨테이너 이미지를 컨테이너 레지스트리에 저장한다. 예를 들어, 여러분이 생성한 컨테이너 이미지의 이름이 다음과 같다고 가정해 보자. ▼ 컨테이너 이미지 : my/my-app:0.0.1 위의 이미지를 쿠버네티스에 배포하기 위해서 Deployment를 생성하기로 했다면 이 Deployment를 위한 manifest(매니페스트) YAML은 대략 다음과 같을 것이다. ▼ Deployment.yaml : apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: default spec: replicas: 2 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: image: 'my/my-app:0.0.1' imagePullPolicy: Always name: my-app 위의 Deployment 매니페스트를 배포하기 위해 kubectl을 사용(물론 다른 방법들도 있다)한다. ▼ $ kubectl apply -f Deployment.yaml 애플리케이션에 변경 사항이 생긴다면 my-app 이미지의 태그는 아마 다음과 같이 변경될 것이다. ▼ my/my-app:0.0.2 우리는 변경된 태그에 맞춰서 Deployment.yaml을 바꿀 것이고 변경된 이미지로 새로운 컨테이너를 배포하기 위해 위에서 사용했던 kubectl 명령어를 사용할 것이다. 우리는 이런 작업을 개발 또는 운영에서 반복적으로 할 것이고 my-app과 같은 이미지는 한 두개가 아닐 것이다. Argo CD를 사용할 때의 배포 환경 컨테이너 이미지는 어떤 방식으로든 생성 했을 것이다. 이 부분은 Argo CD의 영역이 아니다. Argo CD환경(정확히는 GitOps 환경)에서는 위의 Deployment.yaml을 Git Repository에 저장한다. Argo CD는 Git Repository에 있는 Deployment.yaml을 읽고 이 매니페스트를 쿠버네티스에 배포한다. 마치 우리가 kubectl을 사용하여 배포한 것처럼 말이다. 또한, Argo CD는 Git Repository에 있는 Deployment.yaml을 주기적(대략 3분마다)으로 읽는다. 만약, Deployment.yaml이 쿠버네티스에 배포된 Deployment와 다르다면 자동(설정에 따라 수동)으로 Git Repository의 Deployment.yaml을 쿠버네티스에 배포(이를 동기화라고 함) 한다. 참고 Argo CD - Declarative GitOps CD for Kubernetes]]></summary></entry><entry><title type="html">Airprint</title><link href="https://dololgun.github.io/airprint/" rel="alternate" type="text/html" title="Airprint" /><published>2022-01-09T00:00:00+00:00</published><updated>2022-01-09T00:00:00+00:00</updated><id>https://dololgun.github.io/airprint</id><content type="html" xml:base="https://dololgun.github.io/airprint/"><![CDATA[<h2 id="개요">개요</h2>

<p>HP 프린터를 사용하여 air프린터를 수행 시,</p>

<p><code class="language-plaintext highlighter-rouge">암호화 자격 증명 만료</code> 가 나타나며 인쇄가 안되는 경우가 있다.</p>

<h2 id="해결">해결</h2>

<p>프린터 내장 웹 서버로 들어간다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>프린터 및 스캐너 &gt; 옵션 및 소모품 &gt; 프린터 웹 페이지 보기
</code></pre></div></div>

<p>웹페이지가 나타난다.</p>

<p>이 웹페이지에서</p>

<ul>
  <li>네트워크 탭을 선택한다.</li>
  <li>왼쪽 메뉴에서 고급설정을 선택한다.</li>
  <li>하위 메뉴에서 인증서를 선택한다.</li>
  <li>인증서 화면에서 <code class="language-plaintext highlighter-rouge">구성</code>을 클릭하고 <code class="language-plaintext highlighter-rouge">새로운 자체 서명 인증서 생성</code>을 선택한 후 다음을 클릭한다.</li>
  <li>마침을 클릭한다.</li>
</ul>

<h3 id="참조">참조</h3>

<table>
  <tbody>
    <tr>
      <td>[HP 프린터 - “암호화 자격 증명 만료” 오류 표시(macOS, iOS)</td>
      <td>HP® 고객 지원](https://support.hp.com/kr-ko/document/c06503199)</td>
    </tr>
  </tbody>
</table>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><summary type="html"><![CDATA[개요]]></summary></entry><entry><title type="html">CentOS 7 git 최신버전 설치하기</title><link href="https://dololgun.github.io/linux/centos7-git-install/" rel="alternate" type="text/html" title="CentOS 7 git 최신버전 설치하기" /><published>2021-03-08T00:00:00+00:00</published><updated>2021-03-08T00:00:00+00:00</updated><id>https://dololgun.github.io/linux/centos7-git-install</id><content type="html" xml:base="https://dololgun.github.io/linux/centos7-git-install/"><![CDATA[<p>CentOS7에 기본 설치되어 있는 git의 버전은 1.8이다. yum 저장소에 등록되어 있는 것도 1.8이기 때문에 yum update로도 최신버전으로 업그래이드할 수 없다.</p>

<p>최신버전을 설치하기 위해 wandisco 저장소를 yum에 등록해야 한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>yum <span class="nb">install </span>http://opensource.wandisco.com/centos/7/git/x86_64/wandisco-git-release-7-1.noarch.rpm
</code></pre></div></div>

<p>이제 다음 명령어로 이미 설치되어 있는 git을 제거한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>yum remove git
</code></pre></div></div>

<p>다시 git을 설치한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>yum <span class="nb">install </span>git
</code></pre></div></div>

<p>설치완료 후, git 버전을 확인한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>git <span class="nt">--version</span>
git version 2.22.0
</code></pre></div></div>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="linux" /><summary type="html"><![CDATA[CentOS7에 기본 설치되어 있는 git의 버전은 1.8이다. yum 저장소에 등록되어 있는 것도 1.8이기 때문에 yum update로도 최신버전으로 업그래이드할 수 없다.]]></summary></entry><entry><title type="html">Linux Timemachine Server For Mac</title><link href="https://dololgun.github.io/linux-timemachine-server-for-mac/" rel="alternate" type="text/html" title="Linux Timemachine Server For Mac" /><published>2021-02-27T00:00:00+00:00</published><updated>2021-02-27T00:00:00+00:00</updated><id>https://dololgun.github.io/linux-timemachine-server-for-mac</id><content type="html" xml:base="https://dololgun.github.io/linux-timemachine-server-for-mac/"><![CDATA[<p>맥에서 사용하는 타임머신의 스토리지 서버를 리눅스에 설치한다.</p>

<p>이를 위해 리눅스 서버에 2가지가 필요하다.</p>

<ul>
  <li>samba 서비스</li>
  <li>Avahi : 네트워크에서 자신의 네트워크 공유를 자동으로 감지할 수 있도록 한다.</li>
</ul>

<p>Avahi 를 사용하는 이유는 이렇게 해야 mac에서 이 서버를 인식할 수 있다.</p>

<p>### Avahi 도커 설치 하기</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo </span>docker create <span class="nt">--name</span> avahi-config solidnerd/avahi:0.7
<span class="nv">$ </span><span class="nb">sudo </span>docker <span class="nb">cp </span>avahi-config:/etc/avahi <span class="nb">.</span>
<span class="nv">$ </span><span class="nb">sudo </span>docker <span class="nb">rm </span>avahi-config
</code></pre></div></div>

<h3 id="avahi-도커-설정-하기">Avahi 도커 설정 하기</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sed</span> <span class="nt">-i</span> <span class="s1">'s/#enable-dbus=yes/enable-dbus=no/'</span> avahi/avahi-daemon.conf
</code></pre></div></div>

<h3 id="avahi-samba-설정하기">Avahi Samba 설정하기</h3>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ cat <span class="err">&lt;</span><span class="nt">&lt;EOT</span> <span class="nt">&gt;</span>&gt; avahi/services/smb.conf
<span class="cp">&lt;?xml version="1.0" standalone='no'?&gt;</span>
<span class="cp">&lt;!DOCTYPE service-group SYSTEM "avahi-service.dtd"&gt;</span>
<span class="nt">&lt;service-group&gt;</span>
<span class="nt">&lt;name</span> <span class="na">replace-wildcards=</span><span class="s">"yes"</span><span class="nt">&gt;</span>%h<span class="nt">&lt;/name&gt;</span>
<span class="nt">&lt;service&gt;</span>
  <span class="nt">&lt;type&gt;</span>_adisk._tcp<span class="nt">&lt;/type&gt;</span>
  <span class="nt">&lt;txt-record&gt;</span>sys=waMa=0,adVF=0x100<span class="nt">&lt;/txt-record&gt;</span>
  <span class="nt">&lt;txt-record&gt;</span>dk0=adVN=Time Capsule,adVF=0x82<span class="nt">&lt;/txt-record&gt;</span>
<span class="nt">&lt;/service&gt;</span>
<span class="nt">&lt;service&gt;</span>
  <span class="nt">&lt;type&gt;</span>_smb._tcp<span class="nt">&lt;/type&gt;</span>
  <span class="nt">&lt;port&gt;</span>445<span class="nt">&lt;/port&gt;</span>
<span class="nt">&lt;/service&gt;</span>
<span class="nt">&lt;service&gt;</span>
  <span class="nt">&lt;type&gt;</span>_device-info._tcp<span class="nt">&lt;/type&gt;</span>
  <span class="nt">&lt;port&gt;</span>0<span class="nt">&lt;/port&gt;</span>
  <span class="nt">&lt;txt-record&gt;</span>model=RackMac<span class="nt">&lt;/txt-record&gt;</span>
<span class="nt">&lt;/service&gt;</span>
<span class="nt">&lt;/service-group&gt;</span>
EOT
</code></pre></div></div>

<blockquote>
  <p>주의</p>

  <p>selinux가 활성화되어 있다면 samba와 avahi 사용에 각종 보안 제약으로 어려움이 따른다. selinux를 비활성화 하자.</p>
</blockquote>

<h2 id="위와-같이-했는데도-안됐다">위와 같이 했는데도 안됐다.</h2>

<p>혹시 되는 사람은 그대로 하되 안되면 필자가 했던 방법을 참고한다.</p>

<h3 id="중요한건-samba-설정">중요한건 samba 설정</h3>

<p>타임머신을 위한 공유폴더 설정을 다음과 같이 한다. 아래 예시는 타임머신에 필요한 설정만 보여주었다.</p>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[global]</span>
  <span class="py">workgroup</span> <span class="p">=</span> <span class="s">SAMBA</span>
  <span class="py">security</span> <span class="p">=</span> <span class="s">user</span>

  <span class="err">passdb</span> <span class="py">backend</span> <span class="p">=</span> <span class="s">tdbsam</span>

  <span class="py">printing</span> <span class="p">=</span> <span class="s">cups</span>
  <span class="err">printcap</span> <span class="py">name</span> <span class="p">=</span> <span class="s">cups</span>
  <span class="err">load</span> <span class="py">printers</span> <span class="p">=</span> <span class="s">yes</span>
  <span class="err">cups</span> <span class="py">options</span> <span class="p">=</span> <span class="s">raw</span>

  <span class="err">min</span> <span class="py">protocol</span> <span class="p">=</span> <span class="s">SMB2</span>

<span class="nn">[Time Machine Backup]</span>
  <span class="py">path</span> <span class="p">=</span> <span class="s">/mnt/LGH2/tmbackup/data</span>
  <span class="py">browseable</span> <span class="p">=</span> <span class="s">yes</span>
  <span class="err">read</span> <span class="py">only</span> <span class="p">=</span> <span class="s">no</span>
  <span class="err">force</span> <span class="err">create</span> <span class="py">mode</span> <span class="p">=</span> <span class="s">0660</span>
  <span class="err">force</span> <span class="err">directory</span> <span class="py">mode</span> <span class="p">=</span> <span class="s">2770</span>
  <span class="err">valid</span> <span class="py">users</span> <span class="p">=</span> <span class="s">@samba @geonho</span>
  <span class="err">vfs</span> <span class="py">objects</span> <span class="p">=</span> <span class="s">fruit streams_xattr</span>
  <span class="err">fruit:time</span> <span class="py">machine</span> <span class="p">=</span> <span class="s">yes</span>
  <span class="err">fruit:time</span> <span class="err">machine</span> <span class="err">max</span> <span class="py">size</span> <span class="p">=</span> <span class="s">500G</span>
  <span class="err">fruit:</span><span class="py">delete_empty_adfiles</span> <span class="p">=</span> <span class="s">yes</span>
  <span class="err">fruit:</span><span class="py">veto_appledouble</span> <span class="p">=</span> <span class="s">no</span>
  <span class="err">fruit:</span><span class="py">wipe_intentionally_left_blank_rfork</span> <span class="p">=</span> <span class="s">yes</span>
</code></pre></div></div>

<p>위에서 설정한 avahi 도커는 실행할 필요가 없었다. 중요한 것은 <code class="language-plaintext highlighter-rouge">vfs objects = fruit streams_xattr</code> 설정으로 보이는데 잘 모르겠다.</p>

<p>관련된 설명은 다음과 같긴한데,</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>vfs object
This parameter is a synonym for vfs objects.

vfs objects (S)
This parameter specifies the backend names which are used for Samba VFS I/O operations. By default, normal disk I/O operations are used but these can be overloaded with one or more VFS objects. Be aware that the definition of this parameter will overwrite a possible previous definition of the vfs objects parameter.

Default: vfs objects =

Example: vfs objects = extd_audit recycle
</code></pre></div></div>

<p>일단 위와 같이 설정하고 samba를 재시작 한 후, 맥에서 보면 아래와 같이 나온다ㅣ.</p>

<p><img src="../../assets/images/post/macos/image-20210301002737430.png" alt="image-20210301002737430" /></p>

<p>Time Machine 은 필자가 가지고 있는 맥미니 서버에서 항상 잘 나오는 것이고 Time Machine Backup은 이 포스티에서 다루는 리눅스에서 설정한 백업 폴더이다.</p>

<p>그런데, 처음엔 잘 나오다가 특정 시점이 지나면 리눅스에서 설정한 백업 폴더가 나타나지 않았다. 예를 들어, 클라이언트 맥을 재시작 하면 나오지 않았다.</p>

<p>그러다가, 리눅스 서버의 타임머신 공유 폴더를 smb로 직접 연결하면 다시 보였다.</p>

<blockquote>
  <p>주의</p>

  <p>fruit:time machine max size를 설정하지말자 이것을 설정하면 디스크에 이미지를 할당할 수 없다는 오류가 뜬다.</p>
</blockquote>

<h3 id="타임머신을-위한-설정">타임머신을 위한 설정</h3>

<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[global]</span>
        <span class="py">workgroup</span> <span class="p">=</span> <span class="s">SAMBA</span>
        <span class="py">security</span> <span class="p">=</span> <span class="s">user</span>

        <span class="err">passdb</span> <span class="py">backend</span> <span class="p">=</span> <span class="s">tdbsam</span>

        <span class="py">printing</span> <span class="p">=</span> <span class="s">cups</span>
        <span class="err">printcap</span> <span class="py">name</span> <span class="p">=</span> <span class="s">cups</span>
        <span class="err">load</span> <span class="py">printers</span> <span class="p">=</span> <span class="s">yes</span>
        <span class="err">cups</span> <span class="py">options</span> <span class="p">=</span> <span class="s">raw</span>

        <span class="err">min</span> <span class="py">protocol</span> <span class="p">=</span> <span class="s">SMB2</span>
        <span class="err">vfs</span> <span class="py">objects</span> <span class="p">=</span> <span class="s">catia fruit streams_xattr</span>
        <span class="err">fruit:</span><span class="py">aapl</span> <span class="p">=</span> <span class="s">yes</span>
        <span class="err">fruit:</span><span class="py">model</span> <span class="p">=</span> <span class="s">MacSamba</span>

<span class="nn">[timemachine]</span>
        <span class="py">path</span> <span class="p">=</span> <span class="s">/mnt/LGH2/tmbackup/data</span>
        <span class="py">browseable</span> <span class="p">=</span> <span class="s">yes</span>
        <span class="err">read</span> <span class="py">only</span> <span class="p">=</span> <span class="s">no</span>
        <span class="py">writable</span> <span class="p">=</span> <span class="s">yes</span>
        <span class="err">create</span> <span class="py">mask</span> <span class="p">=</span> <span class="s">0644</span>
        <span class="err">directory</span> <span class="py">mask</span> <span class="p">=</span> <span class="s">0755</span>
<span class="c">#       force create mode = 0660
#       force directory mode = 2770
</span>        <span class="err">valid</span> <span class="py">users</span> <span class="p">=</span> <span class="s">@samba @geonho</span>

<span class="c"># following option for timemachine
</span>        <span class="err">fruit:time</span> <span class="py">machine</span> <span class="p">=</span> <span class="s">yes</span>
<span class="c">#       fruit:time machine max size = 500G
#       fruit:metadata = stream
#       fruit:advertise_fullsync = true
#       fruit:veto_appledouble = no
#       fruit:posix_rename = yes
#       fruit:zero_file_id = yes
#       fruit:wipe_intentionally_left_blank_rfork = yes
#       fruit:delete_empty_adfiles = yes
#       inherit acls = Yes
</span>        <span class="err">durable</span> <span class="py">handles</span> <span class="p">=</span> <span class="s">yes</span>
        <span class="err">kernel</span> <span class="py">oplocks</span> <span class="p">=</span> <span class="s">no</span>
        <span class="err">kernel</span> <span class="err">share</span> <span class="py">modes</span> <span class="p">=</span> <span class="s">no</span>
        <span class="err">posix</span> <span class="py">locking</span> <span class="p">=</span> <span class="s">no</span>
</code></pre></div></div>

<h2 id="참조">참조</h2>

<p>https://www.samba.org/samba/docs/current/man-html/vfs_fruit.8.html</p>

<p>https://wiki.samba.org/index.php/Configure_Samba_to_Work_Better_with_Mac_OS_X</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><summary type="html"><![CDATA[맥에서 사용하는 타임머신의 스토리지 서버를 리눅스에 설치한다.]]></summary></entry><entry><title type="html">코히어런스(Coherence) 기본 설정하기</title><link href="https://dololgun.github.io/weblogic/cofigure-coherence/" rel="alternate" type="text/html" title="코히어런스(Coherence) 기본 설정하기" /><published>2021-01-30T00:00:00+00:00</published><updated>2021-01-30T00:00:00+00:00</updated><id>https://dololgun.github.io/weblogic/cofigure-coherence</id><content type="html" xml:base="https://dololgun.github.io/weblogic/cofigure-coherence/"><![CDATA[<p>코히어런스 캐시 서버의 기본적인 설정을 적용해본다.</p>

<h2 id="설정-이해하기">설정 이해하기</h2>

<p>이전 포스팅  <a href="2021-01-17-install-coherence.md">코히어런스 설치하기</a>에서 살짝 언급했지만 코히어런스를 이해하는 것의 대부분은 설정하는 방법을 아는 것이다. 코히어런스의 핵심 라이브러리인 <code class="language-plaintext highlighter-rouge">coherence.jar</code> 파일안에 기본 설정 파일(xml)이 포함되어 있고 우리는 이 파일과 별도로 설정 파일을 생성하여 적용할 수 있다. 만약 아무런 설정을 하지 않는다면 기본 설정 파일로 코히어런스가 동작한다.</p>

<p>코히어런스는 다양한 설정파일을 가지고 있지만 그 중 꼭 알아야 하는 설정파일은 <code class="language-plaintext highlighter-rouge">Operation Configuration File</code>, <code class="language-plaintext highlighter-rouge">Cache Configuration File</code> 이다.</p>

<h3 id="operation-configuration-file">Operation Configuration File</h3>

<p><code class="language-plaintext highlighter-rouge">coherence.jar</code> 파일안에 <code class="language-plaintext highlighter-rouge">tangosol-coherence.xml</code> 에 관련된 설정이 있다. 설정 파일의 이름에서 알 수 있듯이 코히어런스가 동작하는 모든 행위에 대한 설정을 한다.</p>

<p>가이드에서는 이 설정 파일은 그냥 두고 변경해야 할 설정이 있다면 오버라이드 파일을 생성하여 적용하는 것을 추천한다. 즉, 변경할 설정이 있다면 오버라이드 파일을 만들고 코히어런스에게 이런 오버라이드 파일이 있으니 그 파일을 보라고 하는 것이다.</p>

<p>코히어런스는 <code class="language-plaintext highlighter-rouge">tangosol-coherence-override.xml</code> 명칭의 파일이 클래스 패스에 있다면 알아서 오버라이드 파일로 인식하고 로드한다.</p>

<p>그럼 오버라이드 파일을 한번 만들어보자.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">$COHERENCE_HOME/config</code> 폴더를 만든다.</li>
  <li>위의 폴더에 tangosol-coherence-override.xml을 만들고 아래와 같이 작성한다.</li>
</ul>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version='1.0'?&gt;</span>

<span class="c">&lt;!--
This operational configuration override file is set up for use with Coherence in
a development mode.
--&gt;</span>
<span class="nt">&lt;coherence</span> <span class="na">xmlns:xsi=</span><span class="s">"http://www.w3.org/2001/XMLSchema-instance"</span>
    <span class="na">xmlns=</span><span class="s">"http://xmlns.oracle.com/coherence/coherence-operational-config"</span> <span class="na">xsi:schemaLocation=</span><span class="s">"http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;cluster-config&gt;</span>
        <span class="nt">&lt;member-identity&gt;</span>
            <span class="nt">&lt;cluster-name</span> <span class="na">system-property=</span><span class="s">"coherence.cluster"</span><span class="nt">&gt;</span>leegeonho<span class="nt">&lt;/cluster-name&gt;</span>
        <span class="nt">&lt;/member-identity&gt;</span>
    <span class="nt">&lt;/cluster-config&gt;</span>

    <span class="nt">&lt;configurable-cache-factory-config&gt;</span>
        <span class="nt">&lt;init-params&gt;</span>
            <span class="nt">&lt;init-param&gt;</span>
                <span class="nt">&lt;param-type&gt;</span>java.lang.String<span class="nt">&lt;/param-type&gt;</span>
                <span class="nt">&lt;param-value</span> <span class="na">system-property=</span><span class="s">"coherence.cacheconfig"</span><span class="nt">&gt;</span>/Users/geonho/Oracle/Middleware/Oracle_Home/coherence/config/sample-cache-config.xml<span class="nt">&lt;/param-value&gt;</span>
            <span class="nt">&lt;/init-param&gt;</span>
        <span class="nt">&lt;/init-params&gt;</span>
    <span class="nt">&lt;/configurable-cache-factory-config&gt;</span>
<span class="nt">&lt;/coherence&gt;</span>
</code></pre></div></div>

<ul>
  <li><code class="language-plaintext highlighter-rouge">$COHERENCE_HOME/bin/cache-server.sh</code> 파일의 가장 아래부분을 수정하여 클래스 패스 옵션(-cp 옵션)에 $COHERENCE_HOME/config 을 추가한다.</li>
</ul>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>... 중략 ...

<span class="nv">$JAVAEXEC</span> <span class="nt">-server</span> <span class="nt">-showversion</span> <span class="nv">$JAVA_OPTS</span> <span class="nv">$COHERENCE_OPTS</span> <span class="nt">-cp</span> <span class="s2">"</span><span class="nv">$COHERENCE_HOME</span><span class="s2">/lib/coherence.jar:</span><span class="nv">$COHERENCE_HOME</span><span class="s2">/config"</span> com.tangosol.net.DefaultCacheServer <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span>

</code></pre></div></div>

<ul>
  <li>cache-server.sh 를 실행하여 캐시 서버를 기동한다.</li>
</ul>

<p>캐시 서버가 기동 될 때 로그를 잘 보면 아래와 같이 tangosol-coherence-override.xml 이 로드 된 것을 확인할 수 있다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2021-01-30 22:00:55.907/1.389 Oracle Coherence 14.1.1.0.0 &lt;Info&gt; <span class="o">(</span><span class="nv">thread</span><span class="o">=</span>main, <span class="nv">member</span><span class="o">=</span>n/a<span class="o">)</span>: Loaded operational overrides from <span class="s2">"file:/Users/geonho/Oracle/Middleware/Oracle_Home/coherence/config/tangosol-coherence-override.xml"</span>
</code></pre></div></div>

<p>tangosol-coherence-override.xml 설정파일에 정의된 내용을 간략히 설명하도록 하겠다.</p>

<h4 id="cluster-name">cluster-name</h4>

<p><code class="language-plaintext highlighter-rouge">cluster-name</code> 은 말그래도 클러스터 이름을 지정하는 것이다. 코히어런스는 무조건 클러스터를 구성하여 실행된다. 이 말은 우리가 클러스터를 지정하지 않는다면 코히어런스가 알아서 클러스터 이름을 지정한다. 위의 설정에서 클러스터 이름을 leegeonho로 지었으므로 코히어런스 실행 시 아래와 같은 로그를 확인할 수 있다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2021-01-30 22:01:00.777/6.259 Oracle Coherence GE 14.1.1.0.0 &lt;Info&gt; <span class="o">(</span><span class="nv">thread</span><span class="o">=</span>Cluster, <span class="nv">member</span><span class="o">=</span>n/a<span class="o">)</span>: Created a new cluster <span class="s2">"leegeonho"</span> with Member<span class="o">(</span><span class="nv">Id</span><span class="o">=</span>1, <span class="nv">Timestamp</span><span class="o">=</span>2021-01-30 22:00:57.442, <span class="nv">Address</span><span class="o">=</span>192.168.1.67:9900, <span class="nv">MachineId</span><span class="o">=</span>10845, <span class="nv">Location</span><span class="o">=</span>process:49361, <span class="nv">Role</span><span class="o">=</span>CoherenceServer, <span class="nv">Edition</span><span class="o">=</span>Grid Edition, <span class="nv">Mode</span><span class="o">=</span>Development, <span class="nv">CpuCount</span><span class="o">=</span>4, <span class="nv">SocketCount</span><span class="o">=</span>4<span class="o">)</span>
</code></pre></div></div>

<h4 id="configurable-cache-factory-config">configurable-cache-factory-config</h4>

<p>기본 설정된 coherence-cache-config.xml 파일을 오버라이드 하기 위해 사용한다. 자세한 내용은 cache configuration file에서 설명한다.</p>

<h3 id="cache-configuration-file">Cache Configuration File</h3>

<p>이 파일에서 코히어런스 캐시에 대한 설정을 할 수 있다. 기본 설정은 <code class="language-plaintext highlighter-rouge">coherence.jar</code> 파일안에 <code class="language-plaintext highlighter-rouge">coherence-cache-config.xml</code> 에 있다. 물론 이 파일이 아닌 다른 설정 파일도 사용할 수 있다. 이를 위해 <code class="language-plaintext highlighter-rouge">tangosol-coherence-override.xml</code> 파일에 <code class="language-plaintext highlighter-rouge">configurable-cache-factory-config</code> 항목에 파일의 경로를 입력한다.</p>

<h2 id="참조">참조</h2>

<p>https://docs.oracle.com/en/middleware/fusion-middleware/coherence/12.2.1.4/develop-applications/understanding-configuration.html#GUID-C5335E66-6D7F-4C15-B7EC-F6D7D1494066</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="weblogic" /><summary type="html"><![CDATA[코히어런스 캐시 서버의 기본적인 설정을 적용해본다.]]></summary></entry><entry><title type="html">코히어런스(Coherence) 설치하기</title><link href="https://dololgun.github.io/weblogic/install-coherence/" rel="alternate" type="text/html" title="코히어런스(Coherence) 설치하기" /><published>2021-01-17T00:00:00+00:00</published><updated>2021-01-17T00:00:00+00:00</updated><id>https://dololgun.github.io/weblogic/install-coherence</id><content type="html" xml:base="https://dololgun.github.io/weblogic/install-coherence/"><![CDATA[<p>오라클에서 제공하는 in-memory 캐시 서비스인 coherence를 설치하는 내용.</p>

<h2 id="코히어런스coherenece-란">코히어런스(coherenece) 란?</h2>

<p>오라클에서 제공하는 in-memory DB 이다. 다른 말로는 캐시 서버라고도 한다.</p>

<h2 id="설치">설치</h2>

<p>만약 weblogic이 설치되어 있다면 코히어런스도 이미 설치되어 있기 때문에 별도의 설치가 필요 없다. 만약 weblogic과 별개로 사용 하려면 설치가 필요하다. 이 포스팅은 웹로직이 설치되지 않은 환경에서 코히어런스를 설치하는 것에 대해서 다룬다.</p>

<p>그런데 필자가 코히어런스를 직접 설치하게 된 이유가 있다. 필자가 알기론 코히어런스는 웹로직을 사용하는 경우에만 사용한다. 왜냐하면 웹로직과 코히어런스는 오라클에서 제공하는 미들웨어 제품군으로 함께 사용하게 되면 호환성이 매우 좋으며 캐시 서비스를 쉽게 구성할 수 있기 때문이다. 필자가 개발하는 환경도 웹로직과 코히어런스 환경에서 개발을 진행하였다.</p>

<p>다만, 일반적으로 로컬 개발환경은 톰캣으로 진행하는데 모든 개발자 PC에 웹로직을 설치할 수 없기 때문이다. 톰캣과 코히어런스의 연동을 테스트하기 위해서는 로컬PC에 코히어런스를 설치해보고 동작을 확인할 필요성이 생겼다. 또한, 로컬 개발환경에 코히어런스가 없다면 매번 기능을 테스트하기 위해 소스를 수정하고 코히어런스가 설치된 개발 서버에 배포해야 하는 작업이 필요한데 이것은 굉장히 번거러운 일이다.</p>

<h3 id="라이센스-정책">라이센스 정책</h3>

<blockquote>
  <p>정확한 것은 아니지만 필자가 알기론 coherenece는 weblogic라이센스를 구매하면 무료로 사용할 수 있지만 weblogic이 없이 단독으로 사용하기 위해서는 상응하는 라이센스를 구매를 해야 한다. 만약 상업적인 용도로 사용하려면 라이센스 정책을 정확히 확인하여야 한다.</p>
</blockquote>

<h3 id="설치파일-다운로드">설치파일 다운로드</h3>

<p><a href="https://download.oracle.com/otn/nt/middleware/14c/14110/fmw_14.1.1.0.0_coherence_Disk1_1of1.zip">Coherence Stand-Alone Install</a> 에서 최신버전의 coherence를 받는다. 이 글을 쓰는 시점의 최신버전은 <code class="language-plaintext highlighter-rouge">14.1.1</code>이다. <code class="language-plaintext highlighter-rouge">fmw_14.1.1.0.0_coherence_Disk1_1of1.zip</code> 파일을 받게 되는데 압축을 해제하면 <code class="language-plaintext highlighter-rouge">fmw_14.1.1.0.0_coherence.jar</code> 파일을 얻을 수 있다.</p>

<h3 id="jdk-준비">JDK 준비</h3>

<p>Coherence는 오라클 jdk에서만 설치가 가능하고 설치 후에는 다른 jdk로 구동해도 상관없는 것 같다. 그렇기 때문에 Coherence를 설치하기 전에 오라클 jdk를 미리 설치하자. 혹시 Mac에서 다른 버전의 jdk를 설치하려면 필자의 관련 포스팅 <a href="../macos/2021-01-16-java-install.md">Mac OS에 하나 이상의 다른 버전의 JDK 설치하기</a> 를 참조하자.</p>

<h3 id="설치-라이브러리-실행">설치 라이브러리 실행</h3>

<p>fmw_14.1.1.0.0_coherence.jar 파일이 있는 폴더로 이동하여 다음 명령어를 실행한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>java <span class="nt">-jar</span> fmw_14.1.1.0.0_coherence.jar
</code></pre></div></div>

<p>그럼 아래 그림과 같이 설치 GUI가 나타난다. (오라클 JDK를 사용해야만 이런 GUI를 쓸 수 있다고 한다)</p>

<p><img src="../../assets/images/post/weblogic/image-20210117143951570.png" alt="image-20210117143951570" /></p>

<p>필자는 Coherence의 정확한 지식이 없어 기본 설정으로 설치를 하였다. (확인, 다음 버튼만 계속 눌렀다)</p>

<p>아래 그림에서 예제 파일도 확인할 수 있도록 체크한다.</p>

<p><img src="../../assets/images/post/weblogic/image-20210117144702933.png" alt="image-20210117144702933" /></p>

<p>아래 그림과 같이 완료가 되면 설치 성공!</p>

<p><img src="../../assets/images/post/weblogic/image-20210117145029051.png" alt="image-20210117145029051" /></p>

<p>드디어 Mac에 Coherece를 설치하였다.</p>

<h2 id="설치-된-디렉토리-둘러보기">설치 된 디렉토리 둘러보기</h2>

<p>설치를 하였더니 유저 홈 디렉토리에 아래와 같이 2개의 폴더가 생성되었다. 필자의 경우 기본 설정을 그대로 따른 경우 이고 설치경로를 변경하였다면 변경된 경로로 디렉터리가 생성되었을 것이다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>drwxr-x---   3 geonho  staff     96  1 17 14:48 Oracle
drwxrwx---   7 geonho  staff    224  1 17 14:48 oraInventory
</code></pre></div></div>

<p>우리가 관심가져야 할 폴더는 <code class="language-plaintext highlighter-rouge">/Users/geonho/Oracle/Middleware/Oracle_Home/coherence</code>이다. 이 폴더가 coherence 애플리케이션의 home 디렉토리이다. coherence는 COHERENCE_HOME이란 환경변수에 이 경로를 할당하여 사용한다.</p>

<p>이 디렉터리는 아래와 같이 구성되어 있는데,</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>drwxr-x---   9 geonho  staff   288B  1 17 14:49 bin
drwxr-x---   4 geonho  staff   128B  1 17 14:49 doc
drwxr-x---   8 geonho  staff   256B  1 17 14:49 examples
drwxr-x---  26 geonho  staff   832B  1 17 14:49 lib
drwxr-x---   5 geonho  staff   160B  1 17 14:49 plugins
<span class="nt">-rw-r-----</span>   1 geonho  staff   100B 11 21  2019 product.xml
</code></pre></div></div>

<p>bin폴더와 lib폴더는 애플리케이션 구동에 필요한 것으로 보이고 doc, examples은 도움을 줄 수 있는 문서와 샘플인것 같다.</p>

<h2 id="설정-이해하기">설정 이해하기</h2>

<p><code class="language-plaintext highlighter-rouge">$COHERENCE_HOME/lib/coherence.jar</code> 파일에 coherence의 기본설정을 담고 있는 파일이 있다.</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">tangosol-coherence.xml</code> – 런타임시 동작에 대한 설정이다. 클러스터 생성과 설정, 데이터 관리 서비스의 생성과 설정을 한다. 자세한 건 모르겠고 coherence 동작에 관련한 기본 설정이 모두 여기에 들어가 있다고 생각하자.</li>
  <li><code class="language-plaintext highlighter-rouge">tangosol-coherence-override-dev.xml</code> – <code class="language-plaintext highlighter-rouge">tangosol-coherence.xml</code> 파일의 설정을 오버라이드 한다. 개발 모드일 경우에 적용된다. 기본 설정으로 Coherence는 개발 모드로 시작되고 이 파일의 설정이 적용된다.</li>
  <li><code class="language-plaintext highlighter-rouge">tangosol-coherence-override-eval.xml</code> – <code class="language-plaintext highlighter-rouge">tangosol-coherence.xml</code> 파일의 설정을 오버라이드 한다. eval 모드일 경우 적용된다.</li>
  <li><code class="language-plaintext highlighter-rouge">tangosol-coherence-override-prod.xml</code> – <code class="language-plaintext highlighter-rouge">tangosol-coherence.xml</code> 파일의 설정을 오버라이드 한다. prod 모드일 경우 적용된다.</li>
  <li><code class="language-plaintext highlighter-rouge">coherence-cache-config.xml</code> – 클러스터에서 사용 될 수 있는 캐시를 설정한다. 보통 이 파일은 cache configuration deployment descriptor로 역할을 한다.</li>
  <li><code class="language-plaintext highlighter-rouge">coherence-pof-config.xml</code> – 우리가 직접 작성한 클래스의 객체를 저장할 때 직렬화를 거치게 되는데 이 직렬화와 관련된 파일로 보인다.</li>
  <li>Management configuration files – Coherence management reports를 설정하는 파일 셋이다. 이 파일은 <code class="language-plaintext highlighter-rouge">coherence.jar</code>의  <code class="language-plaintext highlighter-rouge">/reports</code>  폴더에 있다. 제세한 건 필자도 모른다.</li>
</ul>

<p>처음부터 모든 설정을 알아야하는 것은 아니다. 우선, <code class="language-plaintext highlighter-rouge">coherence-cache-config.xml</code> 파일을 보자. cache-name이 <code class="language-plaintext highlighter-rouge">*</code> 로 설정되어 있는 것으로 보아, coherence 캐시 설정은 기본적으로 어떤 이름의 캐시라도 사용할 수 있도록 하는 것을 알 수 있다. 이 값을 변경하면 특정 이름의 캐시만 사용 할 수 있도록 제약을 줄 수있다.</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="nt">&lt;caching-scheme-mapping&gt;</span>
    <span class="nt">&lt;cache-mapping&gt;</span>
      <span class="nt">&lt;cache-name&gt;</span>*<span class="nt">&lt;/cache-name&gt;</span>
      <span class="nt">&lt;scheme-name&gt;</span>${coherence.profile near}-${coherence.client direct}<span class="nt">&lt;/scheme-name&gt;</span>
    <span class="nt">&lt;/cache-mapping&gt;</span>
  <span class="nt">&lt;/caching-scheme-mapping&gt;</span>
</code></pre></div></div>

<h2 id="캐시-서버-기동하기">캐시 서버 기동하기</h2>

<p>$COHERENCE_HOME/bin 폴더에 가면 cache-server.sh 파일을 볼 수 있다. 이 파일은 쉘 스크립트 파일인데 coherence 캐시 서버를 구동하는 기본적인 명령어가 기술되어 있다. 이 스크립트를 실행해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./cache-server.sh
</code></pre></div></div>

<p>다수의 로그가 나오고 마지막에 <code class="language-plaintext highlighter-rouge">Started DefaultCacheServer...</code> 메세지가 나타나면 기동에 성공한 것이다. 확인하였는가? 우리는 처음으로 coherence cache server를 기동하였다.</p>

<p>캐시 서버를 기동했지만 이 상태에서 특별히 더 할 것이 없다. 캐시 서버에 데이터를 입력하고 조회하는 기본적인 작업을 하기위해 캐시 팩토리를 기동해야 한다.</p>

<h2 id="캐시-팩토리-기동하기">캐시 팩토리 기동하기</h2>

<p>캐시 서버 터미널은 그대로 두고 새로운 터미널을 열어 $COHERENCE_HOME/bin 폴더에 가면 coherence.sh 파일을 볼 수 있다. 이 파일도 쉘 스크립트 파일인데 내용은 cache-server.sh 파일과 거의 비슷하다. 이 스크립트가 캐시 팩토리를 기동하는 스크립트이다.  스크립트를 실행해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./coherence.sh
</code></pre></div></div>

<p>아래와 같이 <code class="language-plaintext highlighter-rouge">Map (?):</code> 프롬프트가 나타나고 커서가 깜빡거리면 캐시팩토리가 정상적으로 기동된 것이다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Map <span class="o">(</span>?<span class="o">)</span>:
</code></pre></div></div>

<p>이 프롬프트에서 cache my 를 입력해보자. 프롬프트가 <code class="language-plaintext highlighter-rouge">Map (my):</code> 로 바뀔 것이다. 이 과정에서 어떤 일이 일어났는지 알아야 할 필요가 있다.</p>

<p>먼전, 캐시팩토리는 기동하면서 console 명령어를 입력받을 수 있는 상태가 되었다. 그 후 입력한 cache라는 명령어는 특정 cache를 선택하고 그 cache에서 명령을 수행한다는 의미이다. 그래서 프롬프트의 ?가 my로 바뀌었다. my는 cache의 이름이다. coherence cache config를 설명할 때 기본 설정은 어떤 이름도 cache로 사용가능하도록되어 있다고 설명했기 때문에 my라는 이름의 cache도 아무 제약없이 사용할 수 있는 것이다.</p>

<p>이제 데이터를 한번 등록해보자. 다음 명령어를 입력해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Map <span class="o">(</span>my<span class="o">)</span>: put key1 value1
</code></pre></div></div>

<p>이 명령어는 키가 key1이고 그 값이 value1이라는 데이터를 캐시에 등록한다. 이 값을 조회하기 위해 get 명령어를 사용할 수 있다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Map <span class="o">(</span>my<span class="o">)</span>: get key1
value1
</code></pre></div></div>

<p>결과로 value1을 확인할 수 있다.</p>

<p>이 상태에서 또 하나의 캐시 팩토리를 기동하자. 터미널을 새로 열고 coherence.sh를 실행하면 새로운 캐시팩토리가 생성된다. 이 상태에서 <code class="language-plaintext highlighter-rouge">cache my</code> 명령어로 기존 생성된 캐시로 들어간 후 <code class="language-plaintext highlighter-rouge">get key1</code> 명령어를 입력해보자. value1 결과가 보인다.</p>

<p>캐시 서버 1개, 캐시 팩토리 2개를 기동하여 3개의 인스턴스가 동일한 캐시 데이터를 공유하는 것을 확인하였다.</p>

<p>콘솔창에 나타나는 로그를 보며 눈치챘겠지만 하나의 캐시 팩토리가 조인할 때 마다 캐시 서버 로그에서 새로운 맴버가 조인했다는 것을 알려준다.</p>

<h2 id="마무리">마무리</h2>

<p>지금까지 coherence를 설치하고 기본 동작을 확인하였다. 하지만, 이제 시작일 뿐이다. 이것을 제대로 활용하기 위해서는 설정하는 방법, 동작하는 원리 등 정말 알아야 할 것이 많다. 다 이해 할 수는 없겠지만 잘 활용할 수 있도록 기본적인 것들을 하나씩 정리해야겠다.</p>

<h2 id="참조">참조</h2>

<p>https://docs.oracle.com/en/middleware/fusion-middleware/index.html</p>

<p>https://docs.oracle.com/middleware/1212/coherence/COHDG/gs_install.htm#COHDG4996</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="weblogic" /><summary type="html"><![CDATA[오라클에서 제공하는 in-memory 캐시 서비스인 coherence를 설치하는 내용.]]></summary></entry><entry><title type="html">Mac OS에 하나 이상의 다른 버전의 JDK 설치하기</title><link href="https://dololgun.github.io/macos/java-install/" rel="alternate" type="text/html" title="Mac OS에 하나 이상의 다른 버전의 JDK 설치하기" /><published>2021-01-16T00:00:00+00:00</published><updated>2021-01-16T00:00:00+00:00</updated><id>https://dololgun.github.io/macos/java-install</id><content type="html" xml:base="https://dololgun.github.io/macos/java-install/"><![CDATA[<p>이미 JDK가 설치되어 있는 환경에서 또 다른 JDK의 설치가 필요한 경우 고려해야 할 사항을 정리해보았다. 이 글은 MacOS(High Sierra)에 기반하고 있으며 다른 운영체제도(리눅스, 윈도우) 비슷하면서 조금씩 다른 방법으로 관리한다.</p>

<h3 id="자바-버전-및-위치-확인하기">자바 버전 및 위치 확인하기</h3>

<p>아래와 같은 명령어를 사용하면 지금 로그인한 사용자가 실행할 수 있는 java버전이 나타난다. 또한, which명령어를 사용하여 java 바이너리의 위치를 확인할 수 있다. 만약, java 명령어를 인식하지 못한다면 java가 설치되어 있지 않거나 path 설정이 되어 있지 않다고 생각하면 된다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>java <span class="nt">-version</span>
openjdk version <span class="s2">"1.8.0_265"</span>
OpenJDK Runtime Environment <span class="o">(</span>AdoptOpenJDK<span class="o">)(</span>build 1.8.0_265-b01<span class="o">)</span>
OpenJDK 64-Bit Server VM <span class="o">(</span>AdoptOpenJDK<span class="o">)(</span>build 25.265-b01, mixed mode<span class="o">)</span>

<span class="nv">$ </span>which java
/usr/bin/java
</code></pre></div></div>

<p>아래와 같이 path에 java가 있는 경로가 설정되어 있으니 전체경로 없이 java라는 명령어만으로도 정확히 해당 명령어를 실행할 수 있다. 추가로 내 계정에 설정되어 있는 path가 무엇인지 확인하기 위해서는 path변수의 값을 확인하면 된다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">echo</span> <span class="nv">$path</span>
/Users/geonho/.rbenv/shims /usr/local/bin /usr/bin /bin /usr/sbin /sbin /Applications/VMware Fusion.app/Contents/Public
</code></pre></div></div>

<p>이제, /usr/bin 경로로 이동해서 java 파일을 확인하자. java와 관련된 바이너리가 보이는데 흥미롭게 모두 심볼릭링크로 설정되어 있다. 이 링크가 가리키는 방향은 <code class="language-plaintext highlighter-rouge">/System/Library/Framworks</code> 폴더다. 운영체제마다 jdk를 관리하는 방법이 다른데, 맥은 /System/Library/Frameworks/JavaVM.framework 에서 버전별로 관리하는 느낌이다(단순 추정이다). 마치 리눅스에서 alternatives를 사용하는 것과 마찬가지로.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jar -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jar
jarsigner -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/jarsigner
java -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
javac -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javac
javadoc -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javadoc
javah -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javah
javap -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javap
javapackager -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javapackager
javaws -&gt; /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javaws
</code></pre></div></div>

<blockquote>
  <p>주의: M1 mac의 경우는 이 글과 다를 수 있다. 필자가 M1맥의 빅서 운영체제에서 확인한 결과 /usr/bin에 있는 java파일은 실제 바이너리 파일이었다.</p>

  <p>-rwxr-xr-x  1 root   wheel   136K  1  1  2020 java
-rwxr-xr-x  1 root   wheel   136K  1  1  2020 javac
-rwxr-xr-x  1 root   wheel   136K  1  1  2020 javadoc
-rwxr-xr-x  1 root   wheel   136K  1  1  2020 javah
-rwxr-xr-x  1 root   wheel   136K  1  1  2020 javap
-rwxr-xr-x  1 root   wheel   136K  1  1  2020 javapackager
-rwxr-xr-x  1 root   wheel   136K  1  1  2020 javaws</p>
</blockquote>

<p>좀 더 정확히 알아보기 위해 <code class="language-plaintext highlighter-rouge">/System/Library/Frameworks/JavaVM.framework/Versions/A</code> 폴더를 가면 자바와 관련된 라이브러리가 보인다. 그런데, 실제 자바라이브러리가 설치된 경로는 여기가 아니다. 진짜 경로는 다른 방법으로 구해야 한다. 다음 경로의 있는 명령어를 사용하자. 실제 자바가 설치되어 있는 경로는 바로 다음과 같다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>/usr/libexec/java_home
/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
</code></pre></div></div>

<p>해당 폴더로 이동해보면 우리가 자주 접했던 자바의 홈 디렉토리의 구조를 볼 수 있다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-r--r--r--   1 root  wheel      1522  7 29 00:20 ASSEMBLY_EXCEPTION
-r--r--r--   1 root  wheel     19274  7 29 00:20 LICENSE
-r--r--r--   1 root  wheel    152996  7 29 00:20 THIRD_PARTY_README
drwxr-xr-x  45 root  wheel      1440  7 29 00:21 bin
drwxr-xr-x   3 root  wheel        96  7 29 01:39 bundle
drwxr-xr-x   9 root  wheel       288  7 29 00:20 include
drwxr-xr-x   7 root  wheel       224  7 29 00:20 jre
drwxr-xr-x   9 root  wheel       288  7 29 00:20 lib
drwxr-xr-x   5 root  wheel       160  7 29 00:20 man
-rw-r--r--   1 root  wheel        87  7 29 00:20 release
drwxr-xr-x  12 root  wheel       384  7 29 00:20 sample
-rw-r--r--   1 root  wheel  52658253  7 29 00:20 src.zip
</code></pre></div></div>

<p>왜 이런거까지 알아야 하는지 이해할 수 없을지도 모르겠지만, 하나의 운영체제의 다른 버전의 자바라이브러리를 한 개 이상 설치하고 자유롭게 버전을 변경하기 위해서는 알면 더 좋다. 사실 몰라도 강제로 라이브러리 위치를 잡아주면 되지만 라이브러리 관리가 점점 복잡해진다.</p>

<h3 id="jdk-추가-설치">JDK 추가 설치</h3>

<p>상황이 이렇다는 것을 알아두고, 추가로 다른 jdk를 설치해보자. 필자는 weblogic 관련된 설치를 하기 위해 oracle jdk를 home brew를 이용하여 설치해 보았다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>brew search oracle
<span class="o">==&gt;</span> Casks
color-oracle                                       navicat-for-oracle                                 oracle-jdk                                         oracle-jdk-javadoc
</code></pre></div></div>

<p>설치할 수 있는 oracle-jdk가 있는데 Casks를 이용하여 설치해야 한다. 다음과 같은 명령어로 설치를 하자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>brew <span class="nb">install</span> <span class="nt">--cask</span> oracle-jdk

...중략...
installer: Package name is JDK 15.0.1
installer: Installing at base path /
installer: The <span class="nb">install </span>was successful.
🍺  oracle-jdk was successfully installed!
</code></pre></div></div>

<p>위와 같이 base path <code class="language-plaintext highlighter-rouge">/</code>에 설치되었다고 나온다. 그런데 <code class="language-plaintext highlighter-rouge">/</code>가면 추가로 설치된 파일이 보이지 않는다.</p>

<p>자바 버전을 다시 확인해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>java <span class="nt">--version</span>
java 15.0.1 2020-10-20
Java<span class="o">(</span>TM<span class="o">)</span> SE Runtime Environment <span class="o">(</span>build 15.0.1+9-18<span class="o">)</span>
Java HotSpot<span class="o">(</span>TM<span class="o">)</span> 64-Bit Server VM <span class="o">(</span>build 15.0.1+9-18, mixed mode, sharing<span class="o">)</span>
</code></pre></div></div>

<p>이런, java의 버전이 바뀌었다. 포스트의 처음에 했던 과정을 되풀이하여 java 바이너리가 어디에 있는지 확인해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>/usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents/Home
</code></pre></div></div>

<p>확인을 해보니 자바 홈의 경로가 위와 같이 바뀌었다. <code class="language-plaintext highlighter-rouge">/Library/Java/JavaVirtualMachines</code> 로 이동하면 아래와 같이 2개의 자바라이브러리가 설치되어 있다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>drwxr-xr-x  3 root  wheel    96B  8 17 16:01 adoptopenjdk-8.jdk
drwxr-xr-x  3 root  wheel    96B  1 16 14:45 jdk-15.0.1.jdk
</code></pre></div></div>

<p>그럼 어떤 설정이 운영체제의 현재의 자바 버전이 바뀌도록 하였을까? 인터넷 검색을 한 결과 별도의 설정이 없다면 운영체제가 각 자바 버전의 <code class="language-plaintext highlighter-rouge">Info.plist</code> 파일을 확인하여 가장 최신 버전을 기본으로 사용한다고 한다. 예를 들어, jdk-15의 Info.plist(<code class="language-plaintext highlighter-rouge">/Library/Java/JavaVirtualMachines/jdk-15.0.1.jdk/Contents</code> 에 있다) 파일과  adoptopnejdk-8의 Info.plist 파일을 비교하여 가장 최신버전을 선택한다는 것이다.</p>

<h3 id="특정-jdk-비활성화-하기">특정 JDK 비활성화 하기</h3>

<p>최신버전이 jdk-15이니깐 이것의 Info.plist 파일을 info.plist.disable 파일로 변경해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo mv </span>Info.plist Info.plist.disable
</code></pre></div></div>

<p>자바 버전을 검색해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>java <span class="nt">-version</span>
openjdk version <span class="s2">"1.8.0_265"</span>
OpenJDK Runtime Environment <span class="o">(</span>AdoptOpenJDK<span class="o">)(</span>build 1.8.0_265-b01<span class="o">)</span>
OpenJDK 64-Bit Server VM <span class="o">(</span>AdoptOpenJDK<span class="o">)(</span>build 25.265-b01, mixed mode<span class="o">)</span>
</code></pre></div></div>

<p>와우, 다시 예전의 자바버전으로 돌아왔다. 하지만, 이렇게 할 경우 운영체제 전 영역에서 jdk-15는 사용할 수 없다. 만약 서로 다른 유저가 서로 다른 자바 버전을 사용할 수 없다.</p>

<p>유저별로 다른 자바 버전을 사용하는 방법도 존재한다. 우선 비활성화 시켰던 jdk-15를 다시 활성시키자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo mv </span>Info.plist.disable Info.plist

<span class="nv">$ </span>java <span class="nt">-version</span>
java 15.0.1 2020-10-20
Java<span class="o">(</span>TM<span class="o">)</span> SE Runtime Environment <span class="o">(</span>build 15.0.1+9-18<span class="o">)</span>
Java HotSpot<span class="o">(</span>TM<span class="o">)</span> 64-Bit Server VM <span class="o">(</span>build 15.0.1+9-18, mixed mode, sharing<span class="o">)</span>
</code></pre></div></div>

<p>### 유저별로 사용하는 JDK 설정하기</p>

<p>특정 유저에게 JDK를 지정하고자 하면 해당 <code class="language-plaintext highlighter-rouge">JAVA_HOME</code> 변수를 설정해야 한다. 이 변수가 java 플랫폼에서는 약속인것 같다. 이 변수가 설정이 안되어 있다면 이전 단계에서 언급한 운영체제의 설정을 따른다.</p>

<p>유저의 홈디렉토리에 <code class="language-plaintext highlighter-rouge">.profile</code> 을 생성하고 다음 내용을 추가한다. 이미 해당 파일이 생성돼 있을 수도 있다.</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># jdk 1.8버전을 사용하는 유저</span>
<span class="nb">export </span><span class="nv">JAVA_HOME</span><span class="o">=</span><span class="sb">`</span>/usr/libexec/java_home <span class="nt">-v</span> 1.8<span class="sb">`</span>
</code></pre></div></div>

<p>위의 명령어는 JAVA_HOME 변수를 1.8버전으로 설정하는 것이다.</p>

<p>.profile 을 선택한 이유는 쉘과 상관없이 이 유저에게는 이 설정을 적용하기 위해서다. 자세한 내용은 <a href="../linux/2021-01-15-shell-profile.md">쉘(Shell)의 초기화 스크립트 동작 방식 정리</a> 를 참고하자.</p>

<p>다음 로그인 부터는 이 설정이 적용되고 현재에도 이 설정을 적용하고자 한다면 source 명령어를 사용한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">source</span> ~/.profile
</code></pre></div></div>

<p>그리고 다시 자바 버전을 확인하면 버전이 변경된 것을 확인할 수 있다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>java <span class="nt">-version</span>
openjdk version <span class="s2">"1.8.0_265"</span>
OpenJDK Runtime Environment <span class="o">(</span>AdoptOpenJDK<span class="o">)(</span>build 1.8.0_265-b01<span class="o">)</span>
OpenJDK 64-Bit Server VM <span class="o">(</span>AdoptOpenJDK<span class="o">)(</span>build 25.265-b01, mixed mode<span class="o">)</span>
</code></pre></div></div>

<h2 id="참조">참조</h2>

<p>https://apple.stackexchange.com/questions/188485/setting-java-correctly-on-mac</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="macos" /><summary type="html"><![CDATA[이미 JDK가 설치되어 있는 환경에서 또 다른 JDK의 설치가 필요한 경우 고려해야 할 사항을 정리해보았다. 이 글은 MacOS(High Sierra)에 기반하고 있으며 다른 운영체제도(리눅스, 윈도우) 비슷하면서 조금씩 다른 방법으로 관리한다.]]></summary></entry><entry><title type="html">쉘(Shell)의 초기화 스크립트 동작 방식 정리</title><link href="https://dololgun.github.io/linux/shell-profile/" rel="alternate" type="text/html" title="쉘(Shell)의 초기화 스크립트 동작 방식 정리" /><published>2021-01-15T00:00:00+00:00</published><updated>2021-01-15T00:00:00+00:00</updated><id>https://dololgun.github.io/linux/shell-profile</id><content type="html" xml:base="https://dololgun.github.io/linux/shell-profile/"><![CDATA[<h2 id="쉘shell-이란">쉘(Shell) 이란</h2>

<p>쉘이란 운영체제가 사용자와 대화를 할 수 있는 다리 역할을 하는 프로그램이다. 우리가 흔히 사용하는 윈도우 운영체제를 사용하면 이 말을 이해하기 힘들것이다. 왜냐하면 GUI기간의 운영체제를 사용하면 쉘을 사용할 일이 거의 없기 때문이다. 하지만 리눅스, 유닉스 같은 운영체제를 사용하면 쉘을 이용하여 운영체제를 사용하는 경우가 많다.</p>

<p><img src="../../assets/images/post/linux/image-20210116215213743.png" alt="필자가 사용하는 쉘" />위 그림은 필자가 사용하는 쉘이다.</p>

<p>쉘은 종류가 다양한데 일반적으로 많이 사용되는 쉘은 bash이고 요새는 zsh가 많이 사용된다고 한다. 필자도 mac os를 사용할 때는 zsh를 쓰고 linux를 사용할 때는 bash를 사용한다.</p>

<p>그렇다면 현재 내가 사용하고 있는 쉘은 무엇인지 어떻게 알까? 아래 명령어를 사용하면 알 수 있다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">echo</span> <span class="nv">$SHELL</span>
/bin/bash
</code></pre></div></div>

<p>위와 같이 내가 사용하는 쉘 프로그램의 경로가 출력된다. 위의 결과는 bash를 사용하는 것으로 나타났다.</p>

<p>또 한가지 궁금한 점이 생길 수 있다. 내가 사용하는 운영체제에서 사용가능한 쉘은 어떻게 알 수 있을까? 아래 명령어를 사용해보자.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">cat</span> /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
</code></pre></div></div>

<p>사용 가능한 쉘 목록이 위와 같이 조회된다.</p>

<h2 id="로그인-쉘-vs-비로그인-쉘">로그인 쉘 vs 비로그인 쉘</h2>

<p>우리가 쉘을 실행하는 방법은 여러가지가 있다.</p>

<ol>
  <li>터미널 창의 로그인 프롬프트를 통해서 로그인한다.</li>
  <li>이미 로그인 한 상태에서 su - ${유저명}을 이용하여 다른 유저로 변경한다.</li>
  <li>GUI기반의 운영체제에서 터미널을 열어 해당 유저의 쉘을 실행한다.</li>
  <li>ssh로 접속하고 나서 다시 bash를 실행한다.</li>
</ol>

<p>1 ~ 4번 모두 같은 유저이고 이 유저가 bash를 사용한다면 bash를 사용하여 운영체제와 대화를 할 것이다. 하지만 같은 bash라 할지라도 1번의 경우만 로그인 쉘로 동작하고 2,3,4번의 경우 비로그인 쉘로 동작한다. 비로그인 쉘은 로그인 없이 실행하는 Shell을 말한다.</p>

<p>그렇다면, 로그인 쉘과 비로그인 쉘은 어떻게 다를까? 그전에 우리가 로그인 할 때 어떤 일이 일어나는지 알아야 한다.</p>

<h3 id="로그인-시-일어나는-일">로그인 시 일어나는 일</h3>

<p>로그인 쉘이 bash인 경우를 예로 들어보자. 운영체제는 알아서 다음 과정으로 쉘 스크립트를 수행한다.</p>

<ol>
  <li>/etc/profile</li>
  <li><code class="language-plaintext highlighter-rouge">~/.bash_profile</code> or <code class="language-plaintext highlighter-rouge">~/.bash_login</code> or <code class="language-plaintext highlighter-rouge">~/.profile</code></li>
  <li>~/.bashrc</li>
  <li>/etc/bashrc</li>
</ol>

<p>로그인 쉘이 동작하는 경우 1~4번 과정이 모두 수행되지만 비로그인 쉘이 동작하는 경우 3~4번 과정만 수행된다.</p>

<p>우리가 또 숙지해야 할 것이 있는데 위의 스크립트 파일은 사용자별, 쉘별로 수행되는 것이 다르다는 것이다.</p>

<h3 id="사용자-별-구분">사용자 별 구분</h3>

<p>파일의 위치가 <code class="language-plaintext highlighter-rouge">/etc</code> 하위 인지 <code class="language-plaintext highlighter-rouge">~/</code>  하위 인지에 따라 모든 사용자, 특정 사용자인지가 결정된다. 즉, 2번과 3번 과정은 사용자의 홈디렉터리(~/)에 파일이 존재하면 실행되고 존재하지 않으면 실행되지 않는다. 일반적으로 자신이 직접 추가하지 않으면 이런 파일들은 생성되지 않는다. 반대로 1번과 4번은 사용자와 상관없이 무조건 수행된다. 단, 어떤 쉘을 사용하느냐에 따라 수행될수도 안될 수도 있는 파일이 있다.</p>

<h3 id="쉘-별-구분">쉘 별 구분</h3>

<p>.bash_profile과 .bash_login, .bashrc, /etc/bashrc는 bash전용이다. bash로 로그인 하는 경우만 수행된다는 말이다. 이와 비슷하게 다른 쉘들도 자신만의 로그인 스크립트가 있다. 이와 반해 .profile은 쉘과 상관없이 수행된다.</p>

<p>## /etc/profile 효과적으로 수정하기</p>

<p>/etc/profile 의 내용을 살펴보면 기본 설정을 위한 스크립트가 작성되어 있다. 그 중, 아래와 같은 스크립트를 살펴볼 수 있다. (CentOS7을 기준)</p>

<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">for </span>i <span class="k">in</span> /etc/profile.d/<span class="k">*</span>.sh /etc/profile.d/sh.local <span class="p">;</span> <span class="k">do
    if</span> <span class="o">[</span> <span class="nt">-r</span> <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
        if</span> <span class="o">[</span> <span class="s2">"</span><span class="k">${</span><span class="p">-#*i</span><span class="k">}</span><span class="s2">"</span> <span class="o">!=</span> <span class="s2">"</span><span class="nv">$-</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span>
            <span class="nb">.</span> <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span>
        <span class="k">else</span>
            <span class="nb">.</span> <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span> <span class="o">&gt;</span>/dev/null
        <span class="k">fi
    fi
done</span>
</code></pre></div></div>

<p>/etc/profile.d 폴더에 .sh로 끝나는 모든 파일을 실행한다. 그렇기 때문에 /etc/profile 스크립트를 추가할 일이 생길 때 이 파일을 직접 수정하지말고 스크립트의 역할을 잘 표현하는 .sh로 끝나는 파일명을 작성하여 /etc/profile.d 폴더에 추가하는 것이 관리차원에서 더 좋다.</p>

<h2 id="결론">결론</h2>

<p>쉘 초기화 스크립트의 동작 특성을 잘 이해하고 내가 추가하고자 하는 스크립트가 어떤 파일에 들어가야 하는지 잘 결정하는 것이 중요하다.</p>

<h2 id="참조">참조</h2>

<p>https://webdir.tistory.com/126#:~:text=SHELL%20%2Fbin%2Fbash-,Login%20shell%20vs%20Non%2Dlogin%20shell,%ED%95%98%EC%97%AC%20%ED%99%98%EA%B2%BD%EC%9D%84%20%EC%84%A4%EC%A0%95%ED%95%9C%EB%8B%A4.</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="linux" /><summary type="html"><![CDATA[쉘(Shell) 이란]]></summary></entry><entry><title type="html">체크스타일[checkstyle] - 7 : with sonarqube 2</title><link href="https://dololgun.github.io/checkstyle/checkstyle-sonarqube-plugin2/" rel="alternate" type="text/html" title="체크스타일[checkstyle] - 7 : with sonarqube 2" /><published>2020-12-30T00:00:00+00:00</published><updated>2020-12-30T00:00:00+00:00</updated><id>https://dololgun.github.io/checkstyle/checkstyle-sonarqube-plugin2</id><content type="html" xml:base="https://dololgun.github.io/checkstyle/checkstyle-sonarqube-plugin2/"><![CDATA[<h2 id="개요">개요</h2>

<p>소나큐브 체크스타일 플러그인에는 우리가 작성한 커스터 체크가 포함되어 있지 않다.</p>

<p>내가 체크스타일을 사용하는 큰 이유 중 하나는 직접 작성한 커스텀 체크를 활용하는 것인데 소나큐브 체크스타일 플러그인에서 커스텀 체크를 사용할 수 없다니… 소나큐브에서 체크스타일을 사용하는 것의 의미가 없다.</p>

<p>그렇다면 어떻게 소나큐브에서 우리가 작성한 커스텀 체크를 사용할 수 있을까? 답은 간단하다, 소나큐브 체크스타일을 플러그인을 직접 수정하면 된다.</p>

<p>다행히, 소나큐브 체크스타일 플러그인의 소스는 깃헙을 통해 제공되고 있다.</p>

<p>소나큐브 체크스타일 플러그인을 수정하는 것이 어려운 일이었다면 필자도 이렇게 포스팅을 남기진 않았을 것이다. 우리가 작성한 커스텀 체크 정보를 소나큐브 체크스타일 플러그인에 추가만 해주면 된다. 아이러니 하게 가장 어려운 일은 받은 소스를 컴파일 하는 것이었다.</p>

<p>그렇다면 천천히 소나큐브 체크스타일 플러그인 소스를 분석해보자.</p>

<h2 id="소스받기">소스받기</h2>

<p>소스는 <a href="https://github.com/checkstyle/sonar-checkstyle">깃헙 소나 체크스타일</a>에서 받을 수 있다. 소스를 받은 후 이클립스에 import한다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201219150743956.png" alt="image-20201219150743956" /></p>

<p>위와 같이 오류없이 소스가 import되면 아주 운이 좋은 것이고 누군가는 오류가 날수도 있는데 이유는 이클립스에 메이븐 컨넥터가 설치되어 있지 않아서 발생하는 오류로 빌드에는 지장이 없다.</p>

<h2 id="커스텀-체크-추가">커스텀 체크 추가</h2>

<p>위에서 언급한 대로 소나큐브 체크스타일 플러그인의 소스를 직접 수정할 필요는 없다. 대신 몇 가지 설정만 수정한다.</p>

<h3 id="커스텀-체크-모듈-추가">커스텀 체크 모듈 추가</h3>

<p>pom.xml 파일을 열어 이전 포스팅 <a href="/checkstyle/custom-check/">체크스타일[checkstyle] - 5 : 나만의 체크 만들기</a>  에서 작성한 커스텀 체크를 디펜던시에 추가한다.</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>...
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>org.apache.commons<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>commons-lang3<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>3.10<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>org.reflections<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>reflections<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>0.9.12<span class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
    <span class="c">&lt;!-- 나의 커스텀 체크 추가 --&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>app.my<span class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>checkstyle-custom<span class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>0.0.1-SNAPSHOT<span class="nt">&lt;/version&gt;</span>
        <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;/dependencies&gt;</span>
...
</code></pre></div></div>

<p>소나 체크스타일 플러그인을 빌드하면 내가 작성한 커스텀 체크 모듈을 포함한다.</p>

<blockquote>
  <p>주의 : checkstyle-custom은 로컬 리포지토리에 저장되어 있어야 한다. 왜냐하면 checkstyle-custom가 원격 리포지토리(예를 들어, 메이븐 central 리포지토리)에 없기 때문이다. checkstyle-custom 빌드할 때 mvn install 명령어로 로컬 리포지토리에 저장하는 것을 잊지말자.</p>
</blockquote>

<h3 id="rule-설정-추가">Rule 설정 추가</h3>

<p>소나큐브에 추가된 체크스타일 모듈이 무엇인지 알려줘야 하는 작업이다. 소스에서 아래 경로의 파일을 열어보자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/sonar-checkstyle/src/main/resources/org/sonar/plugins/checkstyle/rules.xml
</code></pre></div></div>

<p>이 파일에는 체크스타일에서 사용할 수 있는 모든 Rule이 정의되어 있다. 여기에 우리가 작성한 커스텀 체크 Rule도 추가해야 한다. 아래와 같이 파일 가장 하단에 커스텀 체크라는 주석과 함께 우리가 작성한 커스텀 체크 정보를 기입하였다.</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>	<span class="nt">&lt;rule</span>
		<span class="na">key=</span><span class="s">"com.puppycrawl.tools.checkstyle.checks.modifier.ClassMemberImpliedModifierCheck"</span><span class="nt">&gt;</span>
		<span class="nt">&lt;priority&gt;</span>MINOR<span class="nt">&lt;/priority&gt;</span>
		<span class="nt">&lt;name&gt;</span><span class="cp">&lt;![CDATA[Class Member Implied Modifier]]&gt;</span><span class="nt">&lt;/name&gt;</span>
		<span class="nt">&lt;configKey&gt;</span><span class="cp">&lt;![CDATA[Checker/TreeWalker/ClassMemberImpliedModifier]]&gt;</span><span class="nt">&lt;/configKey&gt;</span>

		<span class="nt">&lt;param</span> <span class="na">key=</span><span class="s">"violateImpliedStaticOnNestedEnum"</span> <span class="na">type=</span><span class="s">"BOOLEAN"</span><span class="nt">&gt;</span>
			<span class="nt">&lt;defaultValue&gt;</span>true<span class="nt">&lt;/defaultValue&gt;</span>
		<span class="nt">&lt;/param&gt;</span>
		<span class="nt">&lt;param</span> <span class="na">key=</span><span class="s">"violateImpliedStaticOnNestedInterface"</span>
			<span class="na">type=</span><span class="s">"BOOLEAN"</span><span class="nt">&gt;</span>
			<span class="nt">&lt;defaultValue&gt;</span>true<span class="nt">&lt;/defaultValue&gt;</span>
		<span class="nt">&lt;/param&gt;</span>
	<span class="nt">&lt;/rule&gt;</span>

	<span class="c">&lt;!-- 커스텀 체크 --&gt;</span>
	<span class="nt">&lt;rule</span> <span class="na">key=</span><span class="s">"app.my.checks.MyPackageNameCheck"</span><span class="nt">&gt;</span>
		<span class="nt">&lt;priority&gt;</span>MINOR<span class="nt">&lt;/priority&gt;</span>
		<span class="nt">&lt;name&gt;</span><span class="cp">&lt;![CDATA[My Package Name]]&gt;</span><span class="nt">&lt;/name&gt;</span>
		<span class="nt">&lt;configKey&gt;</span><span class="cp">&lt;![CDATA[Checker/TreeWalker/MyPackageName]]&gt;</span><span class="nt">&lt;/configKey&gt;</span>
	<span class="nt">&lt;/rule&gt;</span>
<span class="nt">&lt;/rules&gt;</span>
</code></pre></div></div>

<p>Rule 이름을 My Package Name으로 주었다. configKey 명칭은 체크스타일 설정파일의 module name의 위치가 연관성이 있어 보인다.</p>

<h3 id="html-파일-추가">html 파일 추가</h3>

<p>다음 경로에 rule의 내용을 정의한 html파일을 추가 한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>${소스폴더}/src/main/resources/org/sonar/l10n/checkstyle/rules/checkstyle
</code></pre></div></div>

<p>파일명은 커스텀 체크 클래스의 full경로명으로 작성한다. 전체경로와 파일명은 다음과 같다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/sonar-checkstyle/src/main/resources/org/sonar/l10n/checkstyle/rules/checkstyle/app.my.checks.MyPackageNameCheck.html
</code></pre></div></div>

<p>파일내용은 다음과 같이 작성하자.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>나의 커스텀 체크 패키지 명칭
</code></pre></div></div>

<h2 id="빌드">빌드</h2>

<p>테스트를 포함하여 빌드하면 오류가 발생하기 때문에 테스트를 하지 않고 빌드를 한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn <span class="nt">-Pno-validations</span> clean package
</code></pre></div></div>

<p>빌드가 성공하면 <code class="language-plaintext highlighter-rouge">${소스폴더}/target</code>에 <code class="language-plaintext highlighter-rouge">checkstyle-sonar-plugin-${version}-SNAPSHOT.jar</code> 파일이 생성된 것을 확인할 수 있다.</p>

<p>이 jar파일의 압축을 풀고 /META_INF/lib 폴더로 가보자. 아래와 같이 커스텀 체크 모듈(checkstyle-custom-0.0.1-SNAPSHOT.jar)이 존재하는지 확인하자.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201219160730759.png" alt="image-20201219160730759" /></p>

<h2 id="플러그인-다시-설치">플러그인 다시 설치</h2>

<p>원래 설치되어 있던 소나큐브 체크스타일 플러그인을 제거하고 앞에서 빌드한 커스텀 체크모듈을 포함하는 소나큐브 체크스타일을 추가하자. 플러그인 추가를 위한 자세한 내용은 앞선 포스팅  <a href="/checkstyle/chekcstyle-sonarqube-plugin/">체크스타일[checkstyle] - 6 : with sonarqube</a> 을 참조하자.</p>

<p>플러그인에 문제가 있다면 소나큐브 서버가 재기동 되지 않으니 서버를 기동 시 콘솔창의 로그를 잘 확인하도록 하자.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201219163400169.png" alt="image-20201219163400169" /></p>

<h2 id="rule-확인">Rule 확인</h2>

<p>서버가 재기동 된 후, Rule 메뉴에서 체크스타일 Rule을 확인하면 아래와 같이 우리가 작성한 커스텀 체크의 Rule이 나타난다. (감격!)</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201219163256404.png" alt="image-20201219163256404" /></p>

<p>상세 정보를 확인하면 다음과 같다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201219173424941.png" alt="image-20201219173424941" /></p>

<p>우리가 html에 작성한 <code class="language-plaintext highlighter-rouge">나의 커스텀 체크 패키지 명칭</code> 내용이 나타난다.</p>

<h2 id="마무리">마무리</h2>

<p>이것으로 필자가 체크스타일을 사용한 경험을 마무리 하겠다.</p>

<p>체크스타일의 기본적인 내용으로 시작하여 커스텀 체크를 작성하는 방법을 알아보았고 메이븐 플러그인, 이클립스 플러그인, 소나큐브 플러그인을 이용하여 더욱 편하게 체크스타일을 사용하는 방법을 알아보았다.</p>

<p>프로젝트 마다 지켜야 할 고유의 명명 규칙과 소스코드 작성 규칙이 있지만 지금까지 공부한 체크스타일을 이용하여 해당 규칙을 검사하는 것을 자동화 할 수 있을 것으로 기대한다.</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="checkstyle" /><summary type="html"><![CDATA[개요]]></summary></entry><entry><title type="html">체크스타일[checkstyle] - 6 : with sonarqube</title><link href="https://dololgun.github.io/checkstyle/chekcstyle-sonarqube-plugin/" rel="alternate" type="text/html" title="체크스타일[checkstyle] - 6 : with sonarqube" /><published>2020-12-19T00:00:00+00:00</published><updated>2020-12-19T00:00:00+00:00</updated><id>https://dololgun.github.io/checkstyle/chekcstyle-sonarqube-plugin</id><content type="html" xml:base="https://dololgun.github.io/checkstyle/chekcstyle-sonarqube-plugin/"><![CDATA[<h2 id="소나큐브란-">소나큐브란 ?</h2>

<p>체크스타일을 시리즈로 포스팅하다가 갑자기 왠 소나큐브를 이야기 하냐고? 아는 사람은 알겠지만 소나큐브는 코드인스펙션 영역에서 아주 유명한 도구이다. 궁금한 사람은 필자의 포스팅 <a href="/sonarqube/sonarqube/">소나큐브 설치 플러그인 포스팅</a> 을 참고하자.</p>

<h2 id="소나큐브-체크스타일-플러그인">소나큐브 체크스타일 플러그인</h2>

<p>체크스타일도 플러그인을 제공하는 방식으로 소나큐브와 연동된다. 플러그인이 하는 역할을 소나큐브를 통해 체크스타일의 코드인스펙션 기능을 실행하는 것이다. 물론, 실행 된 결과도 소나큐브를 통해서 확인할 수 있으며 체크스타일의 다양한 코딩 룰도 소나큐브를 통해서 설정할 수 있다.</p>

<h3 id="플러그인-설치">플러그인 설치</h3>

<p>소나큐브에서 플러그인을 설치하는 방법은 2가지가 있다. 자동으로 설치하는 방법이 편하지만 이 포스팅에서는 수동으로 설치하는 방법을 사용하겠다. 이유는 나중에 설명하겠다. 먼저, <a href="https://github.com/checkstyle/sonar-checkstyle/releases">소나큐브 체크스타일 플러그인</a>을 받자. <code class="language-plaintext highlighter-rouge">checkstyle-sonar-plugin-8.37.jar</code> 파일을 받을 수 있는데 이 파일을 소나큐브가 설치되어 있는 폴더의 다음 경로에 위치시킨다.</p>

<blockquote>
  <p>주의 : 미리 소나큐브가 설치되어 있어야 한다</p>
</blockquote>

<p>플러그인 파일 경로 :</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>${소나큐브 익스텐션 폴더}/plugins
</code></pre></div></div>

<blockquote>
  <p>[메모] : 소나큐브 익스텐션 폴더의 위치는 소나큐브를 설치한 위치에 따라 다르다. 필자는 소나큐브를 도커 이미지로 설치했으며 컨테이너에서 지정되어 있는 소나큐브 익스텐션 폴더를 호스트의 볼륨과 매칭하였다.</p>
</blockquote>

<p>플러그인(jar) 파일을 이동하였다면 소나큐브를 재시작하고 소나큐브 웹 콘솔에 접속해보자.</p>

<p>무엇이 달라졌을까? 유심히 보지 않으면 알아채기가 쉽지 않다.</p>

<p>체크스타일 플러그인을 적용하기 전의 소나큐브 룰 목록은 다음과 같다. (소나큐브 웹UI의 Rule 탭에서 확인할 수 있다)</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201206153549493.png" alt="image-20201206153549493" /></p>

<p>체크스타일 플러그인을 설치한 후의 Rule 목록을 보면 체크스타일 Rule 목록이 추가되어 있는 것을 확인할 수 있다. 총 354개의 Rule이 추가되었다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201206154214255.png" alt="image-20201206154214255" /></p>

<p>소나큐브에서 체크스타일 Rule을 사용할 수 있는 것이다.</p>

<h2 id="체크스타일-설정하기">체크스타일 설정하기</h2>

<p>소나큐브에서 체크스타일을 설정할 때 주의해야 할 점이 있다. 우리는 지금까지 체크스타일 Rule 설정을 소스 프로젝트 내부에 작성(이전 포스팅의 sun_checks.xml)하였다. 하지만 소나큐브에서는 그 설정을 소나큐브 웹UI에서 하게 되고 소나큐브 서버에서 저장 된다. 그러니 지금까지 작성한 sun_chekcs.xml파일을 소나큐브 설정으로 옮겨야 한다.</p>

<p>일단 연습삼아 체크스타일의 LineLength 룰을 소나큐브에 적용해보자. 체크스타일의 xml파일에서 LineLengh설정은 다음과 같다.</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="nt">&lt;module</span> <span class="na">name=</span><span class="s">"LineLength"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"fileExtensions"</span> <span class="na">value=</span><span class="s">"java"</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/module&gt;</span>
</code></pre></div></div>

<h3 id="체크스타일-룰-확인">체크스타일 룰 확인</h3>

<p>소나큐브에서는 Line Length가 어떤 룰로 이뤄져있는지 확인해보자.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201206202832949.png" alt="image-20201206202832949" /></p>

<p>이 설정을 기억하고 Quality Profils를 생성하자.</p>

<h3 id="quality-profile-생성">Quality Profile 생성</h3>

<p>Quality Profiles를 생성하자. create버큰을 클릭하면 다음과 같이 이름과 언어를 설정하는 부분이 나타난다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201206204007613.png" alt="image-20201206204007613" /></p>

<p>이름은 checkstyle way로 하고 언어는 java를 선택하자.</p>

<h3 id="룰-추가">룰 추가</h3>

<p>처음 Quality Profile을 설정하면 활성화 되어 있는 룰이 하나도 없다. 룰을 하나 씩 추가하며 sun_chekcs.xml과 동일한 기능을 하도록 하는 것이다. 이제 Line Length룰을 활성화한다. chekcstyle way설정화면에서 Active more를 클릭하자.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201206204949278.png" alt="₩" /></p>

<p>java와 관련된 모든 룰이 다 보이는데 여기서 Line Length 룰을 찾아 Activate를 하자. 그러면 다음과 같이 선택한 룰에서 설정 가능한 항목이 나타난다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201206203307004.png" alt="image-20201206203307004" /></p>

<p>max는 40으로 하고 tabWidth는 4로 설정하자.</p>

<h3 id="체크스타일-설정-파일을-이용한-quality-profile-생성">체크스타일 설정 파일을 이용한 Quality Profile 생성</h3>

<p>이번엔 체크 스타일 설정 xml을 이용하여 Quality Profile을 생성해보자. 새로운 Quaility Profile을 생성한다.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Name : checkstyle way2
Language : Java
Parent : None
Checkstyle : checkstyle 포스팅에서 계속 다룬 sun_checkstyle.xml 파일
</code></pre></div></div>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201217223323734.png" alt="image-20201217223323734" /></p>

<p>그런데, 아래 오류 메세지가 나타난다.</p>

<blockquote>
  <p>Rule template can’t be activated on a Quality profile: checkstyle:com.puppycrawl.tool…</p>
</blockquote>

<p>이유가 뭘까?</p>

<p>체크스타일 rule을 확인해보자. 아래와 같이 <code class="language-plaintext highlighter-rouge">RULE TEMPLATE</code> 표시가 있는 Rule과 그렇지 않은 Rule이 있다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201217223744915.png" alt="image-20201217223744915" /></p>

<p><code class="language-plaintext highlighter-rouge">RULE TEMPLATE</code> 표시가 없는 rule은 즉시 active 할 수 있지만 표시가 있는 rule은 activate를 바로 할 수 없다. 대신 Custome Rules을 생성해야 한다.</p>

<p>예를 들어, Final Parameters는 sun_checks.xml에 아래와 같이 설정되어 있다.</p>

<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;module</span> <span class="na">name=</span><span class="s">"FinalParameters"</span> <span class="nt">/&gt;</span>
</code></pre></div></div>

<p>그런데 Final Parameters가 <code class="language-plaintext highlighter-rouge">RULE TEMPLATE</code>이기 때문에 오류가 발생한다. 이를 해결하기 위해, Final Parameters에 대한 커스텀 rule을 생성하자. 아래 화면에서 create를 클릭한다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201217231535431.png" alt="image-20201217231535431" /></p>

<p>커스텀 룰을 만들 때 Key를 입력하게 되어 있는 이 값을 sun_checks.xml 파일과 맞추어 지정하는 것이 중요하다. Key는 체크스타일 설정파일의 module name과 같도록 해야한다. 아래 그림이 그 예이다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201217231627107.png" alt="image-20201217231627107" /></p>

<blockquote>
  <p>주의 : 한번 추가한 커스텀 룰은 삭제가 되지 않는다. 버그인가? delete버튼이 있어 삭제하면 실제로 삭제된 것처럼 보이나, 서버를 재시작하면 삭제했던 룰이 다시 나타나니 이점에 유의하자. 웹UI의 도움말을 보면 의도적으로 삭제하지 않는다고 한다.</p>
</blockquote>

<p>지금 까지 설명한 방법으로 sun_checks.xml에 있는 module 중,  소나큐브 체크스타일에서 <code class="language-plaintext highlighter-rouge">RULE TEMPLATE</code>로 되어 있는 것은 모두 커스텀 룰을 생성해야 한다. module name과 key를 맞추는 것도 있지말자.</p>

<p>커스텀 룰을 모두 생성하였다면 이제 체크스타일 xml설정 파일로 quality profile을 만들 수 있다. 그런데, 이 작업이 생각보다 쉽지 않다. 일일이 모든 module name을 확인해야 한다. 어쩌면, 앞서 설명한 하나 하나 필요한 Rule을 추가하는 것이 더 빠를 수 있다. (필자도 하나 하나 추가 했다)</p>

<h3 id="quality-profile에-프로젝트-추가">Quality Profile에 프로젝트 추가</h3>

<p>Quality Profile에 프로젝트를 할당 할 수 있다. 단, 그전에 최소한 한 개 이상의 프로젝트는 추가되어 있어야 한다.</p>

<p>checkstyle way에 적용할 프로젝트를 추가하자. Quality Profile 메뉴에서 checkstyle way를 선택하면 아래와 같은 화면이 나타나며 여기서 Change Projects를 클릭한다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201219132252056.png" alt="image-20201219132252056" /></p>

<p>아래 그림과 같이 선택할 수 있는 프로젝트가 나타난다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201217234630962.png" alt="image-20201217234630962" /></p>

<h3 id="룰-확인">룰 확인</h3>

<p>룰 탭으로 돌아오면 Rule을 사용하고 있는 Quality Profiles을 확인할 수 있다. 예를 들어, Line Length 룰을 확인하면 다음과 같이 checkstyle way에서 활성화되어 있으며 어떤 옵션이 적용되어 있는지 표시 된다.</p>

<p><img src="../../assets/images/post/checkstyle-sonarqube-plugin/image-20201217234124824.png" alt="image-20201217234124824" /></p>

<h3 id="코드-분석">코드 분석</h3>

<p>코드 분석은 스캔 &gt; 분석의 과정으로 이루어진다. 메이븐을 이용하여 코드 스캔을 할 수 있으며 아래 명령어를 이용한다.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn clean verify sonar:sonar
</code></pre></div></div>

<p>메이븐 프로젝트에 소나큐브를 연동하는 방법은 <a href="/sonarqube/sonarqube/#소나-스캐너-메이븐">소나큐브 설치 플러그인 포스팅</a>을 다시 한번 확인하자.</p>

<h2 id="마무리">마무리</h2>

<p>지금까지 소나큐브를 이용한 체크스타일 활용법을 알아보았다. 하지만 한가지 빠진 부분이 있다. 바로 우리가 직접 작성한 커스텀 체크가 적용되지 않은 것이다. 이 부분은 다음 포스팅에서 다루도록 하겠다.</p>]]></content><author><name>이건호</name><email>dololgun@gmail.com</email></author><category term="checkstyle" /><summary type="html"><![CDATA[소나큐브란 ?]]></summary></entry></feed>