2025년 5월 1일 목요일

osmc netflix addon

osmc에서 어제까지 잘 보던 netflix가 오늘은 안된다.
내용인즉슨, 인증키가 만료됐다고 한다.
이전 키가 6개월쯤 전에 생성된 거던데 기간이 6개월인가보다.

설정 법이 나온 블로그가 있으니 이걸 보고 하면 된다.
KODI 넷플릭스 애드온 인증키로 로그인하기

위는 윈도우즈 기준인데 리눅스에서도 그리 다르지는 않다.

1. plugin.video.netflix 에 가서
2. For Linux (e.g. Ubuntu) and MacOS 를 열고 
3. NFAuthenticationKey_Linux.zip 를 클릭해서 파일을 다운로드 받는다
(현재는 files.fm이란 곳으로 연결되고 여기서 Download를 눌러서 받는다.
 4. 필요한 파이썬 패키지를 설치하고 실행해서 키 파일과 핀코드를 생성한다.
$ pip install websocket-client pycryptodomex
$ unzip NFAuthenticationKey_Linux_1.1.8.zip
$ python NFAuthenticationKey.py
# 크롬브라우저의 시크릿 모드로 netflix 로그인 페이지가 열린다
# 로그인하고 프로필을 선택한다.
# 창을 닫은건지 아니면 저절로 닫힌건지는 기억이 없다. 
# 터미널에 출력된 4자리 핀코드를 외워둔다.
# 생성된 키 파일을 OSMC로 복사한다.
$ scp NFAuthentication.key <osmc host>:
5. OSMC에서 netflix 플러그인에 진입하면 나오는 로그인 방법중 인증키를 선택한다.
6. 복사해둔 키 파일을 선택하면 핀코드 입력이 뜬다.
7. 핀코드를 입력한다.
8. netflix 계정의 비밀번호를 입력한다.

6개월 뒤에 또 해야할 것 같다.

2025년 3월 14일 금요일

새로 환경을 만들고 qemu 이미지 옮기기

ubuntu 22.04를 쓰고 있었는데 ubuntu 24.04로 옮기면서 새로 깔게 됐다.
이전에는 virt-manager도 깔고 이것 저것 깔았었는데
(나름) 최소한의 패키지로 돌려보도록 하겠다.

우선 기존 환경에서 .qcow2 파일을 복사해 두고 설정 파일을 백업했다.
$ cp ~/vmm/images/vm.qcow2 /backup
$ virsh dumpxml vm > /backup/vm.xml

새로운 환경에서 패키지를 설치한다. (의존 패키지들은 같이 설치되지만) 이게 최소인듯.
$ sudo apt update
$ sudo apt install qemu-system-x86 libvirt-daemon-system libvirt-clients virt-viewer

원래대로 돌려준다. 간단하다
$ mkdir -p ~/vmm/images
$ cp /backup/vm.qcow2 ~/vmm/images
$ virsh create /backup/vm.xml
error: Failed to create domain from kcloud.xml error: Network not found: no network with matching name 'default'

라고 생각했는데 default 네트워크가 없다는 애러가 났다.
예전 설치 글을 봤을 때 네트웨크에 관한 설정은 안써있는데
virt-install을 하면 생기는 건지, 뭔가 다른걸 했는데 기록을 빼먹은지는 잘 모르겠다.
(--network network:default 이런 옵션이 들어있는데 이러면 만들어지나?)

default 네트워크를 추가하는 방법은 간단한 것 같다
$ virsh net-define /usr/share/libvirt/networks/default.xml
$ virsh net-autostart default
$ virsh net-list --all
 Name      State    Autostart   Persistent
--------------------------------------------
 default   inactive   yes         yes
$ sudo virsh net-start default
internal error: Network is already in use by interface virbr0

그런데 시작이 안된다.
virbr0를 내리고, 지우고 다시 시작하면 된다는데 그래도 안된다.
몇 번 하다가 찾아낸 해결법은 . . . 재부팅.

이제 다시 설치하면
$ virsh create /backup/vm.xml
error: Failed to create domain from vm.xml
error: Cannot access storage file '/home/user/vmm/images/vm.qcow2' (as uid:64055, gid:993): 허가 거부

이 부분도 예전 설치 글에 없다. 문제의 uid, pid는 libvirt-qemu의 것인데
우선 이 저장소는 기본저장소가 아니고 개인 홈에 있는거라 발생하는 듯 하다.
아마 예전에는(일반적으로는) 사용자를 저 그룹에 추가하지 않았을까 하는데,
어차피 혼자 쓰는 거라, 이번엔 qemu의 user, group을 사용자로 설정해 봤다. 
$ echo -e '\nuser = "'"$USER"'"\ngroup = "'"$USER"'"' | sudo tee -a /etc/libvirt/qemu.conf
user = "user"
group = "user"

이제 잘 된다.
$ virsh create vm.xml
Domain 'vm' created from vm.xml
$ virsh start vm
$ virt-viewer vm

나머지는 samba를 설치해서 연결해줄뿐. 이건 예전 설치 글 참조

끝났다고 생각했느데, 분명히 아까는 썼는데, 다시 실행하니 없다고 나온다.
$ virsh start vm
error: failed to get domain 'vm'

create가 아니고 define을 했었야 했다.
create는 일시적으로  생성하는 것인가 보다.
$ virsh define /backup/vm.xml


참조
https://www.linuxquestions.org/questions/linux-virtualization-and-cloud-90/virsh-failed-to-start-network-default-4175672429/
https://www.xmodulo.com/network-default-is-not-active.html
https://bbs.archlinux.org/viewtopic.php?id=247377

2024년 11월 24일 일요일

파이썬 상대 경로 임포트

ImportError: attempted relative import with no known parent package
임포트를 상대 경로로 지정하면 편할 것 같아 써보니 이런 에러가 난다.
검색해보면 -m 옵션을 쓰면 된다는데, 정리할겸 테스트를 해봤다. 
다음과 같이 준비를 한다.
$ mkdir -p test/src/foo
$ cd test/src
$ touch foo/{__init__,bar}.py
$ cat << EOF > main.py
from foo import bar

def main():
    print('ok')

if __name__ == '__main__':
    main()
EOF

디렉토리 구조는 이렇게 된다. main.py 이외는 빈 파일이다.
test
└── src
    ├── foo
    │    ├── __init__.py
    │    └── bar.py
    └── main.py

1. 먼저 src/에서 실행해 본다.
$ python main.py     - ok
$ python -m main     - ok
잘 동작한다.
이 번에 하나 위에서 실행해 본다.
$ cd ..
$ python src/main.py # ok
$ python -m src.main # ModuleNotFoundError: No module named 'foo'
foo는 이 디렉토리엔 없다. 하나 아래인 src/에 있다.
앞의 3개는 main.py가 있는 곳에서 임포팅을 시도하는 것 같은데,
마지막 것은 현제 디렉토리에서 하고 있는 듯 하다.

2. 이 번엔 foo 앞에 .을 붙여 본다. (상대 경로 지정)
sed -i 's/foo/.&/' src/main.py

src/에서 실행해 보면,
$ cd src
$ python main.py     # ImportError: attempted relative import with no known parent package
$ python -m main     # ImportError: attempted relative import with no known parent package
문제의 임포트 에러가 나왔다.
하나 위에서 실행해 본다.
$ cd ..
$ python src/main.py # ImportError: attempted relative import with no known parent package
$ python -m src.main # ok
1에서 성공했던 앞의 세 명령은 실패했고, 실패했던 마지막 명령은 성공했다.

3. 하는 김에 src도 붙여 본다.
$ sed -i 's/\.foo/src&/' src/main.py
$ cd src
$ python main.py     # ModuleNotFoundError: No module named 'src'
$ python -m main     # ModuleNotFoundError: No module named 'src'
$ cd ..
$ python src/main.py # ModuleNotFoundError: No module named 'src'
$ python -m src.main # ok
앞의 두 명령은 src가 없으니 그렇다쳐도 3번째 명령도 src가 없다고 한다.

지금까지만 보면 python으로 실행하면 임포트 기준이 대상 파일이 있는 디렉토리고
python -m 으로 실행하면 명령을 실행하는 디렉토리인 것 같다.

4. 하나 더 올라가보면
$ cd ..
$ python -m test.src.main # ModuleNotFoundError: No module named 'src'
$ sed -i 's/src.foo/.foo/' test/src/main.py 
$ python -m test.src.main # ok
test/ 위로 올라오니 src가 없다고 에러가 났다.
src없이 상대 경로로 바꾸니 정상 동작을 한다.
상대 경로의 좋은점이다.

지금까지의 테스트를 보면
실행(?) 파일이 있는 디렉토리를 기준으로 임포트 경로를 잡으면 어디에서 실행시키든 문제가 없다.
상대 경로를 쓸거면 -m 옵션으로 실행하고 실행 디렉토리가 임포트의 기준(top-level)이 된다.

5. 하나를 더 보면
$ cd test
$ mkdir lib
$ touch lib/__init__.py
$ sed -i '1i from .. import lib' src/main.py
$ python -m src.main # ImportError: attempted relative import beyond top-level package
src와 같은 레벨에 있는 lib을 상대경로로 지정하면 top-level을 넘을 수 없다고 나온다.
$ cd ..
$ python -m test.src.main # ok
이 경우 src와 lib를 포함하도록 하나 더 위에서 실행하면 된다.

추가로,
1의 상태에서 다음과 같이 추가한다.
$ cat << EOF > src/foo/bar.py
from .baz import foobar
EOF
$ cat << EOF > src/foo/baz.py
foobar = 'foobar'
EOF
$ python src/main.py
bar.py는 상대 경로를 쓰고 있는데 아무런 문제가 없다.
오히려 .를 없애면 baz를 찾을 수 없다는 에러가 나온다. (foo.baz는 괜찮다)

애초부터 최초의 임포트에러는 top-level까지 올라왔을 때만 발생하는 듯 하다.

2024년 9월 17일 화요일

pi-hole 포트 충돌

osmc에 pihole을 사용 중인데,
apt dist-upgrade한 뒤 (rbp4-mediacenter-osmc 21.1.0-4),  pihole이 동작을 안한다.
확인 해보니 53포트가 충돌나서인데 처음 설치시 했던 설정이 먹히지 않는다.

$ sudo find /etc/systemd | grep connman
/etc/systemd/system/multi-user.target.wants/connman.service

$ cat /etc/systemd/system/multi-user.target.wants/connman.service
[Unit]
Description=Connman connection service
After=dbus.service network-pre.target wpa_supplicant.service
Wants=network.target remote-fs-pre.target
Before=remote-fs-pre.target network.target

[Service]
Type=dbus
BusName=net.connman
EnvironmentFile=-/etc/osmc/prefs.d/connman
Restart=always
RestartSec=5
ExecStart = /usr/bin/start-network
ExecStopPost = /bin/sleep 2
StandardOutput=null

[Install]
WantedBy=multi-user.target

업데이트해서인지 EnvironmentFile이 다르다.

새로운 EnvironmentFile에도 noproxy로 설정을 바꾼다.
 
$ sudo sed -i 's/dnsproxy=yes/dnsproxy=no/' /etc/osmc/prefs.d/connman
$ sudo systemctl restart connman
$ ps -ef | grep connman
root      3787     1  0 11:32 ?        00:00:00 /usr/sbin/connmand -n --nodnsproxy --config=/etc/connman.conf

이제 정상으로 돌아왔다.

2024년 4월 27일 토요일

obsidian + syncthing

obsidian (개인적이고 유연한 글쓰기 앱)을 알게되어 설치해 봤다.
기기 간의 동기화는 유료여서 동기화에는 syncthing을 사용한다.

1. 기기 및 공유 디렉토리
우분투 22.04
  ~/sync/obsidian
안드로이드 폰
  내부저장소/sync/obsidian
* 두 기기의 obsidian 디렉토리를 동기화 시킨다.
* wi-fi로 연결된 같은 네트워크

2. ubuntu 설정
  2.1. obsidian
    2.1.1. 설치
$ wget https://github.com/obsidianmd/obsidian-releases/releases/download/v1.5.12/obsidian_1.5.12_amd64.deb
$ sudo dpkg -i obsidian_1.5.12_amd64.deb
$ mkdir ~/sync/obsidian
$ obsidian

     2.1.2. 보관소 생성
English -> 한국어
새 보관소 생성 >
  위치: 탐색 > 홈 > sync > 열기
  보관소 이름: obsidian
생성

  2.2. syncthing
* 우분투 설치 가이드에 따라 apt로 설치하고 systemd 서비스로 등록해도 된다.
* 여기서는 도커 설치 가이드에 따라 도커로 설치. (추천에 따라 host 네트워크 사용)
  2.2.1 설치
$ cd ~/sync
$ mkdir -p ./syncthing/obsidian
$ cat docker-compose.yml
services:
  syncthing:
    image: syncthing/syncthing:1.27.6
    container_name: syncthing
    hostname: syncthing
    environment:
      - PUID=1000  # id -u 값 설정
      - PGID=1000  # id -g 값 설정 
volumes: - ./syncthing:/var/syncthing - ./obsidian:/var/syncthing/obsidian network_mode: host restart: unless-stopped $ docker compose up -d syncthing

  2.2.2 설정
브라우저로 http://localhost:8384/에 연결
GUI 인증 > 설정 > GUI > GUI 인증 사용자, GUI 인증 비밀번호 입력 > 저장

3. 안드로이드 폰 설정
  3.1. obsidian
    3.1.1. 설치
      Play 스토어 > 검색 > obsidian > 설치

     3.1.2. 보관소 생성
Create new vault >
  Vault location: Choose > 내부저장소 > sync(생성) > 선택
  Vault name: obsidian
Create 탐색기?(왼쪽 위) > 설정(톱니바쿼) > Options > General > Language > English -> 한국어 > Relaunch

  3.2. syncthing
    3.2.1. 설치
      Play 스토어 > 검색 > syncthing > 설치

4. 동기화 설정
1) 우분투 > http://localhost:8384/ > 동작 > 기기 식별자 보기 > 큐알코드 표시 상태
2) 폰 > syncthing > 기기 > + > 큐알코드 > 우분투의 큐알코드 촬영, 이름: 우분투 > 확인 (체크마크)
3) 우분투 > http://localhost:8384/ > 큐알코드 종료 > 새 기기 > +기기 추가 > 저장
4) 폰 > syncthing > 폴더 > + >
  폴더명: obsidian,
  디렉토리: 내부저장소/sync/obsidian > 선택
  우분투: 활성화
