diff --git hosting.drush.inc hosting.drush.inc
index 00bbedc..093c4d4 100644
--- hosting.drush.inc
+++ hosting.drush.inc
@@ -26,6 +26,13 @@ function hosting_drush_command() {
     'description' => 'execute a specific queue item',
     'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL
   );
+
+  $items['hosting migrate'] = array('description' => 'migrate the frontend site', 'arguments' => array('example.com' => dt('The name of the site to migrate'), '/path/to/platform' => dt('The platform to migrate the site to.')));
+
+  $items['hosting park'] = array('description' => 'disable the frontend site prior to migration', 'arguments' => array('example.com' => dt('The name of the site to park')));
+
+  $items['hosting unpark'] = array('description' => 'enable the frontend site after a migration', 'arguments' => array('example.com' => dt('The name of the site to unpark')));
+
   return $items;
 }
 
diff --git hosting.inc hosting.inc
new file mode 100644
index 0000000..1050ac9
--- /dev/null
+++ hosting.inc
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ *
+ * General purpose functions
+ *
+ * Those functions are destined to be used by the frontend Drupal
+ * module as well as the drush hooks of the frontend
+ */
+
+/**
+ * Check if a hostname provided is an ip address
+ */
+function _hosting_valid_ip($hostname) {
+  //TODO : provide IPv6 support
+  $parts = explode('.', $hostname);
+  if (sizeof($parts) != 4) {
+    return false;
+  }
+  foreach ($parts as $part) {
+    if (((int) $part < 0) || ((int) $part > 255)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/**
+ * Check if the FQDN provided is valid.
+ */
+function _hosting_valid_fqdn($fqdn) {
+  # regex is an implementation of RFC1035
+  return preg_match("/^([a-z0-9]([a-z0-9-]*[a-z0-9])?\.?)+$/i", $fqdn);
+}
+
+function hosting_format_interval($ts) {
+  if ($ts==mktime()) { 
+    return t('Now');
+  }
+  if (!$ts) {
+    //Treats EPOCH as never
+    return t('Never');
+  }
+
+  return t("@interval ago", array("@interval" => format_interval(mktime() - $ts, 1)));
+}
+
+/**
+ * Make a path canonical
+ *
+ * This removes duplicate slashes, trailing slashes and /./ occurences. It does
+ * not (yet?) resolve .. instances.
+ */
+function hosting_path_normalize($path) {
+  return rtrim(preg_replace('/(\/\/*\.)?\/\/*/', '/', $path), '/');
+}
diff --git migrate.hosting.inc migrate.hosting.inc
new file mode 100644
index 0000000..4232e83
--- /dev/null
+++ migrate.hosting.inc
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file manual site migrate system
+ */
+
+function drush_hosting_hosting_migrate_validate($site, $platform) {
+  // verify the target platform:
+  $data = drush_get_merged_options(); // XXX: necessary because the remote
+                                      // platform may not have been
+                                      // initialised by the frontend (this
+                                      // should be checked instead)
+  $data['root'] = $platform;
+  $data['r'] = $platform;
+  drush_backend_invoke('provision verify', $data);
+  // verify the current platform
+  drush_backend_invoke('provision verify', array('root' => drush_get_option(array('r', 'root'), drush_locate_root())));
+  // verify the site prior to migration
+  drush_backend_invoke('provision verify', array($site));
+}
+
+function drush_hosting_pre_hosting_migrate($site, $platform) {
+  return drush_backend_invoke('hosting park', array($site, $platform));
+}
+
+function drush_hosting_hosting_migrate($site, $platform) { 
+  return drush_backend_invoke('provision clone', array($site, $site, $platform));
+}
+
+function drush_hosting_hosting_migrate_rollback($site, $platform) {
+  return drush_backend_invoke('provision delete', array($site, 'root' => $platform));
+}
+
+function drush_hosting_post_hosting_migrate($site, $platform) {
+  drush_backend_invoke('hosting unpark', array($site, $platform));
+  if (!drush_get_error()) {
+    drush_backend_invoke('provision delete', array($site));
+    drush_backend_invoke('provision verify', array($site, 'root' => $platform, 'publish_path' => $platform));
+  }
+}
diff --git park.hosting.inc park.hosting.inc
new file mode 100644
index 0000000..4230171
--- /dev/null
+++ park.hosting.inc
@@ -0,0 +1,28 @@
+<?php
+
+include_once('hosting.inc');
+
+/**
+ * Make sure that AEgir is ready to be parked
+ *
+ * @todo make sure no task is running
+ */
+function drush_hosting_hosting_park_validate($url, $platform) {
+  if ($platform_id = db_result(db_query('SELECT nid FROM {hosting_platform} WHERE publish_path = "%s"', hosting_path_normalize($platform)))) {
+    drush_log(dt('Platform found for path %path: #%id', array('%path' => $platform, '%id' => $platform_id)));
+  }
+  else {
+    return drush_set_error('PROVISION_FRAMEWORK_ERROR', dt("Cannot find target platform at @path before parking site. Make sure the platform exists in the frontend first.", array('@path' => $platform)));
+  }
+}
+
+/**
+ * TODO: prepare the site for migration
+ * - disable the queue (variable_set...)
+ * - disable the cronjob
+ * - create a failed migrate task for logging
+ * - disable the site
+ */
+function drush_hosting_hosting_park($url) {
+  
+}
diff --git unpark.hosting.inc unpark.hosting.inc
new file mode 100644
index 0000000..ee185ed
--- /dev/null
+++ unpark.hosting.inc
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file Implementation of the hosting unpark command
+ */
+
+include_once('hosting.inc');
+
+function drush_hosting_hosting_unpark($url, $platform) {
+  drush_log('bootstrapping drupal');
+  drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
+  drush_log('fixing platform');
+  if ($platform_id = db_result(db_query('SELECT nid FROM {hosting_platform} WHERE publish_path = "%s"', hosting_path_normalize($platform)))) {
+    $nid = db_result(db_query('SELECT nid FROM {node} WHERE type = "site" AND status = 1 AND title = "%s"', $url));
+    $node = node_load($nid);
+    $node->verified = 0;
+    $node->platform = $platform_id;
+    node_save($node);
+  } else {
+    return drush_set_error('PROVISION_FRAMEWORK_ERROR', dt("Could not find the node for platform path %platform", array('%platform' => $platform)));
+  }
+  // TODO: post migration tasks
+  // - turn on new cron job
+  // - save the drush log to the migrate task and set proper status
+}
