Fossil

Check-in [42a6191e93]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Record sync operations in the new synclog table.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | synclog
Files: files | file ages | folders
SHA3-256: 42a6191e9366a2f156123e41b5b4f5d3e83c0e3d094056054b99ec0eae227dc0
User & Date: drh 2021-12-19 17:50:20.974
Context
2021-12-19
18:10
Add the "E" and "F" capability letters to control reading and writing to the synclog. check-in: 06b3ace4ce user: drh tags: synclog
17:50
Record sync operations in the new synclog table. check-in: 42a6191e93 user: drh tags: synclog
2021-12-18
19:38
Add --chroot option to the 'http' and 'server' commands. check-in: bf6be1e325 user: mistachkin tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/export.c.
1368
1369
1370
1371
1372
1373
1374

1375
1376
1377
1378
1379
1380
1381
** Implementation of the "fossil git export" command.
*/
void gitmirror_export_command(void){
  const char *zLimit;             /* Text of the --limit flag */
  int nLimit = 0x7fffffff;        /* Numeric value of the --limit flag */
  int nTotal = 0;                 /* Total number of check-ins to export */
  char *zMirror;                  /* Name of the mirror */

  char *z;                        /* Generic string */
  char *zCmd;                     /* git command to run as a subprocess */
  const char *zDebug = 0;         /* Value of the --debug flag */
  const char *zAutoPush = 0;      /* Value of the --autopush flag */
  char *zMainBr = 0;              /* Value of the --mainbranch flag */
  char *zPushUrl;                 /* URL to sync the mirror to */
  double rEnd;                    /* time of most recent export */







>







1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
** Implementation of the "fossil git export" command.
*/
void gitmirror_export_command(void){
  const char *zLimit;             /* Text of the --limit flag */
  int nLimit = 0x7fffffff;        /* Numeric value of the --limit flag */
  int nTotal = 0;                 /* Total number of check-ins to export */
  char *zMirror;                  /* Name of the mirror */
  char *zMirrorAbs;               /* Canonicalized name of the mirror */
  char *z;                        /* Generic string */
  char *zCmd;                     /* git command to run as a subprocess */
  const char *zDebug = 0;         /* Value of the --debug flag */
  const char *zAutoPush = 0;      /* Value of the --autopush flag */
  char *zMainBr = 0;              /* Value of the --mainbranch flag */
  char *zPushUrl;                 /* URL to sync the mirror to */
  double rEnd;                    /* time of most recent export */
1694
1695
1696
1697
1698
1699
1700





1701
1702
1703
1704
1705
1706
1707

  /* Maybe run a git repack */
  if( bNeedRepack ){
    const char *zRepack = "git repack -adf";
    gitmirror_message(VERB_NORMAL, "%s\n", zRepack);
    fossil_system(zRepack);
  }






  /* Optionally do a "git push" */
  zPushUrl = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
  if( zPushUrl ){
    char *zPushCmd;
    UrlData url;
    if( sqlite3_strglob("http*", zPushUrl)==0 ){







>
>
>
>
>







1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713

  /* Maybe run a git repack */
  if( bNeedRepack ){
    const char *zRepack = "git repack -adf";
    gitmirror_message(VERB_NORMAL, "%s\n", zRepack);
    fossil_system(zRepack);
  }

  /* Record this export into the sync log */
  zMirrorAbs = file_canonical_name_dup(zMirror);
  sync_log_entry(SYNC_PUSH, zMirrorAbs, "git");
  fossil_free(zMirrorAbs);

  /* Optionally do a "git push" */
  zPushUrl = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
  if( zPushUrl ){
    char *zPushCmd;
    UrlData url;
    if( sqlite3_strglob("http*", zPushUrl)==0 ){
1717
1718
1719
1720
1721
1722
1723

1724
1725
1726
1727
1728
1729
1730
    if( rc ){
      fossil_fatal("cannot push content using: %s", zPushCmd);
    }else if( db_is_writeable("repository") ){
      db_unprotect(PROTECT_CONFIG);
      db_multi_exec("REPLACE INTO config(name,value,mtime)"
                    "VALUES('gitpush:%q',1,now())", zPushUrl);
      db_protect_pop();

    }
    fossil_free(zPushCmd);
  }
}

/*
** Implementation of the "fossil git status" command.







>







1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
    if( rc ){
      fossil_fatal("cannot push content using: %s", zPushCmd);
    }else if( db_is_writeable("repository") ){
      db_unprotect(PROTECT_CONFIG);
      db_multi_exec("REPLACE INTO config(name,value,mtime)"
                    "VALUES('gitpush:%q',1,now())", zPushUrl);
      db_protect_pop();
      sync_log_entry(SYNC_PUSH, zPushUrl, "git-push");
    }
    fossil_free(zPushCmd);
  }
}

/*
** Implementation of the "fossil git status" command.
Changes to src/schema.c.
616
617
618
619
620
621
622

























/* Create the forum-post schema if it does not already exist */
void schema_forum(void){
  if( !db_table_exists("repository","forumpost") ){
    db_multi_exec("%s",zForumSchema/*safe-for-%s*/);
  }
}































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646

/* Create the forum-post schema if it does not already exist */
void schema_forum(void){
  if( !db_table_exists("repository","forumpost") ){
    db_multi_exec("%s",zForumSchema/*safe-for-%s*/);
  }
}

/*
** The following table holds information about servers with which
** this repository has synced, as well as servers with which those 
** servers have synced, and so forth.
*/
static const char zSynclogSchema[] =
@ CREATE TABLE repository.synclog(
@   sfrom TEXT,        -- Sync client. "self" means this repo
@   sto TEXT,          -- Sync server
@   spush DATETIME,    -- Time of last push (julian day)
@   spull DATETIME,    -- Time of last pull (julian day)
@   sdist INT,         -- Distance from this repo.  0 means self
@   stype TEXT,        -- Type of "sto". ex: "git","backup". NULL means fossil
@   PRIMARY KEY(sfrom,sto)
@ ) WITHOUT ROWID;
;

/* Create the forum-post schema if it does not already exist */
void schema_synclog(void){
  if( !db_table_exists("repository","synclog") ){
    db_multi_exec("%s",zSynclogSchema/*safe-for-%s*/);
  }
}
Changes to src/sync.c.
90
91
92
93
94
95
96











































97
98
99
100
101
102
103
    fossil_free(azOther[i]);
    azOther[i] = 0;
  }
  fossil_free(azOther);
  return nErr;
}













































/*
** If the repository is configured for autosyncing, then do an
** autosync.  Bits of the "flags" parameter determine details of behavior:
**
**   SYNC_PULL           Pull content from the server to the local repo
**   SYNC_PUSH           Push content from local up to the server







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
    fossil_free(azOther[i]);
    azOther[i] = 0;
  }
  fossil_free(azOther);
  return nErr;
}

/*
** Make a new entry, or update an existing entry, in the SYNCLOG table
** for a push or pull from this repository to another server named zRemote.
**
** For an ordinary push/pull, zType is NULL.  But it may also be a string
** describing non-standard operations.  For example zType might be "git"
** when doing a "fossil git export", or zType might be "import" when doing
** a "fossil pull --from-parent-project".
**
** For this routine, the sfrom value is always 'self'.  The sto value is
** the zRemote parameter.  sto+sfrom form the primary key.  If an entry
** already exists with the same primary key, then the spull or spush times
** are updated (or both).
*/
void sync_log_entry(
  int syncFlags,            /* Indicates whether a PUSH or PULL or both */
  const char *zRemote,      /* Server with which we push or pull */
  const char *zType         /* Type of sync.  NULL for normal */
){
  const char *zPush;
  const char *zPull;
  if( syncFlags & (SYNC_PULL|SYNC_CLONE) ){
    zPull = "julianday()";
  }else{
    zPull = "NULL";
  }
  if( syncFlags & (SYNC_PUSH) ){
    zPush = "julianday()";
  }else{
    zPush = "NULL";
  }
  schema_synclog();
  db_multi_exec(
    "INSERT INTO repository.synclog(sfrom,sto,spush,spull,sdist,stype)"
    " VALUES('self',%Q,%s,%s,0,%Q)"
    " ON CONFLICT DO UPDATE"
    "   SET spush=coalesce(%s,spush),"
    "       spull=coalesce(%s,spull);",
    zRemote, zPush/*safe-for-%s*/, zPull/*safe-for-%s*/, zType,
    zPush/*safe-for-%s*/, zPull/*safe-for-%s*/
  );
}


/*
** If the repository is configured for autosyncing, then do an
** autosync.  Bits of the "flags" parameter determine details of behavior:
**
**   SYNC_PULL           Pull content from the server to the local repo
**   SYNC_PUSH           Push content from local up to the server
680
681
682
683
684
685
686

687
688
689
690
691
692
693
**
**    --overwrite              OK to overwrite an existing file
**    -R NAME                  Filename of the repository to backup
*/
void backup_cmd(void){
  char *zDest;
  int bOverwrite = 0;

  db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
  bOverwrite = find_option("overwrite",0,0)!=0;
  verify_all_options();
  if( g.argc!=3 ){
    usage("FILE|DIRECTORY");
  }
  zDest = g.argv[2];







>







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
**
**    --overwrite              OK to overwrite an existing file
**    -R NAME                  Filename of the repository to backup
*/
void backup_cmd(void){
  char *zDest;
  int bOverwrite = 0;
  char *zFullName;
  db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
  bOverwrite = find_option("overwrite",0,0)!=0;
  verify_all_options();
  if( g.argc!=3 ){
    usage("FILE|DIRECTORY");
  }
  zDest = g.argv[2];
701
702
703
704
705
706
707



708
      }
    }else{
      fossil_fatal("backup \"%s\" already exists", zDest);
    }
  }
  db_unprotect(PROTECT_ALL);
  db_multi_exec("VACUUM repository INTO %Q", zDest);



}







