Class: Yast::ConfigHistoryClass

Inherits:
Module
  • Object
show all
Defined in:
../../library/general/src/modules/ConfigHistory.rb

Instance Method Summary (collapse)

Instance Method Details

- (Boolean) CheckAllFilesOutOfVersionControl

Find all files which are not under version control Schedule such files for next commit

Returns:

  • (Boolean)

    true on success, false otherwise



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File '../../library/general/src/modules/ConfigHistory.rb', line 342

def CheckAllFilesOutOfVersionControl
  success = true
  Builtins.y2milestone("Adding all files out of version control")
  Builtins.foreach(@log_directories) do |dir|
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat(
          "cd %1; svn add `svn st |grep '^?'|cut -d ' ' -f 7`",
          dir
        )
      )
    )
    if Ops.get_integer(out, "exit", -1) != 0
      Builtins.y2error(
        "Failed to add files in %1: %2",
        dir,
        Ops.get_string(out, "stderr", "")
      )
      success = false
    end
  end
  @commit_needed = true # TODO check if really necessary
  Builtins.y2milestone("Finished successfuly: %1", success)
  success
end

- (Boolean) CheckChangedFilesOutOfVersionControl

Check for changed files which are not under verison control (e.g. new created files) Schedule them for next commit

Returns:

  • (Boolean)

    true on success, false on failure



283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File '../../library/general/src/modules/ConfigHistory.rb', line 283

def CheckChangedFilesOutOfVersionControl
  success = true
  Builtins.foreach(@log_directories) do |dir|
    Builtins.y2milestone("Checking for new files in %1", dir)
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat(
          "find %1 -newer %2 -type f |grep -v '/\\.'",
          dir,
          @changes_timestamp
        )
      )
    )
    if Ops.get_integer(out, "exit", -1) == 1
      Builtins.y2milestone("No changes found")
      next
    end
    param = Ops.get_string(out, "stdout", "")
    files = Builtins.splitstring(param, "\n")
    files = Builtins.filter(files) { |f| f != "" }
    files = Builtins.filter(files) do |f|
      0 ==
        Convert.to_integer(
          SCR.Execute(
            path(".target.bash"),
            Builtins.sformat("svn st %1 | grep '^?'", f)
          )
        )
    end
    @commit_needed = @commit_needed ||
      Ops.greater_than(Builtins.size(files), 0)
    if Ops.greater_than(Builtins.size(files), 0)
      param = Builtins.mergestring(files, " ")
      out = Convert.to_map(
        SCR.Execute(
          path(".target.bash_output"),
          Builtins.sformat("cd %1; svn add --parents %2", dir, param)
        )
      )
      if Ops.get_integer(out, "exit", -1) != 0
        success = false
        Builtins.y2error(
          "Failed to add changes: %1",
          Ops.get_string(out, "stderr", "")
        )
      end
    end
  end
  SCR.Execute(
    path(".target.bash_output"),
    Builtins.sformat("rm %1", @changes_timestamp)
  )
  success
end

- (Boolean) CheckRepoLinked

Check whether repo has been deployed to the filesystem

Returns:

  • (Boolean)

    true if yes (/.svn exists), false otherwise



155
156
157
158
159
160
161
162
163
164
165
166
# File '../../library/general/src/modules/ConfigHistory.rb', line 155

def CheckRepoLinked
  Builtins.y2milestone("Checking whether repo is linked to root directory")
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("test -d %1", "/.svn")
    )
  )
  ret = Ops.get_integer(out, "exit", -1) == 0
  Builtins.y2milestone("Repo linked: %1", ret)
  ret
end

- (Boolean) CheckSvnRepository

Check the presence of SVN repo for storing changes

Returns:

  • (Boolean)

    true if repo exists



140
141
142
143
144
145
146
147
148
149
150
151
# File '../../library/general/src/modules/ConfigHistory.rb', line 140

def CheckSvnRepository
  Builtins.y2milestone("Checking repo presence")
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("test -d %1", @history_location)
    )
  )
  ret = Ops.get_integer(out, "exit", -1) == 0
  Builtins.y2milestone("Repo found: %1", ret)
  ret
end