확인 (체크마크)
5) 우분투 > http://localhost:8384/ > 새 폴더 > v 추가 > 폴더명: obsidian, 폴더 경로: ~/obsidian > 저장

5. 동기화 확인
우분투나 폰의 obsidian 에서 파일을 만들거나 수정하면 15초 ~ 20초 정도 후에 상대 기기에서 반영 확인.
폰의 Wi-fi를 끊고 모바일 네트워크로도 동기화 되는 것 확인.

6. 감상
메모를 보는데 네트워크를 사용하지 않는다니 좋다.
폰에서는 syncthing를 꺼뒀다가(☰ > X 나가기) 필요할 때만 켜서 동기화하면 될 듯 하다

우분투에 설치한 obsidian에는 Vim 키 설정(옵션 > 편집기 > Vim 키 설정)이라는게 있다.
vimwiki는 잘 쓰고 있는데 vimwiki와 연동하거나 외부에서 메모하는데 써봐야겠다.

우분투의 syncthing를 docker로 설치하니 설정이 깔끔하지 않은 듯 하다.

syncthing으로 공유 폴더를 설정시 서로 설정해서 그런지 같은 설정이 2개가 되버렸다.
같은 것이니 하나를 지우면 되긴 하는데 설정 방법이 틀린걸까?