>
>
>

745
746
747
748
749
750
751
752
753
754
755
      }
    }else{
      fossil_fatal("backup \"%s\" already exists", zDest);
    }
  }
  db_unprotect(PROTECT_ALL);
  db_multi_exec("VACUUM repository INTO %Q", zDest);
  zFullName = file_canonical_name_dup(zDest);
  sync_log_entry(SYNC_PUSH, zFullName, "backup");
  fossil_free(zFullName);
}
Changes to src/xfer.c.
1883
1884
1885
1886
1887
1888
1889
1890






1891
1892
1893
1894
1895
1896
1897
1898
1899
1900



1901
1902
1903
1904
1905
1906
1907
  int autopushFailed = 0; /* Autopush following commit failed if true */
  const char *zCkinLock;  /* Name of check-in to lock.  NULL for none */
  const char *zClientId;  /* A unique identifier for this check-out */
  unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */

  if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH;
  if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE|SYNC_UNVERSIONED))==0
     && configRcvMask==0 && configSendMask==0 ) return 0;






  if( syncFlags & SYNC_FROMPARENT ){
    configRcvMask = 0;
    configSendMask = 0;
    syncFlags &= ~(SYNC_PUSH);
    zPCode = db_get("parent-project-code", 0);
    if( zPCode==0 || db_get("parent-project-name",0)==0 ){
      fossil_fatal("there is no parent project: set the 'parent-project-code'"
                   " and 'parent-project-name' config parameters in order"
                   " to pull from a parent project");
    }



  }

  transport_stats(0, 0, 1);
  socket_global_init();
  memset(&xfer, 0, sizeof(xfer));
  xfer.pIn = &recv;
  xfer.pOut = &send;







