Nie można znaleźć klasy, a jednak ona istnieje

31

Podczas wykonywania puppet agentpołączenia z nowego obrazu pojawia się err: Could not find class custommodbłąd. Sam moduł jest /etc/puppet/modules/custommodtaki sam jak wszystkie inne moduły, które wywołujemy, ale ten jest uparty.

[site.pp]

node /clunod-wk\d+\.sub\.example\.local/ {
      include base
      include curl
      include custommod
      class{ "custommod::apps": frontend => "false}
      [...]
}

Gdy puppetmaster jest uruchamiany z wyjściem debugowania, wyraźnie znajduje informacje o bazie i curl:

debug: importing '/etc/puppet/modules/base/manifests/init.pp' in environment production
debug: Automatically imported base from base into production
debug: importing '/etc/puppet/modules/curl/manifests/init.pp' in environment production
debug: Automatically imported curl from curl into production
err: Could not find class custommod for clunod-wk0130.sub.example.local at /etc/puppet/manifests/site.pp:84 on node clunod-wk0130.sub.example.local

Linia 84 jest include custommod

Skrócona struktura katalogów i plików:

/etc/puppet
   |- manifests
   |     |- site.pp
   |
   |- modules
         |- base
         |    |- manifests
         |          |- init.pp
         |
         |- curl
         |    |- manifests
         |          |- init.pp
         |   
         |- custommod
              |- files 
              |     |- apps
              |         |- [...]
              |
              |- manifests
                    |- init.pp
                    |- apps.pp

Sprawdziłem pisownię:}

Treść init.ppw katalogu klienta jest całkowicie nieistotna:

class custommod {
}

Celem jest utworzenie pustej klasy dla pliku apps.pp, czyli tam, gdzie znajduje się mięso.

class custommod::apps {

    [lots of stuff]
}

Tylko nigdy nie dostaje się do pliku aplikacji. Jeśli to skomentuję include custommod, powyższy błąd zostanie wygenerowany w class{ "custommod::apps": frontend => "false}wierszu.

Czego mi brakuje podczas polowania, aby dowiedzieć się, jak generowany jest ten błąd? Muszę zauważyć, że to repozytorium działa dobrze, jeśli jest uruchamiane lokalnie przez puppet apply.

sysadmin1138
źródło
Czy wziąłeś szczyt w pliku yaml klienta, aby sprawdzić, czy Twoja klasa jest obecna?
Zoredache
@Zoredache Katalog / var / lib / puppet / client_yaml / jest pusty na kliencie. Klient dostaje could not retrieve catalog from remote server:błąd, prawdopodobnie dlatego.
sysadmin1138
Hrm .. ponownie utworzył podstawowy układ i strukturę importu i nie mógł odtworzyć problemu (w wersji 2.7.1). Powinny być bezpieczne, aby przestać uwzględniać puste custommod- może nawet spróbować init.ppcałkowicie usunąć , ponieważ nie powinno to być potrzebne.
Shane Madden
@ShaneMadden Po tym, jak spróbuję, moim następnym krokiem jest rzucić stracena nią okiem i spróbować dowiedzieć się, jakie pliki próbuje odczytać w ten sposób.
sysadmin1138

Odpowiedzi:

32

Więc ... to trochę zawstydzające, ale ...

Środowiska.

W moim /etc/puppet.confpliku jest to:

[master]
  manifest=$confdir/manifests/site.pp
  modulepath=$confdir/environments/$environment/modules:$confdir/modules

Po rzuceniu stracego, aby dowiedzieć się, gdzie szuka plików, zauważyłem coś. Szukał pod sprytem /etc/puppet/environments/production/modules, a ponieważ był tam katalog (pusty), nie sprawdził/etc/puppet/modules . Najwyraźniej podczas importowania modułu sprawdza obecność katalogu, a nie obecność pliku (init.pp).

Usuń ten pusty katalog, wszystko zacznie działać.

Uruchom agenta marionetek w innym środowisku, wszystko zacznie działać.

Morał historii:

Ścieżki środowiska lalek nie działają jak bash $ PATH.

sysadmin1138
źródło
8
A jeśli ktoś nie zdefiniował wyraźnie swojej ścieżki do modułu w puppet.conf i chce znaleźć ścieżkę do modułu bez uciekania się do strace, może także biegać puppet config print modulepath.
Alison R.
1
czy zostało to zgłoszone marionetkom?
Felipe Alvarez
3
Ścieżka do modułu wyzwala teraz ostrzeżenie o wycofaniu.
Magellan
4

Natrafiłem na ten sam problem, ale miałem inną poprawkę

Jeśli wygenerujesz taki moduł lalek:

puppet module generate foo-example_module

Stworzy moduł o nazwie example_modulez fooprzestrzenią nazw. Wszystkie manifesty będą znajdować się w katalogu o nazwiefoo-example_module

Nazwa klasy zdefiniowanej w pliku init.pp musi być taka sama jak nazwa folderu.

Prosta poprawka:

mv foo-example_module example_module

Jeśli uruchomisz marionetkę, pojawi się następujący komunikat:

ERROR: example_module not in autoload module layout on line 42

Jeśli używasz pliku Puppetfile z r10k lub librarian-puppet, może być również konieczne usunięcie przestrzeni nazw, aby pliki były umieszczane bez prefiksu „foo” w katalogu modułów.

przed:

mod 'foo-example_module',
    :git => [email protected]:foo/example_module'

po:

mod 'example_module',
    :git => [email protected]:foo/example_module'
spuder
źródło
0

Wystąpił podobny problem z marionetką 3.7.1 dla Fedory: Nie można znaleźć marionetki klasowej dla mojego serwera

Rozwiązanie:

sudo ln -s /my/local/copy/puppet/modules /etc/puppet/

To działa.

Haibo Liu
źródło
0

Miałem podobny problem. W moim przypadku nazwa klasy to „onehost :: change_IoT_password_reminder”. Po użyciu strace odkryłem, że marionetka szukała pliku modułów / onehost / manifests / change_iot_password_reminder.pp. Wydaje się, że używanie wielkich liter w nazwach klas nie jest dobrym pomysłem, nawet jeśli nie jest to pierwsza litera klasy.

Geoff Crompton
źródło