2023년 10월 11일 수요일

리모트 서버의 도커 앱 디버깅

로칼의 vscode 로 리모트 서버(ubuntu)에서 돌아가는 파이썬 도커 앱을 디버깅하는 설정


1. 리모트 서버에 도커 컨테이너가 떠 있음

(리모트에 연결 안 된 상태)

2. 로칼의 vscode 시작
왼쪽 아래의 [><] 클릭 (Open a remote window)
Connect to Host...
설정된 호스트 선택 [또는 새 SSH 호스트 추가... 선택 및 설정]

(리모트에 연결 된 상태)

3. [리모트에 Dev Containers 플러그인이 설치되지 않은 경우 설치]
명령 파레트 > Dev Containers: Attach to running container >
연결할 컨테이너 이름 선택 [처음 연결하는 경우 서버 설치로 시간 걸림]

(리모트의 도커에 연결 된 상태)

4. [컨테이너에 Python 플러그인이 설치되지 않은 경우 설치]
메뉴 > File > Open Folder... > 프로젝트 경로 선택
명령 파레트 > Python: Select Interpreter >
앱에서 사용하는 파이썬 선택


5. 디버깅 [luanch 또는 attach]

2023년 8월 26일 토요일

vite + react + typescript

셋업
# pre-commit 과 yarn 설치
pip install pre-commit
npm i -g yarn

# 프로젝트 생성
yarn create vite 프로젝트명 --template react-swc-ts
cd 프로젝트명
git init
git add .
git commit -m 'initial commit'

# pre-commit 및 패키지 설치
pre-commit install
yarn

# 실행
yarn dev

.pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v2.3.0
    hooks:
      - id: end-of-file-fixer
      - id: trailing-whitespace
        args: [--markdown-linebreak-ext=md]
  - repo: https://github.com/pre-commit/mirrors-prettier
    rev: v3.0.2                                        
    hooks:
      - id: prettier
  - repo: https://github.com/pre-commit/mirrors-eslint
    rev: v8.47.0
    hooks:
      - id: eslint
        files: \.[jt]sx?$
        types: [file]

vite.config.ts
import { defineConfig, loadEnv } from 'vite';
import react from '@vitejs/plugin-react-swc';

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
  //const env = {...loadEnv(mode, '..', ''), ...loadEnv(mode, '.', '')};
  const env = loadEnv(mode, '.', '');
  return {
    plugins: [react()],
    server: {
      port: parseInt(env.PORT),
      open: true, // 시작시 브라우저 띄움
    },
  };
});

type Props = {
  setCount: (value: number) => void; // 함수
};

마운트/언마운트
  useEffect(() => {
    console.log('마운트');
    return () => {
      console.log('언마운트');
    };
  }, []);

마운트/업데이트
  useEffect(() => {
    console.log('마운트/업데이트');
  }); // 또는 [변수 리스트]

업데이트만
  const didMountRef = useRef(false);
  useEffect(() => {
    if (!didMountRef.current) { 
      didMountRef.current = true;
      return;
    }

    console.log('업데이트');
  }); // 또는 [변수 리스트]

확장 프로그램 > React Developer Tools > Components > 톱니(View Settings) > General > [v] Highlight updates when components render.

2023년 7월 23일 일요일

docker registry proxy 테스트

registry kvm: 192.168.122.99
proxy kvm: 192.168.122.98
client kvm: 192.168.122.97

    1. registry 용 vm 생성
host $ sudo virt-install --name registry --os-variant ubuntu22.04 --vcpus 1 --ram 2048 \
--network network:default --cdrom /path/to/ubuntu-22.04.1-live-server-amd64.iso \
--disk size=10

    2. (공통) 도커 설치