- (Boolean) CheckUncommitedChanges

Check for files in version control which had been changed but not committed

Returns:

  • (Boolean)

    true on success



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File '../../library/general/src/modules/ConfigHistory.rb', line 229

def CheckUncommitedChanges
  success = true
  Builtins.foreach(@log_directories) do |dir|
    Builtins.y2milestone("Checking for uncommitted changes in %1", dir)
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat("cd %1; svn st |grep '^M'", dir)
      )
    )
    if Ops.get_integer(out, "exit", -1) == 1 && !@commit_needed
      Builtins.y2milestone("No uncommitted change detected")
    else
      out = Convert.to_map(
        SCR.Execute(
          path(".target.bash_output"),
          Builtins.sformat(
            "cd %1; svn ci -m 'Commit remaining changes before running YaST'",
            dir
          )
        )
      )
      if Ops.get_integer(out, "exit", -1) != 0
        success = false
        Builtins.y2error(
          "Failed to commit changes in %1: %2",
          dir,
          Ops.get_string(out, "stderr", "")
        )
      end
    end
  end
  Builtins.y2milestone("Commit successful: %1", success)
  success
end

- (Boolean) CommitChanges(module_name)

Commit changes done by YaST into the SVN repo

Parameters:

  • module_name (String)

    string name of YaST module which does commit used only in the commit log

Returns:

  • (Boolean)

    true on success, false on failure



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File '../../library/general/src/modules/ConfigHistory.rb', line 486

def CommitChanges(module_name)
  return true if !UseSvn()
  @nested_transactions = Ops.subtract(@nested_transactions, 1)
  if Ops.greater_than(@nested_transactions, 0)
    Builtins.y2milestone(
      "Skipping commit, all nested transaction not yet finished"
    )
    return true
  end
  success = true
  if Recursive()
    success = CheckAllFilesOutOfVersionControl()
  else
    success = CheckChangedFilesOutOfVersionControl()
  end
  success = RemoveDeletedFiles() && success
  success = false if !UpdateCheckout()
  success = DoCommit(module_name) && success
  true
end

- (Boolean) CreateTimeStamp

Create a timestamp to find changed files which are not under version control

Returns:

  • (Boolean)

    true on success



267
268
269
270
271
272
273
274
275
276
277
278
# File '../../library/general/src/modules/ConfigHistory.rb', line 267

def CreateTimeStamp
  Builtins.y2milestone("Creating timestamp to detect changes")
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("touch %1", @changes_timestamp)
    )
  )
  ret = Ops.get_integer(out, "exit", -1) == 0
  Builtins.y2milestone("Success: %1", ret)
  ret
end

- (Boolean) DoCommit(mod)

Do commit to subversion

Returns:

  • (Boolean)

    tru eon success



418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
# File '../../library/general/src/modules/ConfigHistory.rb', line 418

def DoCommit(mod)
  Builtins.y2milestone("Committing changes")
  arg = Builtins.mergestring(@log_directories, " ")
  Builtins.y2debug("Directories to commit: %1", arg)
  log = Builtins.sformat("Changes by YaST module %1", mod)
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("cd / ; svn ci -m '%1' %2", log, arg)
    )
  )
  ret = Ops.get_integer(out, "exit", -1) == 0
  Builtins.y2milestone("Success: %1", ret)
  ret
end

- (Boolean) Init

Initialize before module is started Do not call CommitChanges unless Init returns true!

Returns:

  • (Boolean)

    true on success, false on failure



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File '../../library/general/src/modules/ConfigHistory.rb', line 461

def Init
  return true if !UseSvn()
  if Ops.greater_than(@nested_transactions, 0)
    @nested_transactions = Ops.add(@nested_transactions, 1)
    Builtins.y2milestone(
      "Skiping SVN initialization, translaction already in progress"
    )
    return true
  end
  #ensure the repo exists
  return false if !InitSvnRepository() if !CheckSvnRepository()
  return false if !InitDirectories(Recursive()) if !CheckRepoLinked()
  CheckAllFilesOutOfVersionControl() if Recursive()
  RemoveDeletedFiles()
  return false if !UpdateCheckout()
  return false if !CheckUncommitedChanges()
  return false if !CreateTimeStamp()
  @nested_transactions = Ops.add(@nested_transactions, 1)
  true
