void SG_pull__clone( SG_context* pCtx, const char* pszPullIntoRepoDescriptorName, SG_client* pClient) { sg_pull_instance_data* pMe = NULL; char* pszFragballName = NULL; const SG_pathname* pStagingPathname; SG_NULLARGCHECK_RETURN(pszPullIntoRepoDescriptorName); SG_NULLARGCHECK_RETURN(pClient); SG_ERR_CHECK( _pull_init(pCtx, pClient, pszPullIntoRepoDescriptorName, &pMe) ); SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname) ); /* Request a fragball containing the entire repo */ SG_ERR_CHECK( SG_client__pull_clone(pCtx, pClient, pStagingPathname, &pszFragballName) ); /* commit and cleanup */ SG_ERR_CHECK_RETURN( SG_staging__commit_fragball(pCtx, pMe->pStaging, pszFragballName) ); SG_ERR_CHECK( SG_context__msg__emit(pCtx, "Cleaning up...") ); SG_ERR_CHECK_RETURN( SG_staging__cleanup(pCtx, &pMe->pStaging) ); SG_ERR_CHECK( SG_context__msg__emit(pCtx, "done") ); /* fall through */ fail: _NULLFREE_INSTANCE_DATA(pCtx, pMe); SG_NULLFREE(pCtx, pszFragballName); SG_ERR_IGNORE( SG_context__msg__emit(pCtx, "\n") ); }
static void _add_dagnodes_until_connected(SG_context* pCtx, SG_vhash** ppvhStagingStatus, sg_pull_instance_data* pMe, SG_client* pClient) { SG_bool disconnected = SG_FALSE; SG_vhash* pvhFragballRequest = NULL; char* pszFragballName = NULL; SG_vhash* pvhRequestStatus = NULL; const SG_pathname* pStagingPathname; SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname) ); SG_ERR_CHECK( SG_vhash__has(pCtx, *ppvhStagingStatus, SG_SYNC_STATUS_KEY__DAGS, &disconnected) ); while (disconnected) { #if TRACE_PULL SG_ERR_CHECK( SG_vhash_debug__dump_to_console__named(pCtx, *ppvhStagingStatus, "pull staging status") ); #endif // There's at least one dag with connection problems. // Convert the staging status vhash into a fragball request vhash. pvhFragballRequest = *ppvhStagingStatus; *ppvhStagingStatus = NULL; SG_ERR_CHECK( SG_vhash__add__int64(pCtx, pvhFragballRequest, SG_SYNC_STATUS_KEY__GENERATIONS, GENERATIONS_PER_ROUNDTRIP) ); SG_ERR_CHECK( SG_client__pull_request_fragball(pCtx, pClient, pvhFragballRequest, pStagingPathname, &pszFragballName, &pvhRequestStatus) ); /* Ian TODO: inspect pvhRequestStatus */ SG_VHASH_NULLFREE(pCtx, pvhRequestStatus); SG_VHASH_NULLFREE(pCtx, pvhFragballRequest); SG_ERR_CHECK( SG_staging__slurp_fragball(pCtx, pMe->pStaging, (const char*)pszFragballName) ); SG_NULLFREE(pCtx, pszFragballName); SG_ERR_CHECK( SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, ppvhStagingStatus) ); SG_ERR_CHECK( SG_vhash__has(pCtx, *ppvhStagingStatus, SG_SYNC_STATUS_KEY__DAGS, &disconnected) ); #if TRACE_PULL SG_ERR_CHECK( SG_vhash_debug__dump_to_console__named(pCtx, *ppvhStagingStatus, "pull staging status") ); #endif } SG_ERR_CHECK_RETURN( SG_context__msg__emit(pCtx, "done") ); /* fall through */ fail: SG_VHASH_NULLFREE(pCtx, *ppvhStagingStatus); SG_VHASH_NULLFREE(pCtx, pvhFragballRequest); SG_NULLFREE(pCtx, pszFragballName); SG_VHASH_NULLFREE(pCtx, pvhRequestStatus); SG_ERR_IGNORE( SG_context__msg__emit(pCtx, "\n") ); }
static void _add_blobs_until_done(SG_context* pCtx, SG_staging* pStaging, SG_client* pClient) { SG_bool need_blobs = SG_FALSE; SG_vhash* pvhFragballRequest = NULL; char* pszFragballName = NULL; SG_vhash* pvhRequestStatus = NULL; const SG_pathname* pStagingPathname = NULL; SG_vhash* pvhStagingStatus = NULL; SG_ERR_CHECK_RETURN( SG_context__msg__emit(pCtx, "Retrieving blobs...") ); SG_ERR_CHECK( SG_staging__check_status(pCtx, pStaging, SG_FALSE, SG_FALSE, SG_FALSE, SG_TRUE, SG_TRUE, &pvhStagingStatus) ); SG_ERR_CHECK( SG_vhash__has(pCtx, pvhStagingStatus, SG_SYNC_STATUS_KEY__BLOBS, &need_blobs) ); if (need_blobs) SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pStaging, &pStagingPathname) ); while (need_blobs) { pvhFragballRequest = pvhStagingStatus; pvhStagingStatus = NULL; SG_ERR_CHECK( SG_client__pull_request_fragball(pCtx, pClient, pvhFragballRequest, pStagingPathname, &pszFragballName, &pvhRequestStatus) ); /* Ian TODO: inspect pvhRequestStatus */ SG_VHASH_NULLFREE(pCtx, pvhRequestStatus); SG_VHASH_NULLFREE(pCtx, pvhFragballRequest); SG_ERR_CHECK( SG_staging__slurp_fragball(pCtx, pStaging, (const char*)pszFragballName) ); SG_NULLFREE(pCtx, pszFragballName); SG_ERR_CHECK( SG_staging__check_status(pCtx, pStaging, SG_FALSE, SG_FALSE, SG_FALSE, SG_TRUE, SG_TRUE, &pvhStagingStatus) ); #if TRACE_PULL SG_ERR_CHECK( SG_vhash_debug__dump_to_console__named(pCtx, pvhStagingStatus, "pull staging status") ); #endif SG_ERR_CHECK( SG_vhash__has(pCtx, pvhStagingStatus, SG_SYNC_STATUS_KEY__BLOBS, &need_blobs) ); } SG_ERR_CHECK_RETURN( SG_context__msg__emit(pCtx, "done") ); /* fall through */ fail: SG_VHASH_NULLFREE(pCtx, pvhStagingStatus); SG_VHASH_NULLFREE(pCtx, pvhFragballRequest); SG_NULLFREE(pCtx, pszFragballName); SG_VHASH_NULLFREE(pCtx, pvhRequestStatus); SG_ERR_IGNORE( SG_context__msg__emit(pCtx, "\n") ); }
void SG_pull__all__list_incoming( SG_context* pCtx, const char* pszPullIntoRepoDescriptorName, SG_client* pClient, SG_varray** ppvaInfo) { sg_pull_instance_data* pMe = NULL; char* pszFragballName = NULL; SG_vhash* pvhStatus = NULL; // Used for both fragball request status returned by SG_client // and staging status returned by SG_staging. const SG_pathname* pStagingPathname; SG_NULLARGCHECK_RETURN(pszPullIntoRepoDescriptorName); SG_NULLARGCHECK_RETURN(pClient); SG_ERR_CHECK( _pull_init(pCtx, pClient, pszPullIntoRepoDescriptorName, &pMe) ); SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname) ); /* Request a fragball containing leaves of every dag */ SG_ERR_CHECK_RETURN( SG_context__msg__emit(pCtx, "Retrieving dagnodes...") ); SG_ERR_CHECK( SG_client__pull_request_fragball(pCtx, pClient, NULL, pStagingPathname, &pszFragballName, &pvhStatus) ); /* Ian TODO: inspect pvhStatus */ SG_ERR_CHECK( SG_VHASH_NULLFREE(pCtx, pvhStatus) ); SG_ERR_CHECK( SG_staging__slurp_fragball(pCtx, pMe->pStaging, pszFragballName) ); SG_ERR_CHECK( SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, &pvhStatus) ); /* Check the status and use it to request more dagnodes until the dags connect */ SG_ERR_CHECK( _add_dagnodes_until_connected(pCtx, &pvhStatus, pMe, pClient) ); SG_ERR_CHECK( SG_VHASH_NULLFREE(pCtx, pvhStatus) ); SG_ERR_CHECK( SG_staging__check_status(pCtx, pMe->pStaging, SG_FALSE, SG_FALSE, SG_TRUE, SG_FALSE, SG_FALSE, &pvhStatus) ); { SG_bool b = SG_FALSE; SG_vhash* pvhRequest = NULL; SG_ERR_CHECK( SG_vhash__has(pCtx, pvhStatus, SG_SYNC_STATUS_KEY__NEW_NODES, &b) ); if (b) { /* There are incoming nodes. Get their info. */ SG_ERR_CHECK( SG_vhash__get__vhash(pCtx, pvhStatus, SG_SYNC_STATUS_KEY__NEW_NODES, &pvhRequest) ); SG_ERR_CHECK( SG_client__get_dagnode_info(pCtx, pClient, pvhRequest, ppvaInfo) ); } } /* fall through */ fail: _NULLFREE_INSTANCE_DATA(pCtx, pMe); SG_VHASH_NULLFREE(pCtx, pvhStatus); SG_NULLFREE(pCtx, pszFragballName); }
void SG_server__push_get_staging_path(SG_context* pCtx, SG_server* pServer, const char* pPushId, SG_pathname** ppStagingPathname) { SG_staging* pStaging = NULL; const SG_pathname* pStagingPathname = NULL; SG_NULLARGCHECK_RETURN(pServer); SG_NULLARGCHECK_RETURN(ppStagingPathname); SG_ERR_CHECK( SG_staging__open(pCtx, pPushId, &pStaging) ); SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pStaging, &pStagingPathname) ); SG_ERR_CHECK( SG_pathname__alloc__copy(pCtx, ppStagingPathname, pStagingPathname) ); /* fall through */ fail: SG_STAGING_NULLFREE(pCtx, pStaging); }
void SG_pull__commit( SG_context* pCtx, SG_pull** ppPull, SG_varray** ppvaZingErr, SG_varray** ppvaZingLog) { _sg_pull* pMyPull = NULL; sg_pull_instance_data* pMe = NULL; SG_vhash* pvhStatus = NULL; char* pszFragballName = NULL; const SG_pathname* pStagingPathname; SG_NULL_PP_CHECK_RETURN(ppPull); pMyPull = (_sg_pull*)*ppPull; pMe = pMyPull->pPullInstance; SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname) ); SG_ERR_CHECK_RETURN( SG_context__msg__emit(pCtx, "Retrieving dagnodes...") ); SG_ERR_CHECK( SG_client__pull_request_fragball(pCtx, pMyPull->pClient, pMyPull->pvhFragballRequest, pStagingPathname, &pszFragballName, &pvhStatus) ); #if TRACE_PULL SG_ERR_CHECK( SG_vhash_debug__dump_to_console__named(pCtx, pvhStatus, "pull staging status") ); #endif /* Ian TODO: check status of pull request */ SG_ERR_CHECK( SG_VHASH_NULLFREE(pCtx, pvhStatus) ); SG_ERR_CHECK( SG_staging__slurp_fragball(pCtx, pMe->pStaging, pszFragballName) ); SG_ERR_CHECK( SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, &pvhStatus) ); /* Finish the pull using the status data we got back. */ SG_ERR_CHECK( _pull_common(pCtx, pMyPull->pClient, &pvhStatus, pMe, ppvaZingErr, ppvaZingLog) ); /* fall through */ fail: SG_ERR_IGNORE( _sg_pull__nullfree(pCtx, (_sg_pull**)ppPull) ); SG_VHASH_NULLFREE(pCtx, pvhStatus); SG_NULLFREE(pCtx, pszFragballName); }
void SG_pull__all(SG_context* pCtx, const char* pszPullIntoRepoDescriptorName, SG_client* pClient, SG_varray** ppvaErr, SG_varray** ppvaLog) { sg_pull_instance_data* pMe = NULL; char* pszFragballName = NULL; SG_vhash* pvhStatus = NULL; // Used for both fragball request status returned by SG_client // and staging status returned by SG_staging. const SG_pathname* pStagingPathname; SG_NULLARGCHECK_RETURN(pszPullIntoRepoDescriptorName); SG_NULLARGCHECK_RETURN(pClient); SG_ERR_CHECK( _pull_init(pCtx, pClient, pszPullIntoRepoDescriptorName, &pMe) ); SG_ERR_CHECK( SG_staging__get_pathname(pCtx, pMe->pStaging, &pStagingPathname) ); /* Request a fragball containing leaves of every dag */ SG_ERR_CHECK_RETURN( SG_context__msg__emit(pCtx, "Retrieving dagnodes...") ); SG_ERR_CHECK( SG_client__pull_request_fragball(pCtx, pClient, NULL, pStagingPathname, &pszFragballName, &pvhStatus) ); /* Ian TODO: inspect pvhStatus */ SG_ERR_CHECK( SG_VHASH_NULLFREE(pCtx, pvhStatus) ); SG_ERR_CHECK( SG_staging__slurp_fragball(pCtx, pMe->pStaging, pszFragballName) ); SG_ERR_CHECK( SG_staging__check_status(pCtx, pMe->pStaging, SG_TRUE, SG_FALSE, SG_FALSE, SG_FALSE, SG_FALSE, &pvhStatus) ); /* Finish the pull using the status data we got back. */ SG_ERR_CHECK( _pull_common(pCtx, pClient, &pvhStatus, pMe, ppvaErr, ppvaLog) ); /* fall through */ fail: _NULLFREE_INSTANCE_DATA(pCtx, pMe); SG_VHASH_NULLFREE(pCtx, pvhStatus); SG_NULLFREE(pCtx, pszFragballName); }
void SG_sync_remote__get_staging_path(SG_context* pCtx, const char* pszPushId, SG_pathname** ppStagingPathname) { SG_NULLARGCHECK_RETURN(ppStagingPathname); SG_ERR_CHECK_RETURN( SG_staging__get_pathname(pCtx, pszPushId, ppStagingPathname) ); }