host $ virsh start registry
host $ ssh registry
registry $ echo "$USER ALL=(ALL:ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers
registry $ sudo apt update 
registry $ sudo apt install vim iptables
registry $ wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/containerd.io_1.6.21-1_amd64.deb
registry $ wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-buildx-plugin_0.11.1-1~ubuntu.22.04~jammy_amd64.deb
registry $ wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-ce-cli_24.0.4-1~ubuntu.22.04~jammy_amd64.deb
registry $ wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-ce_24.0.4-1~ubuntu.22.04~jammy_amd64.deb
registry $ wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-compose-plugin_2.19.1-1~ubuntu.22.04~jammy_amd64.deb
registry $ sudo dpkg -i *.deb
registry $ rm -rf *
registry $ sudo usermod -aG docker $USER
registry $ sudo shutdown 0

    3. registry vm 을 proxy vm(과 client vm)으로 복사
host $ virt-clone --original registry --name proxy --file /var/lib/libvirt/images/proxy.qcow2
host $ virsh dumpxml proxy | grep '<mac'
      <mac address='52:54:00:ce:18:74'/>
host $ virsh net-edit default
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.100' end='192.168.122.254'/>
      <host mac='52:54:00:a9:5f:97' name='registry' ip='192.168.122.99'/>
      <host mac='52:54:00:ce:18:74' name='proxy' ip='192.168.122.98'/>
      <host mac='52:54:00:22:dd:40' name='client' ip='192.168.122.97'/>
</dhcp> </ip> </network$ virsh net-destroy default host $ virsh net-start default

    4. proxy vm(과 client vm)의 hostname 변경
host $ virsh start proxy
host $ ssh proxy
proxy $ sudo hostnamectl set-hostname proxy
proxy $ sudo sed -i 's/registry/proxy/' /etc/hosts
proxy $ sudo reboot

    5. registry 설정
    5.1. 사설 repository 사용 설정
host $ ssh registry
registry $ sudo vi /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.122.99:5000"]
}
registry $ sudo systemctl restart docker

    5.2. registry 실행
registry $ mkdir -p workspace/registry
registry $ cd workspace
registry $ vi docker-compose.yml
version: "3"
services:
  registry:
    image: registry:2.8.2
    container_name: registry
    volumes:
      - ./registry:/var/lib/registry
    ports:
      - 5000:5000
    restart: always
registry $ docker compose up -d

    5.3. 테스트용 도커 이미지 생성
registry $ mkdir ~/test
registry $ cd ~/test
registry $ vi Dockerfile
FROM alpine
CMD echo 'hello registry 1.0'
registry $ docker build -t 192.168.122.99:5000/test/hello:1.0 .
registry $ docker push 192.168.122.99:5000/test/hello:1.0
registry $ curl http://192.168.122.99:5000/v2/_catalog
{"repositories":["test/hello"]}
registry $ curl http://192.168.122.99:5000/v2/test/hello/tags/list
{"name":"test/hello","tags":["1.0"]}

    6. proxy 설정
host $ ssh proxy
proxy $ mkdir -p workspace/registry
proxy $ cd workspace
proxy $ vi docker-compose.yml
version: "3"
services:
  proxy:
    image: registry:2.8.2
    container_name: proxy
    environment:
      - REGISTRY_PROXY_REMOTEURL="http://192.168.122.99:5000"
    volumes:
      - ./registry:/var/lib/registry
    ports:
      - 5000:5000
    restart: always
proxy $ docker compose up -d

    7. client 설정
host $ ssh client
client $ sudo vi /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.122.98:5000"]
}
client $ sudo systemctl restart docker
client $ curl http://192.168.122.98:5000/v2/_catalog
{"repositories":[]}
client $ docker run --rm -it 192.168.122.98:5000/test/hello:1.0
hello registry 1.0
client $ curl http://192.168.122.98:5000/v2/_catalog
{"repositories":["test/hello"]}

참고:
https://waspro.tistory.com/532
https://bobcares.com/blog/docker-registry-mirroring/
https://docs.docker.com/registry/spec/api/

2023년 7월 1일 토요일

우분투 업데이트 후 크롬 크래시

우분투 업데이트 후 크롬이 시작하질 않는다.
$ /usr/bin/google-chrome-stable
[5836:5836:0702/120130.931454:FATAL:credentials.cc(127)] Check failed: . : 허가 거부 (13)
추적/중단점 함정 (코어 덤프됨)

찾아보니 새로운 nvidia 커널을 사용하면 발생한다는 것으로 보인다.
https://stackoverflow.com/a/76299196
https://bugs.launchpad.net/ubuntu/+source/linux-meta-nvidia-5.19/+bug/2017980

현재 커널은 nvidia 용인 것으로 보인다.
$ uname -sr
Linux 5.19.0-1010-nvidia-lowlatency

우선 확인을 위해 다른 커널을 사용해 보기로 한다.
https://askubuntu.com/a/16049

현재 커널은 3가지가 설치되어 있다.
$ cat /boot/grub/grub.cfg  | egrep 'menuentry |submenu ' | awk -F"'" '{print $1 $2}'
menuentry Ubuntu
submenu Advanced options for Ubuntu
	menuentry Ubuntu, with Linux 5.19.0-1010-nvidia-lowlatency
	menuentry Ubuntu, with Linux 5.19.0-1010-nvidia-lowlatency (recovery mode)
	menuentry Ubuntu, with Linux 5.19.0-46-generic
	menuentry Ubuntu, with Linux 5.19.0-46-generic (recovery mode)
	menuentry Ubuntu, with Linux 5.15.0-60-generic
	menuentry Ubuntu, with Linux 5.15.0-60-generic (recovery mode)
menuentry UEFI Firmware Settings

아마도 부팅시 grub 메뉴가 안보이도록 되어 있을텐데,
재부팅 > (bios가 끝나고) grub 로딩중일(이라고 생각될) 때 ESC 를 한 번만 누른다.

위에서 확인한 커널을 사용한다.
Advanced > 'Ubuntu, with Linux 5.19.0-46-generic'

부팅후 크롬을 실행하니 문제없이 뜬다.

다음과 같은 해결법이 있겠다.
  1. 크롬 실행시 --no-sandbox 옵션 추가
    동작은 잘 하는데 보안상 문제가 있다고하니 안쓰는게 나을 듯

  2. 문제없는 nvidia 용 커널 사용
    수정 버전이 나올 때까지 기다린다.

  3. generic 커널을 사용하도록 grub 메뉴를 수정
  4. $ sudo sed -i '/^GRUB_DEFAULT=/s/=.*/="1>2"/' /etc/default/grub
    $ sudo update-grub
    $ sudo reboot

  5. nvidia 용 커널 삭제
  6. $ dpkg -l | grep 'ii  linux-image'
    $ sudo apt remove linux-image-5.19.0-1010-nvidia-lowlatency커