end

- (Boolean) InitDirectories(recursive)

Initialize predefined directories for SVN

Parameters:

  • recursive (Boolean)

    boolean true to add whole directories incl. subtree, false to add directory itself only

Returns:

  • (Boolean)

    true on success, false on failure



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File '../../library/general/src/modules/ConfigHistory.rb', line 172

def InitDirectories(recursive)
  Builtins.y2milestone(
    "Linking system with the repository; recursive: %1",
    recursive
  )
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("svn co file://%1 /", @history_location)
    )
  )
  if Ops.get_integer(out, "exit", -1) != 0
    Builtins.y2error(
      "svn check out to root failed: %1",
      Ops.get_string(out, "stderr", "")
    )
    return false
  end
  success = true
  Builtins.foreach(@log_directories) do |dir|
    Builtins.y2milestone("Initializing directory %1", dir)
    params = recursive ? "" : "-N"
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat("cd / ; svn add %2 %1", dir, params)
      )
    )
    if Ops.get_integer(out, "exit", -1) != 0
      success = false
      Builtins.y2error(
        "Failed to add directory %1: %2",
        dir,
        Ops.get_string(out, "stderr", "")
      )
    end
  end
  return false if !success
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      "cd / ; svn ci -m 'Initial check-in'"
    )
  )
  if Ops.get_integer(out, "exit", -1) != 0
    Builtins.y2error(
      "Initial check-in to repo failed: %1",
      Ops.get_string(out, "stderr", "")
    )
    return false
  end
  Builtins.y2milestone("Initial check-in succeeded")
  true
end

- (Boolean) InitFiles(files)

Initialize specified files for version control; useful when not having whole directory under version control, but only relevant files

Parameters:

  • files (Array<String>)

    a list of files to add to repo (resp. ensure they are in)

Returns:

  • (Boolean)

    true on success, false otherwise



512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File '../../library/general/src/modules/ConfigHistory.rb', line 512

def InitFiles(files)
  files = deep_copy(files)
  return true if Builtins.size(files) == 0
  return true if !UseSvn()
  return true if Recursive()
  if @nested_transactions == 0
    Builtins.y2error("InitFiles called before prior initialization")
    return false
  end
  filelist = Builtins.mergestring(files, " ")
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("svn add %1", filelist)
    )
  )
  if Ops.get_integer(out, "exit", -1) != 0
    Builtins.y2error(
      "Failed to schedule files %1 for addition: %2",
      filelist,
      Ops.get_string(out, "stderr", "")
    )
    return false
  end
  success = true
  Builtins.foreach(@log_directories) do |dir|
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat(
          "cd %1; svn ci -m 'Initial check-in of files to be changed'",
          dir
        )
      )
    )
    if Ops.get_integer(out, "exit", -1) != 0
      Builtins.y2error(
        "Failed to commit changes to %1: %2",
        dir,
        Ops.get_string(out, "exit", "")
      )
      success = false
    end
  end
  success
end

- (Boolean) InitSvnRepository

Initialize a SVN repository for config files in /var/lib/YaST2

Returns:

  • (Boolean)

    true on success, false otherwise



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
# File '../../library/general/src/modules/ConfigHistory.rb', line 103

def InitSvnRepository
  Builtins.y2milestone("Initializing repo at %1", @history_location)
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat("svnadmin create %1", @history_location)
    )
  )
  if Ops.get_integer(out, "exit", -1) != 0
    Builtins.y2error(
      "Failed to initialize SVN repository: %1",
      Ops.get_string(out, "stderr", "")
    )
    return false
  end
  out = Convert.to_map(
    SCR.Execute(
      path(".target.bash_output"),
      Builtins.sformat(
        "chown -R root:root %1; chmod -R g= %1; chmod -R o= %1",
        @history_location
      )
    )
  )
  if Ops.get_integer(out, "exit", -1) != 0
    Builtins.y2error(
      "Failed to set svn repo permissions: %1",
      Ops.get_string(out, "stderr", "")
    )
    return false
  end
  Builtins.y2milestone("Repo initialized")
  true
