Skip to content
Permalink
Browse files

Add --last option to restore action

Since migrate upgrades the port command, it can't be used to
continue restoring the state which needs the newly installed
port command. Thus, broken into two stages asking the user to
run `port restore --last` immediately after migrate.

Also, add option to select a snapshot interactively on running
`port restore` which deactivates the currently active ports and
installs/activates the ports from selected snapshot.
  • Loading branch information
umeshksingla authored and neverpanic committed Oct 6, 2017
1 parent d205a99 commit f83d73e751f3ae7f245c01f1d1d34d97200f9da4
@@ -157,17 +157,17 @@ reg_snapshot* reg_snapshot_open(reg_registry* reg, sqlite_int64 id, reg_error* e
}

/**
* Lists all the existing snapshots in the registry for the user to choose
* Lists the existing snapshots in the registry for the user to choose
* from, for restore action
*
* @param [in] reg registry to search in
* @param [out] snapshots a list of snapshots
* @param [out] errPtr on error, a description of the error that occurred
* @return the number of snapshots if success; false if failure
*/
int reg_snapshot_list(reg_registry* reg, reg_snapshot*** snapshots, reg_error* errPtr) {
int reg_snapshot_list(reg_registry* reg, reg_snapshot*** snapshots, int limit, reg_error* errPtr) {
// Currently limiting to last 10 snapshots in the registry
int lower_bound = 10;
int lower_bound = limit;
char* query;
int result;
query = sqlite3_mprintf("SELECT id FROM registry.snapshots ORDER BY id DESC LIMIT %d",
@@ -69,7 +69,7 @@ reg_snapshot* reg_snapshot_open(reg_registry* reg, sqlite_int64 id,
reg_error* errPtr);
// list all snapshots
int reg_snapshot_list(reg_registry* reg, reg_snapshot*** snapshots,
reg_error* errPtr);
int limit, reg_error* errPtr);
// create snapshot method
reg_snapshot* reg_snapshot_create(reg_registry* reg, char* note,
reg_error* errPtr);
@@ -53,7 +53,7 @@ namespace eval migrate {
set id [$snapshot id]
set note [$snapshot note]
set datetime [$snapshot created_at]
ui_msg "Done: Snapshot '$id':'$note' created at $datetime"
ui_msg "Done: Snapshot '$id' : '$note' created at $datetime"

if {[info exists macports::ui_options(questions_yesno)]} {
set msg "Migration will first uninstall all the installed ports, upgrade MacPorts and then reinstall them again."
@@ -69,15 +69,13 @@ namespace eval migrate {
uninstall_installed

ui_msg "Upgrading MacPorts..."
upgrade_port_command

ui_msg "Fetching ports to install..."
set snapshot_portlist [$snapshot ports]

ui_msg "Restoring the original state..."
restore::restore_state $snapshot_portlist
if {[catch {upgrade_port_command} result]} {
ui_debug $::errorInfo
ui_msg "Upgrading port command failed. Try running 'sudo port -v selfupdate' and then, 'sudo port restore --last'"
return 1
}

# TODO: CLEAN PARTIAL BUILDS STEP HERE
ui_msg "You need to run 'port restore --last' to complete the migration."
return 0
}

@@ -36,33 +36,52 @@ package require snapshot 1.0

namespace eval restore {
proc main {opts} {
# The main function. If the action is provided a snapshot id, then it deactivates
# all the current ports and restores the specified snapshot.
#
# If '--last', then it assumes that this is a continution step of migration and
# no need of deactivating, since no ports exist. It simply sorts and installs the
# last snapshot ports
#
# If none, then it lists the last k (or all) snapshots with id for the user to
# choose from. Deactivates and installs the selected snapshot.
#
# Args:
# opts - options array.
# Returns:
# 0 if success

array set options $opts

if ([info exists options(ports_restore_snapshot-id)]) {
# use that snapshot
if {[info exists options(ports_restore_snapshot-id)]} {
# use the specified snapshot
set snapshot [fetch_snapshot $options(ports_restore_snapshot-id)]
puts $snapshot
puts [$snapshot id]
puts [$snapshot note]
puts [$snapshot created_at]
puts [$snapshot ports]
ui_msg "Deactivating all ports installed.."
deactivate_all
} elseif {[info exists options(ports_restore_last)]} {
set snapshot [fetch_snapshot_last]
} else {
set list [list_snapshots]
foreach l $list {
puts "[$l id] : [$l note] [$l created_at]"
}
set retstring [$macports::ui_options(questions_singlechoice) "Select any one snapshot to restore:" "" $list]
set snapshot [lindex $list $retstring]

ui_msg "Deactivating all ports installed.."
deactivate_all
}

if {![check_port_command]} {
return -code error "OS platform mismatch"
}

ui_msg ":: Deactivating all ports installed.."
deactivate_all
ui_msg "Restoring snapshot '[$snapshot note]' created at [$snapshot created_at]"

ui_msg "Fetching ports to install..."
set snapshot_portlist [$snapshot ports]

ui_msg ":: Restoring the selected snapshot.."
ui_msg "Restoring the selected snapshot.."
restore_state [$snapshot ports]

return 0
}

proc check_port_command {} {
@@ -72,7 +91,7 @@ namespace eval restore {
set os_major [lindex [split $os_version .] 0]
set os_platform [string tolower $tcl_platform(os)]

# Check that the current pla tform is the one we were configured for, otherwise need to do migration
# Check that the current platform is the one we were configured for, otherwise need to do migration
if {($os_platform ne $macports::autoconf::os_platform) || ($os_major != $macports::autoconf::os_major)} {
ui_error "Current platform \"$os_platform $os_major\" does not match expected platform \"$macports::autoconf::os_platform $macports::autoconf::os_major\""
ui_error "If you upgraded your OS or changed the hardware architecture, you need to run 'port migrate' instead."
@@ -85,6 +104,10 @@ namespace eval restore {
return [registry::snapshot get_by_id $snapshot_id]
}

proc fetch_snapshot_last {} {
return [registry::snapshot get_last]
}

proc list_snapshots {} {
return [registry::snapshot get_all]
}
@@ -2827,7 +2827,11 @@ proc action_reclaim { action portlist opts } {
}

proc action_snapshot { action portlist opts } {
return [macports::snapshot_main $opts]
if {[catch {macports::snapshot_main $opts} result]} {
ui_debug $::errorInfo
return 1
}
return 0
}

proc action_restore { action portlist opts } {
@@ -4482,7 +4486,7 @@ array set cmd_opts_array {
reclaim {enable-reminders disable-reminders}
fetch {no-mirrors}
snapshot {{note 1}}
restore {{snapshot-id 1}}
restore {{snapshot-id 1} last}
}

##
@@ -120,6 +120,38 @@ static int snapshot_get(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
}
}

/*
* registry::snaphot get_last
*/
static int snapshot_get_last(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]) {
reg_registry* reg = registry_for(interp, reg_attached);
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "get_last");
return TCL_ERROR;
} else if (reg == NULL) {
return TCL_ERROR;
} else {
reg_error error;
reg_snapshot** snapshots;
int limit = 1;
// 1 passed in reg_snapshot_list is to get the last '1' snapshot.
int snapshot_count = reg_snapshot_list(reg, &snapshots, limit, &error);
if (snapshot_count >= 0) {
int retval;
Tcl_Obj* result;
if (snapshot_to_obj(interp, &result, snapshots[0], NULL, &error)) {
Tcl_SetObjResult(interp, result);
retval = TCL_OK;
} else {
retval = registry_failed(interp, &error);
}
free(snapshots);
return retval;
}
return registry_failed(interp, &error);
}
}

/*
* registry::snaphot get_all
*/
@@ -133,7 +165,9 @@ static int snapshot_get_list(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]
} else {
reg_error error;
reg_snapshot** snapshots;
int snapshot_count = reg_snapshot_list(reg, &snapshots, &error);
int limit = 10;
// limit = k passed in reg_snapshot_list is to get the last 'k' snapshots
int snapshot_count = reg_snapshot_list(reg, &snapshots, limit, &error);
if (snapshot_count >= 0) {
int retval;
Tcl_Obj* result;
@@ -162,6 +196,7 @@ static snapshot_cmd_type snapshot_cmds[] = {
/* Global commands */
{ "create", snapshot_create},
{ "get_by_id", snapshot_get},
{ "get_last", snapshot_get_last},
{ "get_all", snapshot_get_list},
{ NULL, NULL }
};

0 comments on commit f83d73e

Please sign in to comment.
You can’t perform that action at this time.