우선 nvidia 커널쪽 문제인듯 하니 4번으로 해결했다.
크롬이 수정할 수도 있을텐데 그러면 다시 설치하면 되겠지.
 

참고
  • https://stackoverflow.com/a/76299196
  • https://bugs.launchpad.net/ubuntu/+source/linux-meta-nvidia-5.19/+bug/2017980
  • https://askubuntu.com/a/16049
  • https://linux.how2shout.com/how-to-change-default-kernel-in-ubuntu-22-04-20-04-lts/

2023년 6월 26일 월요일

씽크패드, 우분투 그리고 배터리

전원 관리

$ sudo add-apt-repository ppa:linrunner/tlp
$ sudo apt update
$ sudo apt install tlp tlp-rdw

커널 버전이 5.17 보다 작고 thinkpad 이면 추가 패키지 설치
ThinkPads only: External Kernel Modules


충전 임계값 

위도우즈 쪽의 프로그램에서는 기본 값이 75, 80 이었기에 같은 값으로 설정했다.

$ echo 75 | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold
$ echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold
# 충전 케이블을 뽑고 75% 이하로 떨어지면 다시 꼽는다.


2023년 6월 15일 목요일

MS 윈도우에서 x-server 사용하기

MS 윈도우에서 x-server  툴들이 몇가지 있는데,
WSL2 에서 ubuntu 를  돌리면 x-server 를 사용할 수 있다는걸 처음 알았다.
ubuntu니까 당연할 수도 있겠지만 WSL2 라서 GUI 기능은 없다고 생각했다.

ubuntu 에 깔려 있는 x 와 관련 있어 보이는 패키지는 다음과 같다.
x11-common
x11-utils
xauth
xdg-user-dirs
xkb-data
ubuntu 쪽에서 뭔가 하는것 같지는 않다.

리모트 서버에서 eog 등을 띄우고 윈도우의 작업관리자를 보면 다음과 같은 그룹이 생긴다.
('* 숫자' 는 같은 이름의 프로세스 개수이다.)

Linux용 Windows 하위 시스템(18)
    COM Surrogate * 2
    Remote Desktop
    Windows Subsystem for Linux * 10
    Windows Subsystem for Linux Service
    콘솔 창 호스트 * 4

눈에 띄는게 Remote Desktop(msrdc.exe) 로 WSL 설치 디렉토리에 있다.

msrdc 는 mstsc 의 후속작(?)으로 Azure Virtual Desktop 의 rdp 클라이언트라고 한다.
ssh 연결할 때 -X 옵션을 주거나 ~/.ssh/config 에서 ForwardX11 yes 를 추가하면
리모트의 x 프로그램을 쓸 수 있다.

이제 다른 x-server 툴들은 지워도 될 것 같다.



2023년 6월 11일 일요일

osmc 에 pihole(광고차단) 설치하기

요즘 웹사이트의 광고 내용이 너무 심하다는 생각이 들어 광고 차단 프로그램을 설치했다.


환경

공유기: ipTIME A8004ITL

라즈베리파이 4: OSMC 2023.06-1

광고 차단 프로그램: Pi-Hole 


OSMC 설치

Disney Plus + OSMC + 라즈베리파이 4 에서 OSMC 설치부분만 따라한다. 이미지는 항상 최신.


도커 설치

찾아보니 pihole 의 도커 이미지가 있길래 도커 이미지를 사용한다.
도커가 아니고 직접 설치하려면 참고의 사이트를 보고 한다.

도커는 패키지로 설치한다. (같은 페이지에 다른 방법도 있으니 참고한다.)
https://docs.docker.com/engine/install/debian/#install-from-a-package

각 패키지 별로 최신 버전을 다운 받아 설치한다.

$ wget https://download.docker.com/linux/debian/dists/bullseye/pool/stable/armhf/containerd.io_1.6.21-1_armhf.deb
$ wget https://download.docker.com/linux/debian/dists/bullseye/pool/stable/armhf/docker-ce_24.0.2-1~debian.11~bullseye_armhf.deb
$ wget https://download.docker.com/linux/debian/dists/bullseye/pool/stable/armhf/docker-ce-cli_24.0.2-1~debian.11~bullseye_armhf.deb
$ wget https://download.docker.com/linux/debian/dists/bullseye/pool/stable/armhf/docker-compose-plugin_2.18.1-1~debian.11~bullseye_armhf.deb
$ sudo dpkg -i *.deb
$ sudo usermod -aG docker $USER
# 재로그인


Pi-hole 설치

설치는 https://hub.docker.com/r/pihole/pihole 를 따라 docker-compose.yml 파일만 생성하면 된다.

필요 없어 보이는 부분은 삭제하고 포트 등은 수정했다. 윈래 내용은 위 페이지를 참고한다.

$ mkdir ~/pihole
$ cd ~/pihole
$ cat << EOF > docker-compose.yml
version: "3"
services:
  pihole:
    container_name: pihole
    image: pihole/pihole
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
    environment:
      TZ: "Asia/Seoul"
# WEBPASSWORD: 'set a secure password here or it will be random' volumes: - "./etc/pihole:/etc/pihole"
- "./etc/dnsmasq.d:/etc/dnsmasq.d"
restart: unless-stopped EOF $ docker compose up -d


문제 해결 1.

53 번 포트가 이미 사용 중이라고 나온다.
확인해보니 connman 서비스가 사용 중이다.

$ sudo netstat -ntpl | grep 53

connman 은 네트워크 연결을 관리해주는 서비스라 없애긴 그렇고 dns 프록시 기능만 끄도록 한다.

$ sudo sed -i 's/dnsproxy=yes/dnsproxy=no/' /etc/connman.prefs
$ sudo systemctl restart connman
$ docker restart pihole


일단 Pi-Hole 의 dns 동작확인
OSMC 를 대상으로 다음과 같이 표시되면 문제 없다. ({} 부분은 각자에 맞게 치환)

$ nslookup www.google.com {OSMC IP 주소}
Server:		{OSMC IP 주소}
Address:	{OSMC IP 주소}#53

Non-authoritative answer:
Name:	www.google.com
Address: 172.217.161.228
Name:	www.google.com
Address: 2404:6800:400a:80b::2004

Pi-Hole 웹 로그인

http://{OSMC IP 주소}:8080/admin

암호 확인

$ docker compose logs pihole | grep
# 암호를 잊어버렸을 때는 docker-compose.yml 에 WEBPASSWORD 를 설정
# 또는 새로 생성
$ docker compose exec pihole pihole -a -p