end

- (Object) main



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File '../../library/general/src/modules/ConfigHistory.rb', line 51

def main
  textdomain "config-history"

  # Location of SVN repo
  @history_location = "/var/lib/YaST2/config-history"

  # Location of timestamp for detecting changed files out of version control
  @changes_timestamp = "/var/lib/YaST2/config-history-timestamp"

  # Directories to put under version control
  @log_directories = ["/etc"]

  # Is the SVN history active?
  @use_svn = nil

  # Always have whole subtree in SVN, not only files changed by YaST
  @store_whole_subtree = nil

  # Count of nested transactions (module calling another module)
  @nested_transactions = 0

  # If true, force commit at the end of initialization/finalization
  @commit_needed = false
end

- (Object) Recursive



88
89
90
91
92
93
94
95
96
97
98
99
# File '../../library/general/src/modules/ConfigHistory.rb', line 88

def Recursive
  if @store_whole_subtree == nil
    @store_whole_subtree = Convert.to_string(
      SCR.Read(path(".sysconfig.yast2.SUBVERSION_ADD_DIRS_RECURSIVE"))
    ) == "yes"
    Builtins.y2milestone(
      "Automatically store whole subtree: %1",
      @store_whole_subtree
    )
  end
  @store_whole_subtree
end

- (Boolean) RemoveDeletedFiles

Check for files which had been deleted, but are still in SVN Schedule such files for deletion with next commit

Returns:

  • (Boolean)

    true on success, false otherwise



372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
# File '../../library/general/src/modules/ConfigHistory.rb', line 372

def RemoveDeletedFiles
  success = true
  Builtins.y2milestone("Checking for removed files")
  Builtins.foreach(@log_directories) do |dir|
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat("cd %1; svn st |grep '^!'|cut -d ' ' -f 7", dir)
      )
    )
    if Ops.get_integer(out, "exit", -1) != 0
      Builtins.y2error(
        "Failed to check for deleted files in %1: %2",
        dir,
        Ops.get_string(out, "stderr", "")
      )
      success = false
      next
    end
    filelist = Ops.get_string(out, "stdout", "")
    files = Builtins.splitstring(filelist, " ")
    files = Builtins.filter(files) { |f| f != "" }
    next if Builtins.size(files) == 0
    filelist = Builtins.mergestring(files, " ")
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat("cd %1; svn rm %2", dir, filelist)
      )
    )
    if Ops.get_integer(out, "exit", -1) != 0
      Builtins.y2error(
        "Failed to remove files in %1: %2",
        dir,
        Ops.get_string(out, "stderr", "")
      )
      success = false
    end
  end
  @commit_needed = true # TODO check if really necessary
  Builtins.y2milestone("Finished successfuly: %1", success)
  success
end

- (Boolean) UpdateCheckout

Update check-out from SVN to avoid commit conflicts

Returns:

  • (Boolean)

    true on success



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File '../../library/general/src/modules/ConfigHistory.rb', line 436

def UpdateCheckout
  success = true
  Builtins.foreach(@log_directories) do |dir|
    Builtins.y2milestone("Updating configuration files in %1", dir)
    out = Convert.to_map(
      SCR.Execute(
        path(".target.bash_output"),
        Builtins.sformat("cd %1; svn up", dir)
      )
    )
    if Ops.get_integer(out, "exit", -1) != 0
      Builtins.y2error(
        "Failed to update %1 from SVN: %2",
        dir,
        Ops.get_string(out, "stderr", "")
      )
      success = false
    end
  end
  success
end

- (Boolean) UseSvn

Is the SVN history in use?

Returns:

  • (Boolean)

    true to log to SVN



78
79
80
81
82
83
84
85
86
# File '../../library/general/src/modules/ConfigHistory.rb', line 78

def UseSvn
  if @use_svn == nil
    @use_svn = Convert.to_string(
      SCR.Read(path(".sysconfig.yast2.STORE_CONFIG_IN_SUBVERSION"))
    ) == "yes"
    Builtins.y2milestone("Using SVN for configuration files: %1", @use_svn)
  end
  @use_svn
end