mirror of
				https://github.com/j-a-n/raspberrymatic-addon-rmupdate.git
				synced 2023-10-10 11:37:40 +00:00 
			
		
		
		
	-
This commit is contained in:
		@@ -70,6 +70,16 @@ proc ::rmupdate::get_partion_start_and_size {device partition} {
 | 
			
		||||
	return [list -1 -1]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
proc ::rmupdate::is_system_upgradeable {} {
 | 
			
		||||
	set ret [get_filesystem_size_and_usage "/"]
 | 
			
		||||
	set size [lindex $ret 0]
 | 
			
		||||
	set used [lindex $ret 1]
 | 
			
		||||
	if { [expr {$used*1.5}] > $size && [expr {$used+50*1024*1024}] >= $size } {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
proc ::rmupdate::mount_image_partition {image partition mountpoint} {
 | 
			
		||||
	variable loop_dev
 | 
			
		||||
	variable sys_dev
 | 
			
		||||
@@ -337,7 +347,12 @@ proc ::rmupdate::install_process_running {} {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
proc ::rmupdate::install_firmware_version {version} {
 | 
			
		||||
proc ::rmupdate::delete_firmware_image {version} {
 | 
			
		||||
	variable img_dir
 | 
			
		||||
	eval {file delete [glob "${img_dir}/*${version}.img"]}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
proc ::rmupdate::install_firmware_version {version {reboot 1}} {
 | 
			
		||||
	if {[rmupdate::install_process_running]} {
 | 
			
		||||
		error "Another install process is running."
 | 
			
		||||
	}
 | 
			
		||||
@@ -369,6 +384,11 @@ proc ::rmupdate::install_firmware_version {version} {
 | 
			
		||||
	update_filesystems $firmware_image
 | 
			
		||||
	
 | 
			
		||||
	file delete $install_lock
 | 
			
		||||
	
 | 
			
		||||
	if {$reboot} {
 | 
			
		||||
		write_log "Rebooting system."
 | 
			
		||||
		exec /sbin/reboot -f
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#puts [rmupdate::get_latest_firmware_version]
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
	<title>RaspberryMatic Update Addon</title>
 | 
			
		||||
	<script>
 | 
			
		||||
		var message_timer_id = null;
 | 
			
		||||
		var install_running = false;
 | 
			
		||||
		var installation_running = "";
 | 
			
		||||
		var current_firmware = '?';
 | 
			
		||||
		var latest_firmware = '?';
 | 
			
		||||
		
 | 
			
		||||
		function display_message(type, html, millis) {
 | 
			
		||||
			clear_message();
 | 
			
		||||
@@ -86,58 +88,123 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
				$('#log-content').html(data.replace(/\n/g, '<br />'));
 | 
			
		||||
				$('#modal-log').modal('refresh');
 | 
			
		||||
				$('#log-content').scrollTop($('#log-content').prop("scrollHeight"));
 | 
			
		||||
				if (install_running) {
 | 
			
		||||
				if (installation_running) {
 | 
			
		||||
					setTimeout(update_install_log, 1000);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		function delete_firmware_image(version) {
 | 
			
		||||
			rest("POST", "/delete_firmware_image", JSON.stringify({"version":version}),
 | 
			
		||||
				function(data) {
 | 
			
		||||
					display_message('success', 'Firmware image ' + version + ' successfully deleted.', 5000);
 | 
			
		||||
					get_firmware_info();
 | 
			
		||||
				}
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		function install_firmware(version) {
 | 
			
		||||
			display_message('info', 'Installing firmware ' + version + '.', 6000000);
 | 
			
		||||
			install_running = true;
 | 
			
		||||
			clear_message();
 | 
			
		||||
			$('#log-content').html('');
 | 
			
		||||
			$('#modal-log').modal('show');
 | 
			
		||||
			rest("POST", "/start_install_firmware", version,
 | 
			
		||||
			if (installation_running) {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			installation_running = version;
 | 
			
		||||
			$('[data-install-version="' + installation_running + '"]').addClass('loading');
 | 
			
		||||
			var reboot = $('#reboot-after-install').is(':checked');
 | 
			
		||||
			display_message('info', 'Installing firmware ' + version + '.', 6000000);
 | 
			
		||||
			clear_message();
 | 
			
		||||
			rest("POST", "/start_install_firmware", JSON.stringify({"version":version, "reboot":reboot}),
 | 
			
		||||
				function(data) {
 | 
			
		||||
					install_running = false;
 | 
			
		||||
					$('[data-install-version="' + installation_running + '"]').removeClass('loading');
 | 
			
		||||
					installation_running = "";
 | 
			
		||||
					display_message('success', 'Firmware ' + version + ' successfully installed.', 6000000);
 | 
			
		||||
					if (!reboot) {
 | 
			
		||||
						get_firmware_info();
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
				function(xhr, ajaxOptions, thrownError) {
 | 
			
		||||
					install_running = false;
 | 
			
		||||
					$('[data-install-version="' + installation_running + '"]').removeClass('loading');
 | 
			
		||||
					installation_running = "";
 | 
			
		||||
					//$('#modal-log').modal('hide');
 | 
			
		||||
					default_error_callback(xhr, ajaxOptions, thrownError);
 | 
			
		||||
					if (!reboot) {
 | 
			
		||||
						get_firmware_info();
 | 
			
		||||
						default_error_callback(xhr, ajaxOptions, thrownError);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			);
 | 
			
		||||
			setTimeout(update_install_log, 1000);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		function install_latest_firmware() {
 | 
			
		||||
			if (latest_firmware && latest_firmware != '?') {
 | 
			
		||||
				install_firmware(latest_firmware);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		function get_firmware_info() {
 | 
			
		||||
			rest("GET", "/get_firmware_info", null, function(data) {
 | 
			
		||||
				$('#firmware_info tbody').empty();
 | 
			
		||||
				data.forEach(function(fw) {
 | 
			
		||||
					if (fw.latest) latest_firmware = fw.version;
 | 
			
		||||
					if (fw.installed) current_firmware = fw.version;
 | 
			
		||||
					var color = 'yellow';
 | 
			
		||||
					if (fw.latest) color = 'green';
 | 
			
		||||
					if (fw.installed) color = 'gray';
 | 
			
		||||
					var disabled = (fw.image || fw.url ? '' : 'disabled');
 | 
			
		||||
					var binstall = $('<div class="ui '+ color +' basic '+ disabled +' button">').attr('data-install-version', fw.version).append($('<i class="sign in icon">'), 'install');
 | 
			
		||||
					binstall.click(function() {
 | 
			
		||||
						install_firmware(this.getAttribute('data-install-version'));
 | 
			
		||||
					});
 | 
			
		||||
					var bcls = '';
 | 
			
		||||
					if (!fw.image) bcls = 'disabled';
 | 
			
		||||
					if (fw.version == installation_running) bcls = 'loading';
 | 
			
		||||
					var bdelete = $('<div class="ui orange basic '+ bcls +' button">').attr('data-delete-version', fw.version).append($('<i class="delete icon">'), 'delete download');
 | 
			
		||||
					bdelete.click(function() {
 | 
			
		||||
						delete_firmware_image(this.getAttribute('data-delete-version'));
 | 
			
		||||
					});
 | 
			
		||||
					
 | 
			
		||||
					var available = (fw.url ? 'checked=""' : '')
 | 
			
		||||
					var downloaded = (fw.image ? 'checked=""' : '')
 | 
			
		||||
					var cls = '';
 | 
			
		||||
					if (fw.installed) cls = ' class="warning"';
 | 
			
		||||
					if (fw.latest) cls = ' class="positive"';
 | 
			
		||||
					$("#firmware_info tbody").append($('<tr' + cls + '>').append(
 | 
			
		||||
						$('<td>').text(fw.version),
 | 
			
		||||
						$('<td class="center aligned">').append($('<div class="ui disabled checkbox">').append($('<input type="checkbox" disabled="disabled" '+available+'>'),$('<label></label>'))),
 | 
			
		||||
						$('<td class="center aligned">').append($('<div class="ui disabled checkbox">').append($('<input type="checkbox" disabled="disabled" '+downloaded+'>'),$('<label></label>'))),
 | 
			
		||||
						$('<td class="center aligned">').append(bdelete, binstall)
 | 
			
		||||
					));
 | 
			
		||||
				});
 | 
			
		||||
				var color = "#d01919";
 | 
			
		||||
				if (current_firmware == latest_firmware) {
 | 
			
		||||
					color = "#21BA45";
 | 
			
		||||
				}
 | 
			
		||||
				$("#firmware-summary").empty();
 | 
			
		||||
				$("#firmware-summary").append(
 | 
			
		||||
					$('<div class="sub header">').html('Current installed version: <span style="color:'+ color +'">' + current_firmware + '</span>'),
 | 
			
		||||
					$('<div class="sub header">').html('Latest avaialable version: ' + latest_firmware)
 | 
			
		||||
				);
 | 
			
		||||
				if (current_firmware != latest_firmware) {
 | 
			
		||||
					$("#firmware-summary").append(
 | 
			
		||||
						$('<div class="ui green basic button" style="margin-top:20px; margin-bottom:20px;">').click(install_latest_firmware).append($('<i class="sign in icon">'), 'Install latest firmware')
 | 
			
		||||
					);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		$(document).ready(function() {
 | 
			
		||||
			rest("GET", "/version", null, function(version) {
 | 
			
		||||
				document.title = document.title + " " + version;
 | 
			
		||||
			});
 | 
			
		||||
			rest("GET", "/get_firmware_info", null, function(data) {
 | 
			
		||||
				$('#firmware_info tbody').empty();
 | 
			
		||||
				data.forEach(function(fw) {
 | 
			
		||||
					var disabled = (fw.image || fw.url ? '' : 'disabled');
 | 
			
		||||
					var binstall = $('<button class="ui green basic '+disabled+' button">').attr('data-version', fw.version).text('install');
 | 
			
		||||
					binstall.click(function() {
 | 
			
		||||
						install_firmware(this.getAttribute('data-version'));
 | 
			
		||||
					});
 | 
			
		||||
					var latest = (fw.latest ? 'checked=""' : '')
 | 
			
		||||
					var installed = (fw.installed ? 'checked=""' : '')
 | 
			
		||||
					var available = (fw.url ? 'checked=""' : '')
 | 
			
		||||
					var downloaded = (fw.image ? 'checked=""' : '')
 | 
			
		||||
					$("#firmware_info tbody").append($('<tr>').append(
 | 
			
		||||
						$('<td>').text(fw.version),
 | 
			
		||||
						$('<td class="center aligned">').append($('<div class="ui disabled checkbox">').append($('<input type="checkbox" disabled="disabled" '+latest+'>'),$('<label></label>'))),
 | 
			
		||||
						$('<td class="center aligned">').append($('<div class="ui disabled checkbox">').append($('<input type="checkbox" disabled="disabled" '+installed+'>'),$('<label></label>'))),
 | 
			
		||||
						$('<td class="center aligned">').append($('<div class="ui disabled checkbox">').append($('<input type="checkbox" disabled="disabled" '+available+'>'),$('<label></label>'))),
 | 
			
		||||
						$('<td class="center aligned">').append($('<div class="ui disabled checkbox">').append($('<input type="checkbox" disabled="disabled" '+downloaded+'>'),$('<label></label>'))),
 | 
			
		||||
						$('<td class="center aligned">').append(binstall)
 | 
			
		||||
					));
 | 
			
		||||
				});
 | 
			
		||||
			rest("GET", "/is_system_upgradeable", null, function(upgradeable) {
 | 
			
		||||
				if (!upgradeable) {
 | 
			
		||||
					var message = 'Filesystems to small, system not upgradeable!<br />';
 | 
			
		||||
					message += 'Please download and install adapted <a href="https://github.com/j-a-n/raspberrymatic-addon-rmupdate">RaspMatic image</a> first.';
 | 
			
		||||
					display_message('error', message, 6000000);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
			get_firmware_info();
 | 
			
		||||
		});
 | 
			
		||||
	</script>
 | 
			
		||||
</head>
 | 
			
		||||
@@ -147,12 +214,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
		<div id="message" class="ui message hidden">
 | 
			
		||||
		</div>
 | 
			
		||||
		<h2 class="ui dividing header">Firmwares</h2>
 | 
			
		||||
		<div class="content" id="firmware-summary">
 | 
			
		||||
		</div>
 | 
			
		||||
		<table id="firmware_info" class="ui celled stackable table">
 | 
			
		||||
			<thead>
 | 
			
		||||
				<tr>
 | 
			
		||||
					<th>Version</th>
 | 
			
		||||
					<th class="center aligned">Latest</th>
 | 
			
		||||
					<th class="center aligned">Installed</th>
 | 
			
		||||
					<th class="center aligned">Available</th>
 | 
			
		||||
					<th class="center aligned">Downloaded</th>
 | 
			
		||||
					<th class="center aligned">Action</th>
 | 
			
		||||
@@ -161,12 +228,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
			<tbody>
 | 
			
		||||
			</tbody>
 | 
			
		||||
		</table>
 | 
			
		||||
		<div class="ui checkbox">
 | 
			
		||||
			<input id="reboot-after-install" type="checkbox" checked="checked">
 | 
			
		||||
			<label>Reboot system after installation</label>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	
 | 
			
		||||
	<div style="height:80%" id="modal-log" class="ui modal">
 | 
			
		||||
		<i class="close icon"></i>
 | 
			
		||||
		<div class="header">
 | 
			
		||||
			Progress
 | 
			
		||||
			Installation log
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="content">
 | 
			
		||||
			<div id="message-log" class="ui message hidden">
 | 
			
		||||
 
 | 
			
		||||
@@ -48,13 +48,34 @@ proc process {} {
 | 
			
		||||
		} elseif {[lindex $path 1] == "get_firmware_info"} {
 | 
			
		||||
			return [rmupdate::get_firmware_info]
 | 
			
		||||
		} elseif {[lindex $path 1] == "start_install_firmware"} {
 | 
			
		||||
			regexp {^([\d\.]+)$} $data match version
 | 
			
		||||
			regexp {\"version\"\s*:\s*\"([\d\.]+)\"} $data match version
 | 
			
		||||
			regexp {\"reboot\"\s*:\s*(true|false)} $data match reboot
 | 
			
		||||
			if { [info exists version] && $version != "" } {
 | 
			
		||||
				rmupdate::install_firmware_version $version
 | 
			
		||||
				return "\"done\""
 | 
			
		||||
				if { ![info exists reboot] } {
 | 
			
		||||
					set reboot "true"
 | 
			
		||||
				}
 | 
			
		||||
				if {$reboot == "true"} {
 | 
			
		||||
					set reboot 1
 | 
			
		||||
				} else {
 | 
			
		||||
					set reboot 0
 | 
			
		||||
				}
 | 
			
		||||
				return "\"[rmupdate::install_firmware_version $version $reboot]\""
 | 
			
		||||
			} else {
 | 
			
		||||
				error "Invalid version: ${data}"
 | 
			
		||||
			}
 | 
			
		||||
		} elseif {[lindex $path 1] == "delete_firmware_image"} {
 | 
			
		||||
			regexp {\"version\"\s*:\s*\"([\d\.]+)\"} $data match version
 | 
			
		||||
			if { [info exists version] && $version != "" } {
 | 
			
		||||
				return "\"[rmupdate::delete_firmware_image $version]\""
 | 
			
		||||
			} else {
 | 
			
		||||
				error "Invalid version: ${data}"
 | 
			
		||||
			}
 | 
			
		||||
		} elseif {[lindex $path 1] == "is_system_upgradeable"} {
 | 
			
		||||
			if {[rmupdate::is_system_upgradeable]} {
 | 
			
		||||
				return "true"
 | 
			
		||||
			} else {
 | 
			
		||||
				return "false"
 | 
			
		||||
			}
 | 
			
		||||
		} elseif {[lindex $path 1] == "read_install_log"} {
 | 
			
		||||
			variable content_type "text/html"
 | 
			
		||||
			return [rmupdate::read_install_log]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								resize_image.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										64
									
								
								resize_image.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
#!/bin/bash -e
 | 
			
		||||
 | 
			
		||||
LOOP_DEV=4
 | 
			
		||||
BOOT_SIZE=$((50*1024*1024))
 | 
			
		||||
ROOT_SIZE=$((1000*1024*1024))
 | 
			
		||||
USR_LOCAL_SIZE=$((2*1024*1024))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if [[ $EUID -ne 0 ]]; then
 | 
			
		||||
	echo "This script must be run as root." 1>&2
 | 
			
		||||
	exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
image_file="$1"
 | 
			
		||||
new_image_file="$1.resized"
 | 
			
		||||
 | 
			
		||||
echo "*** Creating new image file and partitions ***"
 | 
			
		||||
dd if=/dev/zero of=$new_image_file bs=1M count=$((((${BOOT_SIZE}+${ROOT_SIZE}+${USR_LOCAL_SIZE})/1024/1024)+1))
 | 
			
		||||
parted --script $new_image_file \
 | 
			
		||||
	mklabel msdos \
 | 
			
		||||
	mkpart primary fat16 512B ${BOOT_SIZE}B \
 | 
			
		||||
	set 1 boot on \
 | 
			
		||||
	mkpart primary ext4 $((512+${BOOT_SIZE}))B $((${BOOT_SIZE}+${ROOT_SIZE}))B \
 | 
			
		||||
	mkpart primary ext4 $((512+${BOOT_SIZE}+${ROOT_SIZE}))B 100%
 | 
			
		||||
 | 
			
		||||
echo "*** Copying original partitons ***"
 | 
			
		||||
oIFS="$IFS"
 | 
			
		||||
IFS=$'\n'
 | 
			
		||||
for line in $(parted $image_file unit B print | grep primary); do
 | 
			
		||||
	IFS=$oIFS
 | 
			
		||||
	x=($line)
 | 
			
		||||
	num=${x[0]}
 | 
			
		||||
	start=$((${x[1]:0: -1}/512))
 | 
			
		||||
	size=$((${x[3]:0: -1}/512))
 | 
			
		||||
	echo $num - $start - $size
 | 
			
		||||
	seek=0
 | 
			
		||||
	[ "$num" = "1" ] && seek=$start
 | 
			
		||||
	[ "$num" = "2" ] && seek=$(((512+${BOOT_SIZE})/512))
 | 
			
		||||
	[ "$num" = "3" ] && seek=$(((512+${BOOT_SIZE}+${ROOT_SIZE})/512))
 | 
			
		||||
	dd if=$image_file of=$new_image_file bs=512 skip=$start count=$size seek=$seek conv=notrunc
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
echo "*** Resizing filesystems ***"
 | 
			
		||||
rm /dev/mapper/loop${LOOP_DEV}p 2>/dev/null || true
 | 
			
		||||
kpartx -d /dev/loop${LOOP_DEV} 2>/dev/null || true
 | 
			
		||||
losetup -d /dev/loop${LOOP_DEV} 2>/dev/null || true
 | 
			
		||||
 | 
			
		||||
losetup /dev/loop${LOOP_DEV} $new_image_file
 | 
			
		||||
kpartx -a /dev/loop${LOOP_DEV}
 | 
			
		||||
ln -s /dev/loop${LOOP_DEV} /dev/mapper/loop${LOOP_DEV}p
 | 
			
		||||
 | 
			
		||||
fsck.vfat -a /dev/mapper/loop${LOOP_DEV}p1
 | 
			
		||||
fatresize --size $BOOT_SIZE /dev/mapper/loop${LOOP_DEV}p1
 | 
			
		||||
fsck.ext4 -f -y /dev/mapper/loop${LOOP_DEV}p2
 | 
			
		||||
resize2fs /dev/mapper/loop${LOOP_DEV}p2
 | 
			
		||||
fsck.ext4 -f -y /dev/mapper/loop${LOOP_DEV}p3
 | 
			
		||||
resize2fs /dev/mapper/loop${LOOP_DEV}p3
 | 
			
		||||
 | 
			
		||||
rm /dev/mapper/loop${LOOP_DEV}p
 | 
			
		||||
kpartx -d /dev/loop${LOOP_DEV}
 | 
			
		||||
losetup -d /dev/loop${LOOP_DEV}
 | 
			
		||||
 | 
			
		||||
echo "*** Resized image successfully created ***"
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user