우리의 인식은 얼마나 오래 되었나?
한 두 주 전이었나? OwnTone이라는 Server를 발견하고는 무척이나 흥미로워했었다.
그리고 이케아에서 쉼포니스크 스피커를 할인하는 것을 보고 그 녀석을 들었다 놨다 사고 싶어 어쩔줄을 몰라하고 있었다.
그러다 문득 쉼포니스크가 AirPlay지원 이라면 AirPlay를 구성하는 서버도 있을 법 한데?
shairport-sync라고 아주 깔끔한 녀석이 이미 잘 나와있고 라즈베리파이3+B 정도면 아주 훌륭하게 작동한다.
![]() |
|---|
| Image Desc. |
WiFi형태의 네트워크 플레이어만 보면 어쩌던지 연결 해 보고 싶어하는 취미를 가진 사람으로서 이미 그 정신이 MPD에 머물러 있는 나는 이미 얼마나 옛날사람인가 싶다.
PCI passthrough
HASS를 올려 놓은 proxmox에서 블루투스장치가 필요해서 알아보니 PCI passthrough가 필요한 모양이다만.
과연 내가 사용하고 있는 자치에서 이게 된다는 건지 안된다는 건지 조사가 필요하다.
-
Blacklist Driver
Proxmox VE에서 PCI 패스스루를 설정할 때, 특정 장치에 대해 기본적으로 로드되는 커널 드라이버를 차단(블랙리스트)하는 것이 필요할 수 있습니다. 이는 해당 장치를 vfio-pci 모듈에 바인딩하기 위해 필요합니다. 블랙리스트를 설정하지 않으면, 기본 드라이버가 장치를 사용하게 되어 PCI 패스스루가 제대로 작동하지 않을 수 있습니다. -
OVMF
OVMF(Open Virtual Machine Firmware)는 UEFI(Unified Extensible Firmware Interface) 펌웨어의 가상화된 구현입니다. 이는 가상 머신(VM)에서 UEFI를 사용할 수 있도록 합니다. UEFI는 기존의 BIOS를 대체하는 최신 펌웨어 인터페이스로, 하드웨어 초기화, 운영 체제 로드 및 시스템 서비스를 관리합니다. OVMF는 특히 KVM/QEMU와 같은 가상화 플랫폼에서 사용됩니다.
acquiring lock * for container
![]() |
|---|
| 아침에 봤더니 이모양이다. |
ERRO[0000] Refreshing container 51761aec6dfe3ef8bd04b4bbff9625956787b37fbe248d654703462ca7a9ad4e: acquiring lock 2 for container 51761aec6dfe3ef8bd04b4bbff9625956787b37fbe248d654703462ca7a9ad4e: file exists
문제가 무엇인지 찾아본다.
- Github에서 누간가 질문한 글에서 유추하기를 Podman의 경우 root가 아닌 계정으로 작동하기 때문에 발생하는 것으로 보인다.
- loginctl이라는 녀석이 유용해 보인다.
GPT에게 질문해본다.
loginctl enable-linger 명령은 사용자가 시스템에 로그아웃한 후에도 그 사용자의 서비스가 계속 실행될 수 있도록 설정합니다. 이는 특히 rootless(비루트) Podman과 같은 도구를 사용할 때 유용합니다. 사용자가 로그아웃할 때 systemd가 사용자 세션과 관련된 리소스를 정리하지 않도록 하여 Podman 프로세스가 중단되지 않게 합니다.
setbool + httpd_can_network_connect
![]() |
|---|
| Nginx-Proxy 설정에 문제가 생긴다. |
처음에는 뭐가 문제인지 몰랐다. (이전에 사용하던 conf 파일을 집어넣었는데 말이다.)
$ getsebool -a | grep httpd_can_network
httpd_can_network_connect --> off
이 모든것이 SELinux에 대한 경험이 부족한 것에서 비롯되는 것이 아닌가 한다.
![]() |
|---|
| 그리고 모든 것은 로그에서 출발한다. |
Podman + iptable
![]() |
|---|
| Podman에서 Run했을때 마주한 에러 |
이런저런 사정으로 서버 전체를 다시구성하고 있는데, 뭔가 Ubuntu보다는 Rocky가 나은거 같아서 이번에도 선택을 했더니 알 수 없는 메시지를 뿌린다.
ERRO[0000] Starting some container dependencies
ERRO[0000] "netavark: code: 3, msg: modprobe: ERROR: could not insert 'ip_tables': Operation not permitted\niptables v1.8.10 (legacy): can't initialize iptables table `nat': Table does not exist (do you need to insmod?)\nPerhaps iptables or your kernel needs to be upgraded.\n"
Error: starting some containers: internal libpod error
좀 읽어보면 iptable에 insert를 못했다는 이야기인데.. 이제까지 환경설정하면서 처음 만나는 상황이 아닌가 싶다.
Vite + Build + Root
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
Streamlit에 Google login 컴포넌트를 만들어 넣고 있는데, URL로 불러오면 잘 보이는 것이 build해서 File로 serving하면 위와같은 메시지를 뿌린다.
뭘까? 한참을 읽어보고 network tab에서 읽어들이는 위치를 찾아보고 나서 이해가 된다.
http://localhost:9020/component/login_component.login_component/index.html?streamlitUrl=http%3A%2F%2Flocalhost%3A9020%2F
이 녀석이 Vite에서 생성된 index.html을 Streamlit에서 호출하는 녀석인데, Build된 녀석은 나름 저 혼자 돌아가는줄 알고 있을터이니, 빌드한 결과가 “/“로 잡혀있을 것이 분명했다.
Swagger + OAuth2
목표
- swagger에서
- google oauth를 swagger authorize ui에 적용
- 인증된 Token을 각 API에서 Header에 설정 할 수 있도록
custom open api
from fastapi.security.oauth2 import OAuth2AuthorizationCodeBearer
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel, OAuthFlowAuthorizationCode
from fastapi.openapi.models import SecurityScheme as SecuritySchemeModel
from fastapi.openapi.utils import get_openapi
# --------------------------------------------------------------
# Google oAuth2
CLIENT_ID = "...알아서"
CLIENT_SECRET = "...알아서"
TOKEN_URL = "...알아서"
AUTHORIZATION_URL = "...알아서"
class OAuth2Google(OAuth2AuthorizationCodeBearer):
def __init__(self):
super().__init__(authorizationUrl=AUTHORIZATION_URL, tokenUrl=TOKEN_URL)
oauth2_scheme = OAuth2Google()
# --------------------------------------------------------------
# Auth for Swagger
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="FastAPI with Google OAuth2",
version="1.0.0",
description="This is a FastAPI application integrating Google OAuth2",
routes=app.routes,
)
openapi_schema["components"]["securitySchemes"] = {
"OAuth2Google": {
"type": "oauth2",
"flows": {
"authorizationCode": {
"authorizationUrl": AUTHORIZATION_URL,
"tokenUrl": TOKEN_URL,
"scopes": {
"openid": "OpenID Connect",
"email": "Access to your email address",
"profile": "Access to your basic profile info"
}
}
}
}
}
app.openapi_schema = openapi_schema
return app.openapi_schema
# open api 변경
app.openapi = custom_openapi
이런 간단한 코드로 아래와 같은 훌륭한 화면을 도출 해 낼 수 있었으나.
HASS + Sonoff
Image Sample
![]() |
|---|
| configuration.yaml을 바꾸라는 정성스런 이미지. |
HASS OS를 올리고 sonoff를 위해 eWelink를 설치한것 까지는 좋았는데, 이 녀석이 동작을 안한다.
switch.turn_on을 찾을 수 없다는 메시지만 보여주고 답이 없다.
웃기는건 이전 버전에 어찌어찌 설치한 녀석들은 좀 야매스러워도 즉각 반응하는 것이 좀 이상했다.
약간의 구글링을 통해서 이 답변을 보고 configuration.yaml을 어찌 찾을 수 있을까 생각 해보니 SSH Addon이 보여서 설치하고 들어가.. 어 이미지에 있는 설정을 한땀 한땀 키인하고 재시작을 했더니 잘 적용이 된다.
HASS OS + Rpi3B
![]() |
|---|
| HASS OS Boot Image |
얼마전 NAS로 사용하고 있던 Ubuntu의 메모리가 2G인 것을 보고 깜짝 놀랐다. 최소 4G는 끼워준것같았는데.. 거기서 돌리고 있던 각종 서비스를 생각하면 너무한가 싶기도 하고 전혀 불편을 모르고 있었다는 것이 말이다.
지금 확인해봐도 1G사용에 800M cache다
토요일 처음 시작은 거실에서 사용하던 Rpi3+MPD에 Creative Roar2 Speaker를 USB로 붙이는 것이었는데, 자연스럽게 인식하던 Audio Engin2+와 다르게 usb device는 인식이 되는데 audio card에는 올라오지 않는다.
자 이렇게 뭔가 뜻하던 것이 안되는 상황이 되면, 그것을 해결하기 위해서 문제를 더 크게 만드는 재주가 있는듯 하다.
Swagger에 Google oAuth를 적용하며
Swagger에 Google oAuth를 적용하는 시도를 하고있었다.
대충 다 맞게 적용한거 같은데 자꾸만 redirect_uri_mismatch를 반환하는 것이다.
![]() |
|---|
| Swagge에서 보여주는 메시지 |
Google Console에서 설정하려고 아무생각없이 긁었는데.. 그게 문제다.
http://localhost:9031/docs/oauth2-redirect flowName=GeneralOAuthFlow
중간에 공백이 왜 있을까? 고민을 살짝 했으나.. 출력의 문제라고 판단하고
http://localhost:9031/docs/oauth2-redirect?flowName=GeneralOAuthFlow
당연히 될 일이 아니다.
결론은 아래와 같다.
http://localhost:9031/docs/oauth2-redirect
안내 메시지의 출력시 개행은 항상 중요하다.
요청 세부정보:
redirect_uri=http://localhost:9031/docs/oauth2-redirect
flowName=GeneralOAuthFlow