|
>
>
>
>
>
>




|
|




>
>
>







1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
  int autopushFailed = 0; /* Autopush following commit failed if true */
  const char *zCkinLock;  /* Name of check-in to lock.  NULL for none */
  const char *zClientId;  /* A unique identifier for this check-out */
  unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */

  if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH;
  if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE|SYNC_UNVERSIONED))==0
     && configRcvMask==0 && configSendMask==0 ){
    return 0;
  }
  if( zPCode==0 && (syncFlags & SYNC_CLONE)==0 ){
    /* Every established repository must have a project-code */
    fossil_fatal("no project-code defined for this repository");
  }
  if( syncFlags & SYNC_FROMPARENT ){
    configRcvMask = 0;
    configSendMask = 0;
    syncFlags &= ~(SYNC_PUSH);
    zAltPCode = db_get("parent-project-code", 0);
    if( zAltPCode==0 || db_get("parent-project-name",0)==0 ){
      fossil_fatal("there is no parent project: set the 'parent-project-code'"
                   " and 'parent-project-name' config parameters in order"
                   " to pull from a parent project");
    }
  }
  if( zAltPCode!=0 && zPCode!=0 && sqlite3_stricmp(zPCode,zAltPCode)==0 ){
    zAltPCode = 0;
  }

  transport_stats(0, 0, 1);
  socket_global_init();
  memset(&xfer, 0, sizeof(xfer));
  xfer.pIn = &recv;
  xfer.pOut = &send;
2680
2681
2682
2683
2684
2685
2686




2687
2688
2689
2690
2691
2692
2693
                    db_timespan_name(rSkew));
     g.clockSkewSeen = 1;
  }else if( rSkew*24.0*3600.0 < -10.0 ){
     fossil_warning("*** time skew *** server is slow by %s",
                    db_timespan_name(-rSkew));
     g.clockSkewSeen = 1;
  }





  fossil_force_newline();
  fossil_print(
     "%s done, wire bytes sent: %lld  received: %lld  ip: %s\n",
     zOpType, nSent, nRcvd, g.zIpAddr);
  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(







>
>
>
>







2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
                    db_timespan_name(rSkew));
     g.clockSkewSeen = 1;
  }else if( rSkew*24.0*3600.0 < -10.0 ){
     fossil_warning("*** time skew *** server is slow by %s",
                    db_timespan_name(-rSkew));
     g.clockSkewSeen = 1;
  }

  if( nErr==0 ){
    sync_log_entry(syncFlags, g.url.canonical,  zAltPCode!=0 ? "import" : 0);
  }

  fossil_force_newline();
  fossil_print(
     "%s done, wire bytes sent: %lld  received: %lld  ip: %s\n",
     zOpType, nSent, nRcvd, g.zIpAddr);
  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(