diff --git a/.gitignore b/.gitignore index 63b8e77..844770f 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,10 @@ ssh.config* backup *~ *.vdi + +# qemu vm dir +/vm +/exports + +*.bak + diff --git a/bootstrap.sh b/bootstrap.sh index e7788b9..a7f6dfc 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -2,6 +2,23 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +show_completion_message() { + echo "---------------------- + +Congrats!!! + +You can now ssh into the machine by +\`\`\` +ssh $machine_name +\`\`\` + +- \`./status.sh\` to check the VM status +- \`./halt.sh\` to shut down the VM +- \`./up.sh\` to turn on the VM +- \`./destory.sh\` to start from scratch +" +} + noStartupScript=$(echo ${@} | grep -w '\-\-noStartupScript' >> /dev/null && echo 1 || echo "") echo "bootstrap.sh:" $@ @@ -15,27 +32,21 @@ else fi echo ================================= -echo Bootstrap vagrant machine +echo Bootstrap virtual machine echo ================================= source ./.env -expand_disk_size=${EXPAND_DISK_GB:-4} +expand_disk_size=${EXPAND_DISK_GB:-} swapfile=${SWAPFILE:-} -COMPOSE_VERSION=${_VER_DOCKER_COMPOSE} - -if [ "$_VER_DOCKER" ]; then - # setting docker version for provisioning - sed -i "s/VERSION=.*/VERSION=$_VER_DOCKER/" $SCRIPT_DIR/config/env_var.sh -fi # get username from env or prompt -username=$VAGRANT_USERNAME -if [ -z "$VAGRANT_USERNAME" ]; then - echo -n "> Please enter default vagrant user name [vagrant]:" +username=$VM_USERNAME +if [ -z "$VM_USERNAME" ]; then + echo -n "> Please enter default vm user name [linuxdev]:" read input - username=${input:-vagrant} - echo "VAGRANT_USERNAME=$username">> .env + username=${input:-linuxdev} + echo "VM_USERNAME=$username">> .env fi machine_name=${NAME:-linuxdev} @@ -67,43 +78,147 @@ if [ -z "$DOTFILES_REPO" ]; then fi fi +if [ -z "$DISK_SIZE_GB" ]; then + echo -n "> Please enter the gigabytes of disk [64]:" + read input + echo "DISK_SIZE_GB=${input:-64}">> .env +fi + +source ./.env + echo ================================= -echo Welcome $username! Pleae wait a moment for bootstrapping $machine_name +echo Welcome $username! Please wait a moment for bootstrapping $machine_name -vagrant plugin install vagrant-env -vagrant up +is_installed=$(grep INSTALL_COMPLETE ./vm/.status) + +if [ -n "$is_installed" ]; then + echo "The VM is already created" >&2 +else + +if [ "$windows" = 1 ]; then + echo "INSTALLING" >> ./vm/.status + vagrant plugin install vagrant-env + if vagrant up; then + echo "INSTALL_COMPLETE" >> ./vm/.status + fi +else + # VM이 이미 생성되었는지 확인 + if [ -f "./vm/disk.qcow2" ]; then + if [ -f "./vm/.status" ]; then + status=$(tail -1 ./vm/.status) + case "$status" in + "INSTALLING") + echo "VM '$machine_name' installation is in progress..." + echo "Check status: tail -f ./vm/install.log" + echo "To restart installation: rm -rf ./vm/ && ./bootstrap.sh" + exit 0 + ;; + "FAILED"|"TIMEOUT") + echo "VM '$machine_name' installation failed or timed out" + echo "Removing failed installation..." + rm -rf ./vm/ + echo "Retrying installation..." + ;; + esac + else + echo "VM '$machine_name' exists but status unknown" + echo "To start VM: ./up.sh" + echo "To recreate VM: rm -rf ./vm/ && ./bootstrap.sh" + exit 0 + fi + fi + + # Mac - QEMU VM 생성 + echo "Creating and installing Debian LTS with QEMU..." + # QEMU 프로세스 실행 중 확인 + if pgrep -f "qemu-system-aarch64" > /dev/null; then + echo "QEMU VM is already running. Please stop it first with './halt.sh'" + exit 1 + fi + if lsof -i :2222 > /dev/null 2>&1; then + echo "Port 2222 is already in use. Please stop it manually." + exit 1 + fi + + # VM 생성 및 설치 + set +e + ./scripts/qemu.create.sh "$machine_name" "${MEMORY:-2048}" "${CPUS:-2}" "${DISK_SIZE_GB:-20}" "$username" + set -e + + echo "\n=== VM Setup Complete ===" +fi + +fi # if is_installed + +# Set platform-specific defaults +if [ "$windows" = 1 ]; then + # Windows/Vagrant defaults + default_user_name="vagrant" + host_directory="/vagrant/" +else + # Mac/QEMU defaults + default_user_name="linuxdev" + host_directory="/mnt/host/" + ssh_port="2222" + ssh_host="localhost" +fi # create ssh config file SSH_CONFIG="$SCRIPT_DIR/ssh.config" -if [ -z "$(grep vagrant $SSH_CONFIG)" ]; then - vagrant ssh-config >> $SSH_CONFIG +if [ "$windows" = 1 ]; then + # Windows/Vagrant: Use vagrant ssh-config + if [ -z "$(grep $default_user_name $SSH_CONFIG)" ]; then + vagrant ssh-config >> $SSH_CONFIG + fi +else + # Mac/QEMU: Create SSH config manually + if [ ! -f "$SSH_CONFIG" ] || [ -z "$(grep "User $default_user_name"ca $SSH_CONFIG)" ]; then + echo Setting User $default_user_name to $SSH_CONFIG + cat > "$SSH_CONFIG" << EOF +Host default + HostName $ssh_host + User $default_user_name + Port $ssh_port + UserKnownHostsFile /dev/null + StrictHostKeyChecking no + PasswordAuthentication no + IdentityFile $(pwd)/vm/key/id_rsa + IdentitiesOnly yes + LogLevel FATAL +EOF + fi fi # create user with UID 1000 -#### user vagrant +#### switch default user ssh="ssh -F $SSH_CONFIG default" exists=$($ssh id -u $username 2>/dev/null) -vagrant_uid=$($ssh id -u vagrant 2>/dev/null) +admin_uid=$($ssh id -u $default_user_name 2>/dev/null) set -e -if [ "$vagrant_uid" == "1000" ] && ([ "$exists" != "" ] && [ "$exists" != "1000" ]); then +if [ "$admin_uid" == "1000" ] && ([ "$exists" != "" ] && [ "$exists" != "1000" ]); then echo switching is required, remove $username and try again fi -if [ -z "$vagrant_uid" ]; then +if [ -z "$admin_uid" ]; then echo ssh connection looks like failed exit -1; fi -$ssh sudo cp -a /home/vagrant/.ssh /root/ -$ssh sudo chown -R root:root /root/.ssh + +# Skip SSH key copying for QEMU (already done during installation) +if [ "$windows" = 1 ]; then # vagrant only + $ssh sudo cp -a /home/$default_user_name/.ssh /root/ + $ssh sudo chown -R root:root /root/.ssh +fi + if [ -z "$(grep root $SSH_CONFIG.user)" ]; then -$sed -e '0,/vagrant/{s/vagrant/'$username'/}' -e '0,/default/{s/default/'$machine_name/'}' $SSH_CONFIG >> $SSH_CONFIG.user +$sed -e "0,/$default_user_name/{s/$default_user_name/$username/}" -e '0,/default/{s/default/'$machine_name'/}' $SSH_CONFIG >> $SSH_CONFIG.user fi if [ -z "$(grep root $SSH_CONFIG.root)" ]; then - $sed -e '0,/vagrant/{s/vagrant/root/}' -e '0,/default/{s/default/root/}' $SSH_CONFIG >> $SSH_CONFIG.root + $sed -e "0,/$default_user_name/{s/$default_user_name/root/}" -e '0,/default/{s/default/root/}' $SSH_CONFIG >> $SSH_CONFIG.root fi #### user root @@ -114,52 +229,28 @@ ip_address=${IP_ADDRESS:-192.168.99.123} $ssh "touch ~/.hushlogin" $ssh << EOSSH -docker -v && exit; - -echo "====> Installing Docker" -docker_version=\$(grep '^_VER_DOCKER=' /vagrant/.env |tail -1 |cut -d'=' -f2) -echo "Version: \$docker_version" - -apt-get update -apt-get install -y ca-certificates curl -install -m 0755 -d /etc/apt/keyrings -curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc -chmod a+r /etc/apt/keyrings/docker.asc - -echo \ - "deb [arch=\$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ - \$(. /etc/os-release && echo "\$VERSION_CODENAME") stable" | \ - tee /etc/apt/sources.list.d/docker.list > /dev/null -apt-get update - -apt list -a docker-ce - -if [ -z "\$docker_version" ];then - apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -else - apt_docker_ver=\$(apt list -a docker-ce |grep -m1 \${docker_version} |cut -d' ' -f2) - echo "apt-get install -y docker-ce=\${apt_docker_ver} docker-ce-cli=\${apt_docker_ver} containerd.io docker-buildx-plugin docker-compose-plugin" - apt-get install -y docker-ce=\${apt_docker_ver} docker-ce-cli=\${apt_docker_ver} containerd.io docker-buildx-plugin docker-compose-plugin -fi -docker -v - +[ -d dotfiles ] && rm -rf dotfiles || true && \ +git clone -b alt/linuxdev https://github.com/kennyhyun/dotfiles.git dotfiles && \ +PRODUCTION=1 dotfiles/scripts/linux.sh linuxdev && \ +rm -rf dotfiles EOSSH -if [ -z "$exists" ]; then +# switch default user to $username +if [ "$username" != "$default_user_name" ] && [ -z "$exists" ]; then echo "user $username not found" $ssh << EOSSH echo --------------------- echo "creating $username" -vagrant_uid=\$(id -u vagrant) -if [ \$vagrant_uid == 1000 ]; then +admin_uid=\$(id -u ${default_user_name}) +if [ \$admin_uid == 1000 ]; then pkill -U 1000 - usermod -u 1002 vagrant - groupmod -g 1002 vagrant + usermod -u 1002 ${default_user_name} + groupmod -g 1002 ${default_user_name} fi -chown -R vagrant:vagrant /home/vagrant +chown -R ${default_user_name}:${default_user_name} /home/${default_user_name} useradd $username -u 1000 --create-home if ! [ -d "/home/$username/.ssh" ]; then - cp -a /home/vagrant/.ssh /home/$username/ + cp -a /home/${default_user_name}/.ssh /home/$username/ chown -R $username:$username /home/$username/.ssh fi grep $username /etc/passwd @@ -167,16 +258,18 @@ EOSSH echo --------------------- fi +# initial setup vm_hosts_vars=$(set | grep "__VMHOSTS__[^=]\+=" | cut -c 12-) $ssh << EOSSH -echo --------------------- Removing vagrant password -passwd vagrant --delete > /dev/null +echo --------------------- Removing ${default_user_name} password +passwd ${default_user_name} --delete > /dev/null echo --------------------- echo Adding $username to Sudoer usermod -aG sudo $username echo "$username ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/98_$username chmod 440 /etc/sudoers.d/98_$username usermod -aG docker $username +usermod -aG microk8s $username if [[ "\$(hostname)" =~ ^debian-[0-9]+$ ]]; then echo found default hostname, changing it to $machine_name @@ -185,7 +278,7 @@ if [[ "\$(hostname)" =~ ^debian-[0-9]+$ ]]; then echo "127.0.0.1 $machine_name" >> /etc/hosts fi -if [ $swapfile ]; then +if [ -n "$swapfile" ]; then echo Found SWAPFILE config if ! [ -f "/swapfile" ]; then echo "----- @@ -205,7 +298,7 @@ fi swapon --show free -h -if ! [ -f "/dummy" ]; then +if [ -n "$expand_disk_size" ] && ! [ -f "/dummy" ]; then echo "----- Expanding actual size for ${expand_disk_size}GB" let "blockSize = $expand_disk_size * 1024" @@ -214,10 +307,26 @@ Expanding actual size for ${expand_disk_size}GB" dd if=/dev/zero of=/dummy bs=1M count=\$blockSize oflag=append conv=notrunc fi +# add hosts entry +echo "$vm_hosts_vars" | while read -r line; do + host=\$(echo \$line | cut -d"=" -f 2) + ip=\$(echo \$line | cut -d"=" -f 1 | cut -f1,2,3,4 -d'_' | tr _ ".") + if [ -z "\$(grep "\$ip \$host" /etc/hosts)" ]; then + echo "Adding \"\$ip \$host\" to hosts file" + echo "\$ip \$host" >> /etc/hosts + fi +done + +EOSSH + + +if [ "$windows" = 1 ]; then # vagrant only +$ssh << EOSSH + if [ -z "\$(crontab -l|grep "${machine_name}.startup.sh")" ]; then echo "----- Adding startup script to crontab" - cp /vagrant/config/vm.docker.disk.sh /root/docker.disk.sh && \ + cp ${host_directory}config/vm.docker.disk.sh /root/docker.disk.sh && \ chmod +x /root/docker.disk.sh && \ echo "#!/bin/sh /root/docker.disk.sh" > /root/${machine_name}.startup.sh && \ @@ -236,17 +345,8 @@ crontab scripts:" fi crontab -l -# add hosts entry -echo "$vm_hosts_vars" | while read -r line; do - host=\$(echo \$line | cut -d"=" -f 2) - ip=\$(echo \$line | cut -d"=" -f 1 | cut -f1,2,3,4 -d'_' | tr _ ".") - if [ -z "\$(grep "\$ip \$host" /etc/hosts)" ]; then - echo "Adding \"\$ip \$host\" to hosts file" - echo "\$ip \$host" >> /etc/hosts - fi -done - EOSSH +fi $ssh "rm ~/.hushlogin" @@ -268,6 +368,12 @@ fi ssh $machine_name "touch ~/.hushlogin" #### user $username +if [ "$username" == "$default_user_name" ]; then + echo "username was the default user, stop personalising." + show_completion_message + exit +fi + ssh $machine_name << EOSSH echo "============================== @@ -297,29 +403,6 @@ Installing oh my zsh...." fi fi -if [ "\$?" -eq 0 ]; then -if [ -f "/usr/local/bin/docker-compose" ]; then - echo "----- -docker-compose aleady exists" - docker-compose --version -else - echo "----- -Installing docker-compose...." - sudo pip3 install requests --upgrade - dc_version=\${COMPOSE_VERSION:-1.29.2} - dc_version_url=/docker/compose/releases/download/\${dc_version}/docker-compose-\$(uname -s)-\$(uname -m) - if [ -z "\$dc_version_url" ];then - echo "Could not find the docker-compose url, please install manually from \$github_compose_release_url" - else - docker_compose_url=https://github.com\${dc_version_url} - echo Downloading: \$docker_compose_url - sudo wget \$docker_compose_url -O /usr/local/bin/docker-compose -q --show-progress --progress=bar:force - sudo chmod +x /usr/local/bin/docker-compose - docker-compose --version - fi -fi -fi - if [ "\$?" -eq 0 ]; then mkdir -p ~/Projects if [ -d ~/samba ]; then @@ -329,7 +412,7 @@ else echo "----- Configuring samba" mkdir -p samba - cp /vagrant/config/samba/* samba/ + cp ${host_directory}config/samba/* samba/ cd samba docker-compose down docker-compose up -d @@ -357,10 +440,10 @@ if [ -d ~/.docker/certs.$machine_name ]; then else echo "-------- Creating Docker certs" - ssh $machine_name /vagrant/scripts/create_docker_certs.sh + ssh $machine_name ${host_directory}scripts/create_docker_certs.sh mkdir -p ~/.docker/certs.$machine_name cp $SCRIPT_DIR/certs/*.pem ~/.docker/certs.$machine_name/ - ssh $machine_name sudo /vagrant/scripts/config_docker_certs.sh + ssh $machine_name sudo ${host_directory}scripts/config_docker_certs.sh echo "export DOCKER_CERT_PATH=~/.docker/certs.$machine_name export DOCKER_HOST=tcp://$ip_address:$docker_port export DOCKER_TLS_VERIFY=1 @@ -377,10 +460,10 @@ mkdir -p $SCRIPT_DIR/data/fonts touch $SCRIPT_DIR/data/fonts/.download_start_file if [ "$FONT_URLS" ] || [ "$PATCHED_FONT_URLS" ]; then echo "Installing fonts" -ssh $machine_name "bash /vagrant/scripts/download-fonts.sh \"$FONT_URLS\" \"$PATCHED_FONT_URLS\"" +ssh $machine_name "bash ${host_directory}scripts/download-fonts.sh \"$FONT_URLS\" \"$PATCHED_FONT_URLS\"" downloaded=$(find $SCRIPT_DIR/data/fonts -maxdepth 1 -newer $SCRIPT_DIR/data/fonts/.download_start_file -type f -name "*.ttf") if [ "$downloaded" ]; then - if [ "$windows" ]; then + if [ "$windows" = 1 ]; then while read file; do base=$(basename "$file") font_args="$font_args \"$base\"" @@ -406,7 +489,7 @@ else ssh $machine_name << EOSSH if ! [ -d ~/dotfiles ]; then echo "======= Cloning dotfiles" - git clone $([ -n "$DOTFILES_BRANCH" ] && echo "--branch $DOTFILES_BRANCH") --recurse-submodules $DOTFILES_REPO ~/dotfiles && \ + git clone $([ -n "$DOTFILES_BRANCH" ] && echo "-b $DOTFILES_BRANCH") --recurse-submodules $DOTFILES_REPO ~/dotfiles && \ init=\$(find dotfiles -maxdepth 1 -type f -executable -name 'init*' \ -o -type f -executable -name "bootstrap*" -o -type f -executable -name "setup*" \ -o -type f -executable -name "install*" \ @@ -426,7 +509,7 @@ EOSSH fi echo "Setting up host environments" -if [ -z "$windows" ]; then +if [ "$windows" -ne 1 ]; then if [ -z "$noStartupScript" ]; then $SCRIPT_DIR/scripts/setup-launchd.sh fi @@ -493,16 +576,4 @@ echo --------------------- rm ~/.hushlogin EOSSH -echo "---------------------- - -Congrats!!! - -You can now ssh into the machine by -\`\`\` -ssh $machine_name -\`\`\` - -- \`vagrant halt\` to shut down the VM -- \`vagrant up\` to turn on the VM -- \`./destory.sh\` to start from scratch -" +show_completion_message diff --git a/halt.sh b/halt.sh new file mode 100755 index 0000000..0cca001 --- /dev/null +++ b/halt.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ $(uname -s) == "Darwin" ]]; then + # Mac - QEMU 사용 + ./scripts/qemu.halt.sh +else + # Windows - Vagrant 사용 + vagrant halt +fi \ No newline at end of file diff --git a/scripts/export-split.sh b/scripts/export-split.sh new file mode 100755 index 0000000..159bef5 --- /dev/null +++ b/scripts/export-split.sh @@ -0,0 +1,223 @@ +#!/bin/bash + +set -e + +SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +# 설정 +VM_NAME="${1:-linuxdev}" +EXPORT_FORMAT="qcow2" # qcow2만 지원 +OUTPUT_DIR="$PROJECT_DIR/exports" +VOLUME_SIZE="268435456" # 256MB 정확히 (바이트 단위) + +# 함수들 +get_vm_architecture() { + local vm_disk="$PROJECT_DIR/vm/disk.qcow2" + if [ -f "$vm_disk" ]; then + # qemu-img info로 아키텍처 정보 추출 시도 + local arch_info=$(qemu-img info "$vm_disk" 2>/dev/null | grep -i "format specific" -A 10 || true) + + # 프로세서 아키텍처 감지 + local host_arch=$(uname -m) + case "$host_arch" in + "arm64"|"aarch64") echo "arm64" ;; + "x86_64"|"amd64") echo "x64" ;; + "i386"|"i686") echo "x86" ;; + *) echo "$host_arch" ;; + esac + else + # VM 디스크가 없으면 호스트 아키텍처 사용 + local host_arch=$(uname -m) + case "$host_arch" in + "arm64"|"aarch64") echo "arm64" ;; + "x86_64"|"amd64") echo "x64" ;; + "i386"|"i686") echo "x86" ;; + *) echo "$host_arch" ;; + esac + fi +} + +check_vm_status() { + echo "Checking VM status..." + if pgrep -f "qemu-system-aarch64" > /dev/null; then + echo "⚠️ VM is running. Shutting down safely..." + "$PROJECT_DIR/halt.sh" + + # VM 종료 대기 + for i in {1..30}; do + if ! pgrep -f "qemu-system-aarch64" > /dev/null; then + echo "✅ VM shutdown complete" + break + fi + if [ $i -eq 30 ]; then + echo "❌ VM shutdown timeout" + exit 1 + fi + sleep 2 + done + else + echo "✅ VM is not running" + fi +} + +export_qcow2_uncompressed() { + local input_file="$PROJECT_DIR/vm/disk.qcow2" + local arch=$(get_vm_architecture) + local output_file="$OUTPUT_DIR/${VM_NAME}-${arch}-$(date +%Y%m%d).qcow2" + + echo "Exporting QCOW2 format (uncompressed)..." + qemu-img convert -f qcow2 -O qcow2 "$input_file" "$output_file" + echo "✅ QCOW2 export complete: $output_file" + echo "$output_file" +} + +create_7zip_volumes() { + local file_path="$1" + local filename="$(basename "$file_path")" + local dir="$(dirname "$file_path")" + local base_name="${filename%.*}" + + echo "Creating 7zip volumes (${VOLUME_SIZE} each)..." + + # 7zip 설치 확인 + if ! command -v 7z >/dev/null 2>&1; then + echo "Installing 7zip..." + if [[ $(uname -s) == "Darwin" ]]; then + brew install p7zip + else + sudo apt-get update && sudo apt-get install -y p7zip-full + fi + fi + + # 7zip으로 볼륨 분할 압축 (최대 압축률, 무조건 001 확장자) + cd "$dir" + local archive_name="${base_name}" + # 포맷에 따라 다른 아카이브 이름 사용 + if [[ "$filename" == *.img ]]; then + archive_name="${base_name}-raw" + elif [[ "$filename" == *.qcow2 ]]; then + archive_name="${base_name}" + fi + 7z a -t7z -v${VOLUME_SIZE}b -mx=9 "${archive_name}.7z" "$filename" + + # 압축 파일 검증 (무조건 001 파일로 검증) + echo "Verifying compressed archive..." + if 7z t "${archive_name}.7z.001" > /dev/null 2>&1; then + echo "✅ Archive verification successful" + + # 검증 성공 시 원본 파일 자동 삭제 + rm "$file_path" + echo "✅ Original file deleted after verification" + else + echo "❌ Archive verification failed - keeping original file" + return 1 + fi + + + + # 체크섬 파일 생성 (무조건 001부터 시작하는 볼륨들) + echo "Creating checksums..." + for vol_file in ${archive_name}.7z.*; do + if [ -f "$vol_file" ]; then + shasum -a 256 "$vol_file" >> "${archive_name}.sha256" + fi + done + + echo "✅ 7zip archive created:" + + # 무조건 001부터 시작하는 볼륨 설정 + local archive_ext=".7z.001" + local extract_cmd_suffix=".*" + local notes_desc_aux="split into 256MB volumes." + + ls -lh ${archive_name}${archive_ext} + echo "" + echo "📁 Files to upload:" + echo " - ${archive_name}${archive_ext} (volume file(s))" + echo " - ${archive_name}.sha256 (checksum(s))" + + echo "" + echo "💡 GitHub Release upload commands:" + echo " gh release create v$(date +%Y%m%d) ${archive_name}${archive_ext} ${archive_name}.sha256 \\" + echo " --title 'VM Export $(date +%Y-%m-%d)' \\" + echo " --notes 'VM disk image${notes_desc_aux}. Extract with: 7z x ${archive_name}.7z${extract_cmd_suffix}'" + + # 자동 업로드 옵션 + if [ "$2" = "--upload" ]; then + echo "" + read -p "Create GitHub Release now? (y/N): " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Creating GitHub Release..." + "$SCRIPT_DIR/upload-release.sh" "${archive_name}" + fi + fi +} + +# 메인 실행 +main() { + echo "🚀 Starting VM export with 7zip splitting..." + echo "VM Name: $VM_NAME" + echo "Format: $EXPORT_FORMAT" + echo "Volume Size: $VOLUME_SIZE" + echo "Output: $OUTPUT_DIR" + + # 출력 디렉토리 생성 + mkdir -p "$OUTPUT_DIR" + + # VM 상태 확인 및 종료 + check_vm_status + + # VM 디스크 파일 존재 확인 + if [ ! -f "$PROJECT_DIR/vm/disk.qcow2" ]; then + echo "❌ VM disk not found: $PROJECT_DIR/vm/disk.qcow2" + exit 1 + fi + + # QCOW2 export + export_qcow2_uncompressed + local arch=$(get_vm_architecture) + local exported_file="$OUTPUT_DIR/${VM_NAME}-${arch}-$(date +%Y%m%d).qcow2" + + # 파일 정보 출력 + echo "" + echo "📊 Export Summary:" + echo " File: $exported_file" + echo " Size: $(du -h "$exported_file" | cut -f1)" + + # 7zip 볼륨 생성 + create_7zip_volumes "$exported_file" + + echo "" + echo "✅ Export and splitting complete!" +} + +# 사용법 출력 +if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then + echo "Usage: $0 [VM_NAME] [--upload]" + echo "" + echo "Arguments:" + echo " VM_NAME VM name (default: linuxdev)" + echo " --upload Create GitHub Release after export" + echo "" + echo "Features:" + echo " - Exports VM disk in QCOW2 format" + echo " - Splits into 256MB 7zip volumes for GitHub Release" + echo " - Creates checksums for verification" + echo " - Compatible with all virtualization platforms" + echo "" + echo "Examples:" + echo " $0 # Export as QCOW2, split with 7zip" + echo " $0 myvm # Export specific VM" + echo " $0 myvm --upload # Export and create GitHub Release" + echo "" + echo "After upload, users can:" + echo " 1. Download all .7z.* files" + echo " 2. Run the extraction script" + echo " 3. Convert to desired format with qemu-img" + exit 0 +fi + +# 메인 실행 +main "$@" \ No newline at end of file diff --git a/scripts/qemu.create.sh b/scripts/qemu.create.sh new file mode 100755 index 0000000..e70758f --- /dev/null +++ b/scripts/qemu.create.sh @@ -0,0 +1,290 @@ +#!/bin/bash + +# QEMU 완전 자동화 VM 생성 스크립트 +create_qemu_vm() { + local vm_name="$1" + local memory="$2" + local cpus="$3" + local disk_size="${4:-20}" + local username="${5:-linuxdev}" + + echo "Creating QEMU VM: $vm_name (Debian 13 LTS)" + echo "Memory: ${memory}MB, CPUs: $cpus, Disk: ${disk_size}GB" + + # Debian 13 ARM64 ISO 다운로드 + local base_url="https://cdimage.debian.org/debian-cd/current/arm64/iso-cd" + local iso_filename="debian-13.0.0-arm64-netinst.iso" + local iso_url="$base_url/$iso_filename" + local sha256_url="$base_url/SHA256SUMS" + local iso_path="$HOME/Downloads/$iso_filename" + local sha256_path="$HOME/Downloads/SHA256SUMS" + + # ISO 파일 다운로드 + if [ ! -f "$iso_path" ]; then + echo "Downloading Debian 13 ARM64 ISO..." + curl -L -o "$iso_path" "$iso_url" + + # SHA256SUMS 다운로드 + echo "Downloading SHA256SUMS for verification..." + curl -L -o "$sha256_path" "$sha256_url" + + + # SHA256 검증 + echo "Verifying ISO integrity..." + cd "$HOME/Downloads" + if grep "$(basename "$iso_path")" "$sha256_path" | shasum -a 256 -c -; then + echo "✅ ISO verification successful" + else + echo "❌ ISO verification failed" + return 1 + fi + cd - > /dev/null + fi + + # VM 디스크 이미지 생성 + local vm_dir="$(pwd)/vm" + echo "Using vm_dir: $vm_dir" + mkdir -p "$vm_dir" + + # # ISO에서 kernel과 initrd 추출 + # local extract_dir="$vm_dir/extract" + # if [ ! -f "$extract_dir/vmlinuz" ] || [ ! -f "$extract_dir/initrd.gz" ]; then + # echo "Extracting kernel and initrd from ISO..." + # mkdir -p "$extract_dir" + + # # 7zip 설치 확인 + # if ! command -v 7z >/dev/null 2>&1; then + # echo "Installing 7zip..." + # brew install p7zip + # fi + + # # ISO에서 파일 추출 + # echo "Extracting files from ISO..." + # 7z x "$iso_path" -o"$extract_dir/iso_content" "install.a64/vmlinuz" "install.a64/initrd.gz" -y + + # # 파일 이동 + # mv "$extract_dir/iso_content/install.a64/vmlinuz" "$extract_dir/vmlinuz" + # mv "$extract_dir/iso_content/install.a64/initrd.gz" "$extract_dir/initrd.gz" + + # # 임시 폴더 삭제 + # rm -rf "$extract_dir/iso_content" + + # echo "✅ Kernel and initrd extracted successfully" + # fi + + # 사용 가능한 포트 찾기 (미리 정의) + local http_port=8080 + while lsof -i :$http_port > /dev/null 2>&1; do + http_port=$((http_port + 1)) + done + + # for Automated Install + # Preseed 파일 생성 (완전 자동 설치) + # HTTP 포트와 사용자명을 preseed에 삽입하기 위해 임시 변수 사용 + local preseed_late_cmd="wget -O /tmp/id_rsa.pub http://10.0.2.2:$http_port/key/id_rsa.pub && \ + mkdir -p /target/home/$username/.ssh /target/root/.ssh && \ + chmod 700 /target/home/$username/.ssh && \ + chmod 700 /target/root/.ssh && \ + cp /tmp/id_rsa.pub /target/home/$username/.ssh/authorized_keys && \ + chmod 600 /target/home/$username/.ssh/authorized_keys && \ + chown 1000:1000 -R /target/home/$username/.ssh && \ + cp /tmp/id_rsa.pub /target/root/.ssh/authorized_keys && \ + chmod 600 /target/root/.ssh/authorized_keys && \ + echo '$username ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/98_$username && \ + chmod 440 /target/etc/sudoers.d/98_$username && \ + sed -i 's/^#\?PermitRootLogin prohibit-password/PermitRootLogin yes/' /target/etc/ssh/sshd_config" + + cat > "$vm_dir/preseed.cfg" << EOF +d-i debian-installer/locale string en_AU +d-i console-setup/ask_detect boolean false +d-i console-setup/layoutcode string us +d-i keyboard-configuration/xkb-keymap select us +d-i netcfg/choose_interface select auto +d-i netcfg/get_hostname string $vm_name +d-i netcfg/get_domain string local +d-i mirror/country string manual +d-i mirror/http/hostname string ftp.au.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string +d-i passwd/root-login boolean false +d-i passwd/user-fullname string $username +d-i passwd/username string $username +d-i passwd/user-password password debian +d-i passwd/user-password-again password debian +d-i clock-setup/utc boolean true +d-i time/zone string Australia/Sydney +d-i partman-auto/method string regular +d-i partman-auto/choose_recipe select atomic +d-i partman/confirm_write_new_label boolean true +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true +d-i base-installer/install-recommends boolean false +tasksel tasksel/first multiselect ssh-server +d-i pkgsel/include string openssh-server sudo curl wget git +d-i pkgsel/upgrade select none +d-i grub-installer/only_debian boolean true +d-i grub-installer/with_other_os boolean true +d-i preseed/late_command string $preseed_late_cmd +d-i finish-install/reboot_in_progress note +d-i debian-installer/exit/halt boolean true +EOF + + + if [ -f $vm_dir/.status ]; then + vm_installed=$(grep INSTALL_COMPLETE $vm_dir/.status) + fi + if [ -z "$vm_installed" ]; then + echo "Using HTTP port: $http_port" + + # HTTP 서버로 preseed 제공 + echo "Starting HTTP server for preseed..." + cd "$vm_dir" + python3 -m http.server $http_port > /dev/null 2>&1 & + local http_pid=$! + cd - > /dev/null + + + if [ ! -f "$vm_dir/disk.qcow2" ]; then + echo "Creating VM disk image..." + qemu-img create -f qcow2 "$vm_dir/disk.qcow2" "${disk_size}G" + fi + + # VM 전용 키페어 생성 (설치 전에 필요) + mkdir -p "$vm_dir/key" + if [ ! -f "$vm_dir/key/id_rsa" ]; then + echo "Creating VM keypair..." + ssh-keygen -t rsa -b 2048 -f "$vm_dir/key/id_rsa" -N "" -C "$username@$vm_name" + echo "✅ VM keypair created" + fi + + # 초기 설정 스크립트 생성 (설치 전에 필요) + if [ ! -f "$vm_dir/setup.sh" ]; then + cat > "$vm_dir/setup.sh" << 'SETUP_EOF' +#!/bin/bash +# Setup user SSH keys +mkdir -p /target/home/REPLACE_USERNAME/.ssh +cp /target/mnt/host/vm/key/id_rsa.pub /target/home/REPLACE_USERNAME/.ssh/authorized_keys +chown 1000:1000 /target/home/REPLACE_USERNAME/.ssh/authorized_keys +chmod 600 /target/home/REPLACE_USERNAME/.ssh/authorized_keys +chmod 700 /target/home/REPLACE_USERNAME/.ssh + +# Setup root SSH keys +mkdir -p /target/root/.ssh +cp /target/mnt/host/vm/key/id_rsa.pub /target/root/.ssh/authorized_keys +chown 0:0 /target/root/.ssh/authorized_keys +chmod 600 /target/root/.ssh/authorized_keys +chmod 700 /target/root/.ssh + +# Setup sudoers +echo 'REPLACE_USERNAME ALL=(ALL) NOPASSWD:ALL' > /target/etc/sudoers.d/98_REPLACE_USERNAME +chmod 440 /target/etc/sudoers.d/98_REPLACE_USERNAME +SETUP_EOF + if [[ $(uname -s) == "Darwin" ]]; then + gsed -i "s/REPLACE_USERNAME/$username/g" "$vm_dir/setup.sh" + else + sed -i "s/REPLACE_USERNAME/$username/g" "$vm_dir/setup.sh" + fi + chmod +x "$vm_dir/setup.sh" + fi + + # 설치용 임시 시작 + # after booting, + # choose Advanced and Auto installation + # and paste http://10.0.2.2:8080/preseed.cfg + + echo "Starting automated Debian installation..." + echo "📋 Preseed URL: http://10.0.2.2:$http_port/preseed.cfg" + echo "🔧 Boot options: auto=true priority=critical preseed/url=http://10.0.2.2:$http_port/preseed.cfg" + echo "⚠️ Manual step required: Select 'Advanced options' -> 'Automated install' and enter the preseed URL above" + + # 설치 시작 상태 기록 + echo "INSTALLING" >> "$vm_dir/.status" + echo "$(date) - Installation started" > "$vm_dir/install.log" + echo "Installation started for $vm_name" >> "$vm_dir/install.log" + + qemu-system-aarch64 \ + -M virt,highmem=on,gic-version=3 \ + -accel hvf \ + -cpu host \ + -smp $cpus \ + -m ${memory}M \ + -bios /opt/homebrew/share/qemu/edk2-aarch64-code.fd \ + -drive file="$vm_dir/disk.qcow2",format=qcow2,if=virtio \ + -drive file="$iso_path",media=cdrom,readonly=on \ + -netdev user,id=net0,hostfwd=tcp::2222-:22 \ + -device virtio-net-pci,netdev=net0 \ + -monitor unix:$vm_dir/monitor.sock,server,nowait \ + -vnc 127.0.0.1:1,password=off \ + -nographic + + echo "INSTALL_COMPLETE" >> "$vm_dir/.status" + echo "$(date) - Installation completed" >> "$vm_dir/install.log" + + # HTTP 서버 종료 및 설치 완료 기록 + kill $http_pid 2>/dev/null || true + echo "✅ VM installation completed" + fi + + # Start the VM + ./up.sh -q + + # Wait until SSH authentication is ready + echo "Waiting for SSH authentication to be ready..." + for i in {1..10}; do + if timeout 3 ssh -p 2222 -i "$vm_dir/key/id_rsa" -o StrictHostKeyChecking=no -o ConnectTimeout=3 "$username@localhost" "echo ''" 2>/dev/null; then + echo "✅ SSH authentication is ready" + break + fi + if [ $i -eq 10 ]; then + echo "❌ Timeout waiting for SSH authentication" + return 1 + fi + echo "Attempt $i/10: SSH not ready yet, waiting..." + sleep 3 + done + + echo "SSHD_STARTED" >> "$vm_dir/.status" + echo "Installation completed for $vm_name, up and running" >> "$vm_dir/install.log" + + # VM 설정 완료 + + echo "✅ VM setup completed successfully!" + echo "🔑 SSH Key Authentication: ssh -p 2222 -i ./vm/key/id_rsa $username@localhost" + echo "🔑 Root Access: ssh -p 2222 -i ./vm/key/id_rsa root@localhost" + echo "📝 Password Login (fallback): ssh -p 2222 $username@localhost (password: debian)" + echo "" + echo "🚀 Next steps:" + echo " - VM is already running and ready to use" + echo " - Continue with: ./bootstrap.sh" + echo " - Stop VM: ./halt.sh" + echo " - Check status: ./status.sh" + + return 0 +} + +# ================================ + +set -e + +# QEMU 설치 확인 +if ! command -v qemu-img >/dev/null 2>&1; then + echo "Installing QEMU..." + brew install qemu +fi + +# GNU sed 설치 및 설정 (macOS) +if [[ $(uname -s) == "Darwin" ]]; then + if ! command -v gsed >/dev/null 2>&1; then + echo "Installing GNU sed..." + brew install gnu-sed + fi +fi + +# 메인 실행 +if [ "$#" -lt 3 ]; then + echo "Usage: $0 [disk_size_gb] [username]" + exit 1 +fi + +create_qemu_vm "$@" diff --git a/scripts/qemu.halt.sh b/scripts/qemu.halt.sh new file mode 100755 index 0000000..b00d603 --- /dev/null +++ b/scripts/qemu.halt.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +VM_DIR="$(cd "$SCRIPT_DIR/.." && pwd)/vm" + +# .env 파일에서 설정 로드 +if [ -f "$SCRIPT_DIR/../.env" ]; then + source "$SCRIPT_DIR/../.env" +fi + +NAME=${NAME:-linuxdev} +VM_USERNAME=${VM_USERNAME:-debian} +MONITOR_SOCK="$VM_DIR/monitor.sock" + +# VM이 실행 중인지 확인 +if ! pgrep -f "qemu-system-aarch64.*vm/disk.qcow2" > /dev/null; then + echo "VM '$NAME' is not running" + exit 0 +fi + +echo "Stopping VM '$NAME'..." + +# Monitor 소켓으로 우아한 종료 시도 +if [ -S "$MONITOR_SOCK" ]; then + echo "Sending ACPI powerdown signal..." + echo "system_powerdown" | socat - unix:"$MONITOR_SOCK" 2>/dev/null + + # 10초 대기 + echo "checking qemu-system-aarch64 pid" + for i in {1..50}; do + if ! pgrep -f "qemu-system-aarch64.*vm/disk.qcow2"; then + echo "✅ VM '$NAME' stopped gracefully" + exit 0 + fi + sleep 1 + done +fi + +# # SSH로 종료 시도 +# echo "Trying SSH shutdown..." +# ssh -p 2222 -o ConnectTimeout=3 $VM_USERNAME@localhost 'sudo poweroff' 2>/dev/null + +# # 10초 더 대기 +# for i in {1..10}; do +# if ! pgrep -f "qemu-system-aarch64.*vm/disk.qcow2" > /dev/null; then +# echo "✅ VM '$NAME' stopped via SSH" +# exit 0 +# fi +# sleep 1 +# done + +# # 강제 종료 +# echo "Force stopping VM '$NAME'..." +# pkill -f "qemu-system-aarch64.*vm/disk.qcow2" +# sleep 2 + +if ! pgrep -f "qemu-system-aarch64.*vm/disk.qcow2" > /dev/null; then + echo "✅ VM '$NAME' force stopped" +else + echo "❌ Failed to stop VM '$NAME'" + exit 1 +fi \ No newline at end of file diff --git a/scripts/qemu.up.sh b/scripts/qemu.up.sh new file mode 100755 index 0000000..8d91ec4 --- /dev/null +++ b/scripts/qemu.up.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +VM_DIR="$(cd "$SCRIPT_DIR/.." && pwd)/vm" + +# .env 파일에서 설정 로드 +if [ -f "$SCRIPT_DIR/../.env" ]; then + source "$SCRIPT_DIR/../.env" +fi + +# 기본값 설정 +CPUS=${CPUS:-2} +MEMORY=${MEMORY:-2048} +NAME=${NAME:-linuxdev} + +# VM 디렉토리 생성 +mkdir -p "$VM_DIR" + +# VM이 이미 실행 중인지 확인 +if pgrep -f "qemu-system-aarch64.*vm/disk.qcow2" > /dev/null; then + echo "VM '$NAME' is already running" + exit 0 +fi + +# VM 디스크 파일 존재 확인 +if [ ! -f "$VM_DIR/disk.qcow2" ]; then + echo "VM disk not found at $VM_DIR/disk.qcow2" + echo "Please run ./bootstrap.sh first to create the VM" + exit 1 +fi + + +iso_filename="debian-13.0.0-arm64-netinst.iso" +iso_path="$HOME/Downloads/$iso_filename" + +# 콘솔 모드 확인 +if [ "$1" = "--console" ] || [ "$1" = "-c" ]; then + echo "Starting VM '$NAME' in console mode... in '$VM_DIR'" + echo "Press Ctrl+A, X to exit console" + qemu-system-aarch64 \ + -M virt,highmem=on,gic-version=3 \ + -accel hvf \ + -cpu host \ + -smp $CPUS \ + -m ${MEMORY}M,slots=4,maxmem=$((MEMORY * 2))M \ + -bios /opt/homebrew/share/qemu/edk2-aarch64-code.fd \ + -drive file="$VM_DIR/disk.qcow2",format=qcow2,if=virtio \ + -netdev user,id=net0,hostfwd=tcp::2222-:22 \ + -device virtio-net-pci,netdev=net0 \ + -monitor unix:$VM_DIR/monitor.sock,server,nowait \ + -nographic +else + echo "Starting VM '$NAME' in headless mode... in '$VM_DIR'" + if [ "$1" != "-q" ]; then + echo "SSH: ssh -p 2222 kenny@localhost" + echo "VNC: localhost:5901" + echo "Console: ./up.sh --console" + fi + qemu-system-aarch64 \ + -M virt,highmem=on,gic-version=3 \ + -accel hvf \ + -cpu host \ + -smp $CPUS \ + -m ${MEMORY}M,slots=4,maxmem=$((MEMORY * 2))M \ + -bios /opt/homebrew/share/qemu/edk2-aarch64-code.fd \ + -drive file="$VM_DIR/disk.qcow2",format=qcow2,if=virtio \ + -netdev user,id=net0,hostfwd=tcp::2222-:22 \ + -device virtio-net-pci,netdev=net0 \ + -monitor unix:$VM_DIR/monitor.sock,server,nowait \ + -vnc 127.0.0.1:1,password=off \ + -daemonize +fi \ No newline at end of file diff --git a/scripts/qemu.wait-install.sh b/scripts/qemu.wait-install.sh new file mode 100755 index 0000000..458b88d --- /dev/null +++ b/scripts/qemu.wait-install.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# 설치 완료 대기 및 상태 업데이트 스크립트 + +VM_DIR="$1" +USERNAME="$2" +MAX_WAIT=1800 # 30분 최대 대기 + +echo "Waiting for installation to complete..." >> "$VM_DIR/install.log" + +for i in $(seq 1 $MAX_WAIT); do + # SSH 연결 테스트 (설치 완료 확인) + if ssh -p 2222 -o ConnectTimeout=3 -o StrictHostKeyChecking=no "$USERNAME@localhost" 'echo "Installation complete"' >> "$VM_DIR/install.log" 2>&1; then + echo "COMPLETED" > "$VM_DIR/install.status" + echo "$(date): Installation completed successfully" >> "$VM_DIR/install.log" + + # 설치 완료 후 VM 종료 + echo "system_powerdown" | socat - unix:"$VM_DIR/monitor.sock" 2>/dev/null + + echo "✅ Installation completed! VM has been shut down." + echo "Use './up.sh' to start the installed VM" + exit 0 + fi + + # VM이 종료되었는지 확인 (설치 실패 가능성) + if ! pgrep -f "qemu-system-aarch64.*vm/disk.qcow2" > /dev/null; then + echo "FAILED" > "$VM_DIR/install.status" + echo "$(date): VM stopped unexpectedly during installation" >> "$VM_DIR/install.log" + echo "❌ Installation failed - VM stopped unexpectedly" + exit 1 + fi + + # 10초마다 체크 + sleep 10 +done + +# 타임아웃 +echo "TIMEOUT" > "$VM_DIR/install.status" +echo "$(date): Installation timed out after 30 minutes" >> "$VM_DIR/install.log" +echo "⏰ Installation timed out. Please check manually." +exit 1 \ No newline at end of file diff --git a/scripts/upload-release.sh b/scripts/upload-release.sh new file mode 100755 index 0000000..05be933 --- /dev/null +++ b/scripts/upload-release.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e + +# 사용법 확인 +if [ "$#" -lt 1 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then + echo "Usage: $0 [tag] [title]" + echo "" + echo "Arguments:" + echo " archive_name Base name of archive (without extension)" + echo " tag Release tag (default: v$(date +%Y%m%d))" + echo " title Release title (default: VM Export $(date +%Y-%m-%d))" + echo "" + echo "Examples:" + echo " $0 linuxdev-arm64-20250827" + echo " $0 linuxdev-arm64-20250827 v1.0.0 'Stable Release'" + echo "" + echo "Files to upload:" + echo " - .7z (or .7z.*)" + echo " - .sha256" + exit 0 +fi + +ARCHIVE_NAME="$1" +TAG="${2:-v$(date +%Y%m%d)}" +TITLE="${3:-VM Export $(date +%Y-%m-%d)}" + +# exports 디렉토리로 이동 +cd "$(dirname "$0")/../exports" + +# 파일 존재 확인 +if [ ! -f "${ARCHIVE_NAME}.sha256" ]; then + echo "❌ Checksum file not found: ${ARCHIVE_NAME}.sha256" + exit 1 +fi + +# 아카이브 파일 확인 +if [ -f "${ARCHIVE_NAME}.7z" ]; then + ARCHIVE_FILES="${ARCHIVE_NAME}.7z" + EXTRACT_CMD="7z x ${ARCHIVE_NAME}.7z" + NOTES="VM disk image. Extract with: $EXTRACT_CMD" +elif [ -f "${ARCHIVE_NAME}.7z.001" ]; then + ARCHIVE_FILES="${ARCHIVE_NAME}.7z.*" + EXTRACT_CMD="7z x ${ARCHIVE_NAME}.7z.001" + NOTES="VM disk image split into 256MB volumes. Extract with: $EXTRACT_CMD" +else + echo "❌ Archive file not found: ${ARCHIVE_NAME}.7z or ${ARCHIVE_NAME}.7z.001" + exit 1 +fi + +# GitHub CLI 확인 +if ! command -v gh >/dev/null 2>&1; then + echo "❌ GitHub CLI not found. Install with: brew install gh" + exit 1 +fi + +# 파일 목록 출력 +echo "📁 Files to upload:" +ls -lh $ARCHIVE_FILES "${ARCHIVE_NAME}.sha256" + +echo "" +echo "🚀 Creating GitHub Release..." +echo "Tag: $TAG" +echo "Title: $TITLE" + +# GitHub Release 생성 +gh release create "$TAG" $ARCHIVE_FILES "${ARCHIVE_NAME}.sha256" \ + --title "$TITLE" \ + --notes "$NOTES" + +echo "✅ GitHub Release created successfully!" +echo "🔗 View release at: gh release view $TAG --web" diff --git a/setup.sh b/setup.sh index 25519f3..bbe9c96 100755 --- a/setup.sh +++ b/setup.sh @@ -7,31 +7,31 @@ do if [ "$param" == "--no-devtools" ] ; then no_devtools=1 fi - if [ "$param" == "--no-xcode" ] ; then - no_xcode=1 - fi + # if [ "$param" == "--no-xcode" ] ; then + # no_xcode=1 + # fi if [ "$param" == "--no-vscode" ] ; then no_vscode=1 fi if [ "$param" == "--no-gnused" ] ; then no_gnused=1 fi - if [ "$param" == "--no-git" ] ; then - no_git=1 - fi - if [ "$param" == "--no-iterm2" ] ; then - no_iterm2=1 - fi - if [ "$param" == "--no-virtualbox" ] ; then - no_virtualbox=1 + # if [ "$param" == "--no-git" ] ; then + # no_git=1 + # fi + if [ "$param" == "--no-alacritty" ] ; then + no_alacritty=1 fi - if [ "$param" == "--no-vagrant" ] ; then - no_vagrant=1 + # if [ "$param" == "--no-virtualbox" ] ; then + # no_virtualbox=1 + # fi + if [ "$param" == "--no-qemu" ] ; then + no_qemu=1 fi done if [ $no_devtools ]; then - no_xcode=1 + # no_xcode=1 no_vscode=1 no_gnused=1 no_git=1 @@ -46,18 +46,18 @@ fi echo "======================================= Setting up linuxdev host apps -git, item2, vscode, virtualbox, vagrant +git, alacritty, vscode, qemu =======================================" if [ -z "$no_confirm" ]; then echo -n "> Press enter to install or ^C to stop" read input fi -if [[ "$no_xcode" || $(xcode-select -p 1>/dev/null;echo $?) == "0" ]]; then - echo Skip installing xcode-select -else - xcode-select --install -fi +# if [[ "$no_xcode" || $(xcode-select -p 1>/dev/null;echo $?) == "0" ]]; then +# echo Skip installing xcode-select +# else +# xcode-select --install +# fi if brew -v ; then echo Skip installing brew @@ -66,19 +66,19 @@ else $SHELL -c "$brew_install_script" fi -# git -if [ -z "$no_git" ]; then -brew install git -fi +# # git +# if [ -z "$no_git" ]; then +# brew install git +# fi # gnu-sed if [ -z "$no_gnused" ]; then brew install gnu-sed fi -# iterm2 -if [ -z "$no_iterm2" ]; then -brew install --cask iterm2 +# alacritty +if [ -z "$no_alactritty" ]; then +brew install --cask alactritty fi # vscode @@ -86,13 +86,17 @@ if [ -z "$no_vscode" ]; then brew install --cask visual-studio-code fi -# virtualbox -if [ -z "$no_virtualbox" ]; then -brew install --cask virtualbox -fi +# # virtualbox +# if [ -z "$no_virtualbox" ]; then +# brew install --cask virtualbox +# fi -# vagrant -if [ -z "$no_vagrant" ]; then -brew install --cask vagrant -fi +# # vagrant +# if [ -z "$no_vagrant" ]; then +# brew install --cask vagrant +# fi +# qemu +if [ -z "$no_qemu" ]; then +brew install qemu +fi diff --git a/up.sh b/up.sh new file mode 100755 index 0000000..2088944 --- /dev/null +++ b/up.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ $(uname -s) == "Darwin" ]]; then + # Mac - QEMU 사용 + ./scripts/qemu.up.sh "$@" +else + # Windows - Vagrant 사용 + vagrant up +fi \ No newline at end of file