여기부턴 잘못 설정하면 집안 전체의 인터넷이 안될 수도 있다.
바꾸기 전의 값을 잘 기록해 뒀다가 문제가 생기면 되돌리던가,
강제 리셋 시키는 방법을 알아 두는게 좋다.


Pi-Hole 설정

기본적으로는 아무 것도 안해도 동작한다.

DNS 서버가 기본으로 google 로 되어 있는데 이걸 KT 로 바꿔 줬다.
http://{OSMC IP 주소}:8080/admin/settings.php?tab=dns

Google 쪽 체크는 없애고 커스텀 쪽에 값을 추가했다. KT 의 주소는 공유기에서 복사.

Custom 1 (IPv4)    Custom 1 (IPv4)
[v]                [v]
[168.126.63.1]     [168.126.63.2]


공유기의 DNS 설정 변경

공유기 관리 페이지 > 고급 설정 > 네트워크 관리 > 인터넷 설정 정보 > 다음 설정 > 설정 버튼 클릭
[v] DNS 주소 수동 입력 에 체크

기본 DNS 주소	[].[].[].[]  <= {OSMC IP 주소}
보조 DNS 주소	[].[].[].[]  <= 비워둔다


참고로 OSMC 는 서버로 동작하기 때문에 늘 IP 가 같아야 한다.
고정 IP 로 설정하거나 공유기의 DHCP 서버 설정에서 수동 주소를 설정한다.


블랙리스트 추가

https://yorublog.tistory.com/16 에서 Tip 광고가 나오나요? 부분을 따라 추가한다.

광고를 오른 클릭 > 링크 주소 복사 > https://이 사이 부분만 복사/...

http://{OSMC IP 주소}:8080/admin/groups-domains.php 에서 다음 부분에 복사해 넣고 Add to Blacklist 버튼 추가

Domain:
[aaa.bbb.ccc.com]


문제 해결 2.

이게 문제인지는 잘 모르겠다. 블랙리스트를 추가해도 광고가 떴다.
어디선가 설정하고 몇 분 있어야 동작한다고 했던 것 같긴한데 다음 동작을 했다.

http://192.168.192.123:8081/admin/gravity.php 에서 Update 클릭

시간이 지나서 된 건지 블록리스트를 업데이트해서 된 건지는 확실치 않다. 

PS. 몇 개 더 해보니 시간이 걸리는게 맞는 것 같다.


보조 DNS 설정 추가

OSMC 는 항상 켜두기는 하는데 혹시 동작이 안되 집안의 인터넷이 안되는
사태가 발생하면 안될 것 같아 보조 DNS 는 원래 값으로 설정해 뒀다.

공유기 관리 페이지 > 고급 설정 > 네트워크 관리 > 인터넷 설정 정보 > 다음 설정 > 설정 버튼 클릭
[v] DNS 주소 수동 입력 에 체크

기본 DNS 주소	[].[].[].[]           <= {OSMC IP 주소}
보조 DNS 주소	[168].[126].[63].[1]  <= 기존의 기본 DNS 주소


참고

  • https://yorublog.tistory.com/16
  • https://github.com/pi-hole/pi-hole/#one-step-automated-install
  • https://docs.docker.com/engine/install/debian/#install-from-a-package
  • https://www.techkhoji.com/pi-hole-blocking-not-working-fix/

2023년 5월 27일 토요일

vim 에서 JSX.IntrinsicElements 에러 수정

vim 8 + coc-tsserver 으로 .tsx 파일을 열었는데 다음과 같은 에러가 보인다. 

 Property 'div' does not exist on type 'JSX.IntrinsicElements'. (tsserver 2339)

검색해보면 주로 컴포넌트 이름을 소문자로 잘못 써서(<Hello> 를 <hello> 로 사용) 나오는 것 같다. 
하지만 이 경우는 div 로 기본 html 태그이니 에러가 나오는 것은 이상하다.

JSX.IntrinsicElements 이란 를 보고 설치된 모듈을 검색해 봐도 잘 들어있다.
$ grep 'interface IntrinsicElements {' -wrn  node_modules/
node_modules/@types/react/ts5.0/index.d.ts:3177:        interface IntrinsicElements {
node_modules/@types/react/index.d.ts:3209:        interface IntrinsicElements {
$ sed -n '/interface IntrinsicElements {/,/\<div\>/p' node_modules/@types/react/index.d.ts
        interface IntrinsicElements {
    . . .
            div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;

찾다보니 coc-tsserver  에 tsserver.tsdk 와 tsserver.useLocalTsdk 설정이 있는 것을 알았다.
tsserver.tsdk 는 IntelliSense 사용을 위해 lib*.d.ts 를 찾을 수 있는 TypeScript 설치 경로를 지정하고, tsserver.useLocalTsdk 는 workspace (node_modules 아래)에서 찾는다.

다음과 같이 vim 에서 coc 설정 파일을 열고 workspace 의 모듈을 사용하도록 설정을 추가한다.
:CocConfig
{
  "tsserver.useLocalTsdk": true
}

참고로 vim 시작시 coc 가 시작하지 않게 하려면 .vimrc 에 다음을 추가한다.
let g:coc_start_at_startup = v:false
도중에 시작은
:CocStart

2023년 5월 13일 토요일

OSMC 에서 쿠팡플레이 실행

쿠팡플레이를 써볼 수 있게 되서 설정해 봤다.

  1. osmc 설치로 kodi 설치까지는 된 거고
  2. 애드온 설치 를 따라 repository.nightrain_v19_public.zip 를 설치
    (osmc는 kodi 와 스킨이 달라 다르게 보이지만 내용은 같아서 따라갈 수 있다.)
    (이 파일은 오래됐지만 링크만 제공하고 링크는 최신이라 문제 없다.)
    서비스 설치할 때 Coupang Play MINI 만 설치했다.
  3. 로그인 정보 입력 및 프로필 선택.
    (프로필은 만든 목록이 보이지 않고 프로필1, 프로필2 등으로 보인다.)

로그인하고 목록 조회 등은 잘 나오는데 막상 재생하면 에러가 났다.
osmc 를 새로 설치한거라 drm 라이브러리가 설치 안되서 그럴것 같았다.
다른 플러그인에서는 drm 라이브러리 설치 화면이 연동되었는데 그렇게는 안되어 있는 모양이다.
(플러그인이 있는 것만으로도 고맙긴하다.)

widevine-arm-broken 에서 Update Widevine (Non-SlyGuy Users) 를 보고 설치한다.
  • 설정 > 애드온 탐색기 > 저장소에서 설치 > 모든 저장소 > 프로그램 애드온 >
    InputStream Helper
  • 설정 > 전문가 > Widevine CDM 라이브러리를 (다시) 설치
  • 모두 예
  • 재부팅
위의 라이브러리 설치 전에 어디선가 보고 다음 패키지를 설채했었는데
지워도 동작하는걸 보면 설치할 필요는 없을지도 모르겠다.
혹시라도 Widevine 라이브러리 설치시 에러가 나면 다음을 설치하면 될 것 같다.

$ sudo apt remove python3-pycryptodome python3-pip

참고:
https://hoing.io/archives/11171
https://www.matthuisman.nz/2021/05/widevine-arm-broken.html

hdl 팁

  • 1 비트를 16 비트로 확장

Mux16(a=false, b=true, sel=bit, out=out);

  • 1 더하기
Add(a=a, b[0]=true, b[1..15]=false, out=out);
  • sub 버스의 일부만 사용하고 싶은 경우, 출력에서 미리 빼둔다.

 Mux16(a=a, b=b, sel=no, out=out, out[0..7]=sub0);

2023년 5월 2일 화요일

ubuntu 업데이트 후 trackpoint 동작 안함

Thinkpad T15 에서 ubuntu 22.04 사용 중인데 소프트웨어 업데이트 후
트렉포인트가 동작하지 않는다. 

다음과 같이 펌웨어 업데이트 후 동작하게 되었다.

$ fwupdmgr refresh
$ fwupdmgr update
    . . .
Upgrade Embedded Controller from 0.1.14 to 0.1.15?
. . . Upgrade Intel Management Engine from 225.60.1807 to 225.67.2046?
. . . Upgrade Prometheus from 10.01.3273255 to 10.01.3478575?
. . .
Upgrade System Firmware from 0.1.24 to 0.1.28?
. . .
An update requires a reboot to complete. Restart now? [y|N]: 


LVFS 를 지원하는 장치에 대해서는 제조사에 관계없이 같은 방식으로 업데이트가 가능하다고 함.

참고:
* https://www.cyberciti.biz/faq/thinkpad-update-firmware-on-linux-x1-extreme-p1-gen2/


이건 안해봤는데 트랙포인트 감도 조절하는 방법이라고 함.
ubuntu 20.04 의 방법이 22.04 에서도 유효할 듯

* https://silvae86.github.io/2019/05/17/tuning-ibm-lenovo-trackpoint/

2023년 4월 16일 일요일

명령어 결과를 한 줄씩 클릭보드에 복사

command |
while read line; do echo "$line" | xclip -selection clipboard; read -u1 -p "$line"; done

command 의 실행 결과를
while loop 에서 한 줄씩
    클립보드에 복사하고
    표시
    엔터를 누르면 다음 줄에 대해 반복

설명이 필요한 부분은 두 번째 read 로
-u 옵션이 없으면 키보드가 아니고 파이프에서 입력을 읽어
한줄씩 처리가 안된다.

2023년 3월 24일 금요일

터미널에서 프로그래스바 표시하기

bash의 경우: pv

설치: sudo apt install pv 또는 conda install pv

사용 예:

docker save image | gzip | pv | ssh remote docker load


python의 경우: tqdm

설치: pip install tqdm

사용 예:

>>> import time
>>> from tqdm import tqdm
>>> for i in tqdm(range(101), total=100):
...     time.sleep(0.1)


2023년 3월 13일 월요일

도커로 webOS 빌드

webOS OSE 를 빌드하려는데 빌드를 위한 패키지는 설치하고 싶지 않아서 docker 로 빌드했다.

https://github.com/shallweeee/build-webos

600MB 짜리 (압축풀면 2.2GB) 이미지 하나 빌드하는데 하루 종일 걸린 것 같다.
에러가 나서 여러 번 끊기긴 했는데, 다시하면 문제 없이 실행되는게
아무래도 다 메모리 사용량이 커서였던 것 같다.
동시 실행 갯수 옵션을 줄여가며 다시 돌리다 보니 완성은 됐다.
(너무 줄여서 더 걸린 것 같기도 하다)

디스크 사용량은 몇 가지 큰 디렉토리만 보면 다음과 같다. (너무 크다.)

230G ./BUILD
30G  ./downloads
12G  ./sstate-cache

이미지 쓰기 에 따라 SD 카드에 이미지를 쓴다.

부팅 중의 화면이 다른 라즈베리파이 배포판이랑 좀 다르긴 한데 어찌됐든 화면이 뜨긴 했다.


그. 런. 데... 뭐가 너무 없다. (그냥 개발 환경인듯.)

osmc와 비교하면 이미지 크기는 굉장히 큰데 할 수 있는게 거의 없다.
(LG TV 가 아니라서인지) TV 리모컨도 안먹고,  설정도 언어와 Wifi 정도(?) 밖에 없다.
마우스나 키보드 둘 다 필요하고 (어느 하나만으로는 조작을 못하겠다.)
음성 명령은 되는듯 보이나 대응 리모컨이 없어서 못해봤다.
그나마 Youtube 앱을 전체화면 모드로 돌리는 것은 괜찮은듯 하다.

디바이스에 접속은 ares cli 를 쓰면 되는것 같았는데,
그냥 ssh 만으로도 접속은 잘 됐다. 사용자는 root 고 암호는 없다.

혹시나 해서 nginx 로 sstate-cache 서버를 만들어서 새로 빌드를 해봤는데, 이건 광속이다.
10734 개의 태스크 중 마지막 300 여개 정도 빼고는 거의 다운로드만 일어난 것같이 빨리 처리됐다.
나머지는 컴파일을 하기도 해서 시간이 좀 걸렸다.

다른 서버에 nginx 를 설치하고 sstate-cache 를 위한 설정을 추가 및 restart

# /etc/nginx/nginx.conf
http {
    . . .
    server {
    listen 34567;
    server_name sstate.webos.ose;
    root /yocto/webOS/sstate-cache;
    autoindex on;
  }
}

sstate-cache를 서버에 복사

$ scp -r sstate-cache <서버이름>:<포트>/<sstate-cache 까지의 경로>

webOS 빌드 설정에 sstate-cache 설정 추가 및 빌드

$ ./scripts/docksh ./mcf -b8 -p8 --sstatemirror http://192.168.0.12:34567 raspberrypi4-64
$ ./scripts/docksh bitbake webos-image

2023년 1월 24일 화요일

qemu + 윈도우10 guest 설치

환경

Host: Ubuntu 22.04
Guest: Windows 10


1. 가상 머신 생성
cpu 와 메모리는 사용하는 PC 성능에 맞게 설정한다.

$ sudo apt update
$ sudo apt install qemu-system-x86 virtinst virt-viewer
$ virt-install --name=win10 --cpu model=host-passthrough \
--vcpus sockets=1,dies=1,cores=2,threads=2 --ram=8192 --hvm --network network:default \
--disk path=/path/to/win10.qcow2,size=32 --cdrom=/path/to/Windows.iso --osinfo name=win10

설명
--name=win10                                # 가상머신 이름
--cpu model=host-passthrough                # 호스트 CPU 구성 복사. 
--vcpus sockets=1,dies=1,cores=2,threads=2  # cpu 4개 할당. 윈도우에선 cores 와 threads 만
                                            # 사용가능한 듯
--ram=8192                                  # 메모리 8GB 할당
--hvm                                       # 풀가상화
--network network:default                   # 네트워크는 기본 사용
--disk path=/path/to/win10.qcow2,size=32    # 32GB 크기의 win10.qcow2 디스크 이미지 할당
--cdrom=/path/to/Windows.iso                # 윈도우10 설치 이미지 사용
--osinfo name=win10                         # 게스트 OS는 윈도우10

2. 윈도우10 설치

3. 윈도우 확장팩 설치
SPICE Guest Tools 를 설치한다. (클립보드 공유, 그래픽 드라이버 등)

4. 호스트와 공유 폴더 설정
몇가지 방법이 있는데 제일 간단(?)하고 안정적인 삼바를 통한 공유로 했다.
공유할 필요가 없거나 다른 방법이 있으면 안해도 된다.
가상머신을 사용할 때마다 초기화할거라 (6. 스냅샷 사용 참조) 데이터 보존용으로 설정했다. 

4.1 호스트의 삼바 서버
smb.conf 파일에서 Share Definitions 줄을 기준으로 아래를 삭제하고 다음 공유 설정을 추가했다.
hosts deny 는 가상머신만 허용하고 있는데 다른 용도로도 사용한다면 안쓰는게 좋다.
사용자는 사용하는 계정으로 바꿔준다.

$ sudo apt install samba
$ sudo vi /etc/samba/smb.conf
   . . .
#   hosts deny = all except 192.168.122.
#======================= Share Definitions =======================
[host]
   path = /home/사용자/vmm/share
   valid users = 사용자
   guest ok = no
   read only = no
   browseable = no
   create mask = 0700
   security mask = 0700
directory mask = 0700 $ sudo smbpasswd -a 사용자
$ sudo service smbd restart

윈도우 탐색기에서 네트워크 드라이브로 \\192.168.122.1\host 를 등록한다.

4.2 qemu 의 built-in 삼바 서버
https://www.ashbysoft.com/posts/libvirt-qemu-samba/ 를 따라 해봤는데 실패했다.

4.3 Remmina
원격데스크탑으로 연결하는 방식으로 파일 공유 자체는 굉장히 쉽다.
다른 PC에 연결할 때는 괜찮은데, 같은 PC 의 가상환경에 연결할 때는 virt-viewer 가 더 좋은 것 같다.

$ sudo apt install remmina
$ remmina

4.4 Cockpit
https://dausruddin.com/how-to-enable-clipboard-and-folder-sharing-in-qemu-kvm-on-windows-guest/#Solution_Folder_sharing
Cockpit Web-UI 를 통해서 접근해야만 동작하는것 같다.
그리고 어차피 spice-webdavd 를 설치하고 채널을 추가하면 virt-viewer 만으로도 공유는 가능하다.

4.5 sshfs
(몇 개월 전에 해본 기억으로) 리눅스에서는 쉬운데 윈도우에서는 설치/설정이 좀 까다롭고 동작이 깔끔하지 않았다

4.6 Virtio-FS
시도해보지는 않았다.

5. 사용

$ virsh start win10 # 가상머신 win10 기동
$ virt-viewer win10 & # 가상머신 win10 에 연결
$ virsh edit win10 # 가상머신 설정 변경
# cdrom 을 검색해서 <source file='...'/> 줄을 삭제하면 재부팅시 cdrom 이 빈상태가 된다.

GUI 로 조작하려면 virt-manager 를 설치한다.
$ sudo apt install virt-manager
$ virt-manager

6. 스냅샷 사용
그냥, 가상머신을 사용하려는게 목적이면 이건 안해도 된다.

가상머신을 기동할 때마다 초기 상태로 돌려서 사용하고자 한다.
이미지를 백업해 두고 매번 백업본을 복사해서 쓰는 것도 방법이지만 파일 크기가 큰 관계로 스냅샷 기능을 사용한다.
VHD 의 상속이나 도커의 레이어에 해당한다고 보면 될 것 같다.
원본 이미지는 읽기 전용으로 두고 변경되는 부분만 스냅샷 이미지에 저장한다.

자세한 설명 참고: https://kashyapc.fedorapeople.org/virt/lc-2012/snapshots-handout.html

6.1 윈도우 최적화
매번 같은 일을 하지 않도록 필요한 프로그램을 설치하고 설정해둔다.

6.2 베이스 이미지 크기 줄이기
꼭 필요하지는 않다
virtualbox 와 달리 처음부터 전체 디스크 크기를 할당하고 쓰는 것 같다.
더 커질일이 없으니 이미지 크기를 줄여 놓는다.

$ sudo chown $USER:$USER win10.qcow2 # root 권한으로 생성되었다
$ qemu-img convert -p -O qcow2 win10.qcow2 win10.qcow2.orig
$ ls -lh
# win10.qcow2.orig 는 실제 사용량만큼 작아져 있다.

6.3 스냅샷 생성

$ qemu-img create -F qcow2 -b win10.qcow2.orig -f qcow2 win10.qcow2

overlay 파일을 새로 생성하고 가상머신을 시작하면 깨끗한 상태로 시작하고,
생성하지 않고 시작하면 이전 상태가 계속 된다. 필요에 따라 나눠쓰면 되겠다.

참고
https://linuxstory1.tistory.com/entry/%ED%85%8D%EC%8A%A4%ED%8A%B8-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-%EA%B0%80%EC%83%81-%EB%A8%B8%EC%8B%A0-%EA%B4%80%EB%A6%AC%ED%95%98%EA%B8%B0
https://www.spice-space.org/download.html
https://www.ashbysoft.com/posts/libvirt-qemu-samba/
https://dausruddin.com/how-to-enable-clipboard-and-folder-sharing-in-qemu-kvm-on-windows-guest/
https://kashyapc.fedorapeople.org/virt/lc-2012/snapshots-handout.html